1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
use rand::{CryptoRng, RngCore};

use amcl_wrapper::errors::SerzDeserzError;
use amcl_wrapper::field_elem::FieldElement;
use amcl_wrapper::group_elem::GroupElement;
use amcl_wrapper::group_elem_g2::G2;
use VerkeyGroup;

pub(crate) const MESSAGE_DOMAIN_PREFIX: [u8; 2] = [0, 0];
pub(crate) const VERKEY_DOMAIN_PREFIX: [u8; 2] = [1, 1];

pub struct Params {
    pub g: VerkeyGroup,
}

impl Params {
    pub fn new(label: &[u8]) -> Self {
        // NUMS
        let g = VerkeyGroup::from_msg_hash(label);
        Params { g }
    }
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SigKey {
    pub x: FieldElement,
}

impl SigKey {
    pub fn new<R: RngCore + CryptoRng>(rng: &mut R) -> Self {
        Self {
            x: FieldElement::random_using_rng(rng),
        }
    }

    pub fn from_bytes(sk_bytes: &[u8]) -> Result<SigKey, SerzDeserzError> {
        FieldElement::from_bytes(sk_bytes).map(|x| SigKey { x })
    }

    pub fn to_bytes(&self) -> Vec<u8> {
        self.x.to_bytes()
    }
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct VerKey {
    pub point: VerkeyGroup,
}

impl VerKey {
    pub fn from_sigkey(sk: &SigKey, params: &Params) -> Self {
        VerKey {
            point: &params.g * &sk.x,
        }
    }

    pub fn from_bytes(vk_bytes: &[u8]) -> Result<VerKey, SerzDeserzError> {
        VerkeyGroup::from_bytes(vk_bytes).map(|point| VerKey { point })
    }

    pub fn to_bytes(&self) -> Vec<u8> {
        self.point.to_bytes()
    }
}

pub struct Keypair {
    pub sig_key: SigKey,
    pub ver_key: VerKey,
}

impl Keypair {
    pub fn new<R: RngCore + CryptoRng>(rng: &mut R, params: &Params) -> Self {
        let sk = SigKey::new(rng);
        let vk = VerKey::from_sigkey(&sk, params);
        Keypair {
            sig_key: sk,
            ver_key: vk,
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use rand::thread_rng;

    #[test]
    fn gen_verkey() {
        let mut rng = thread_rng();
        let sk1 = SigKey::new(&mut rng);
        let sk2 = SigKey::new(&mut rng);
        let params = Params::new("test".as_bytes());
        for mut sk in vec![sk1, sk2] {
            let mut vk1 = VerKey::from_sigkey(&sk, &params);
            debug!("{}", sk.x.to_hex());
            debug!("{}", &vk1.point.to_hex());

            let mut vk2 = VerKey::from_sigkey(&sk, &params);
            debug!("{}", &vk2.point.to_hex());

            //assert_eq!(&vk1.point.to_hex(), &vk2.point.to_hex());

            /*let bs = vk1.to_bytes();
            let bs1 = bs.clone();
            let mut vk3 = VerKey::from(bs1);
            assert_eq!(&vk3.point.tostring(), &vk1.point.tostring());
            assert_eq!(&vk3.point.tostring(), &vk2.point.tostring());

            let mut sk_bytes: [u8; MODBYTES] = [0; MODBYTES];
            sk.x.tobytes(&mut sk_bytes);
            let mut s = SigKey::from(sk_bytes.to_vec());
            assert_eq!(&s.x.tostring(), &sk.x.tostring());

            let bs2: Vec<u8> = vk3.into();
            assert_eq!(bs, bs2);*/

            let bs = vk1.to_bytes();
            let mut vk11 = VerKey::from_bytes(&bs).unwrap();
            // FIXME: Next line fails
            //assert_eq!(&vk1.point.to_hex(), &vk11.point.to_hex());
            assert_eq!(vk1.point.to_bytes(), vk11.point.to_bytes());

            let bs = sk.to_bytes();
            let mut sk1 = SigKey::from_bytes(&bs).unwrap();
            assert_eq!(sk1.x.to_hex(), sk.x.to_hex());
        }
    }
}