arnaucube
arnaucube/babyjubjub-rsPublic Self-hosted repository
babyjubjub-rs/src/lib.rs
src/lib.rsRaw
  1#[macro_use]
  2extern crate arrayref;
  3extern crate generic_array;
  4extern crate mimc_rs;
  5extern crate num;
  6extern crate num_bigint;
  7extern crate num_traits;
  8extern crate rand;
  9
 10use blake2::{Blake2b, Digest};
 11use mimc_rs::Mimc7;
 12use poseidon_rs::Poseidon;
 13use std::cmp::min;
 14
 15use num_bigint::{BigInt, RandBigInt, Sign, ToBigInt};
 16use num_traits::{One, Zero};
 17
 18use generic_array::GenericArray;
 19
 20mod utils;
 21
 22#[macro_use]
 23extern crate lazy_static;
 24
 25lazy_static! {
 26    static ref D: BigInt = BigInt::parse_bytes(b"168696", 10).unwrap();
 27    static ref A: BigInt = BigInt::parse_bytes(b"168700", 10).unwrap();
 28    static ref Q: BigInt = BigInt::parse_bytes(
 29        b"21888242871839275222246405745257275088548364400416034343698204186575808495617",
 30        10,
 31    )
 32    .unwrap();
 33    static ref B8: Point = Point {
 34        x: BigInt::parse_bytes(
 35            b"5299619240641551281634865583518297030282874472190772894086521144482721001553",
 36            10,
 37        )
 38        .unwrap(),
 39        y: BigInt::parse_bytes(
 40            b"16950150798460657717958625567821834550301663161624707787222815936182638968203",
 41            10,
 42        )
 43        .unwrap(),
 44    };
 45    static ref ORDER: BigInt = BigInt::parse_bytes(
 46        b"21888242871839275222246405745257275088614511777268538073601725287587578984328",
 47        10,
 48    )
 49    .unwrap();
 50    static ref SUBORDER: BigInt = &BigInt::parse_bytes(
 51        b"21888242871839275222246405745257275088614511777268538073601725287587578984328",
 52        10,
 53    )
 54    .unwrap()
 55        >> 3;
 56}
 57
 58#[derive(Clone, Debug)]
 59pub struct Point {
 60    pub x: BigInt,
 61    pub y: BigInt,
 62}
 63
 64impl Point {
 65    pub fn add(&self, q: &Point) -> Result<Point, String> {
 66        // x = (x1*y2+y1*x2)/(c*(1+d*x1*x2*y1*y2))
 67        // y = (y1*y2-x1*x2)/(c*(1-d*x1*x2*y1*y2))
 68
 69        // x = (x1 * y2 + y1 * x2) / (1 + d * x1 * y1 * y2)
 70        let one: BigInt = One::one();
 71        let x_num: BigInt = &self.x * &q.y + &self.y * &q.x;
 72        let x_den: BigInt = &one + &D.clone() * &self.x * &q.x * &self.y * &q.y;
 73        let x_den_inv = utils::modinv(&x_den, &Q)?;
 74        let x: BigInt = utils::modulus(&(&x_num * &x_den_inv), &Q);
 75
 76        // y = (y1 * y2 - a * x1 * x2) / (1 - d * x1 * x2 * y1 * y2)
 77        let y_num = &self.y * &q.y - &A.clone() * &self.x * &q.x;
 78        let y_den = utils::modulus(&(&one - &D.clone() * &self.x * &q.x * &self.y * &q.y), &Q);
 79        let y_den_inv = utils::modinv(&y_den, &Q)?;
 80        let y: BigInt = utils::modulus(&(&y_num * &y_den_inv), &Q);
 81
 82        Ok(Point { x: x, y: y })
 83    }
 84
 85    pub fn mul_scalar(&self, n: &BigInt) -> Result<Point, String> {
 86        let mut r: Point = Point {
 87            x: Zero::zero(),
 88            y: One::one(),
 89        };
 90        let mut rem: BigInt = n.clone();
 91        let mut exp: Point = self.clone();
 92
 93        let zero: BigInt = Zero::zero();
 94        let one: BigInt = One::one();
 95        while rem != zero {
 96            let is_odd = &rem & &one == one;
 97            if is_odd == true {
 98                r = r.add(&exp)?;
 99            }
100            exp = exp.add(&exp)?;
101            rem = rem >> 1;
102        }
103        r.x = utils::modulus(&r.x, &Q);
104        r.y = utils::modulus(&r.y, &Q);
105        Ok(r)
106    }
107
108    pub fn compress(&self) -> [u8; 32] {
109        let mut r: [u8; 32] = [0; 32];
110        let (_, y_bytes) = self.y.to_bytes_le();
111        let len = min(y_bytes.len(), r.len());
112        r[..len].copy_from_slice(&y_bytes[..len]);
113        if &self.x > &(&Q.clone() >> 1) {
114            r[31] = r[31] | 0x80;
115        }
116        r
117    }
118
119    pub fn equals(&self, p: Point) -> bool {
120        if self.x == p.x && self.y == p.y {
121            return true;
122        }
123        false
124    }
125    pub fn zero() -> Point {
126        return Point {
127            x: Zero::zero(),
128            y: Zero::zero(),
129        };
130    }
131}
132
133pub fn decompress_point(bb: [u8; 32]) -> Result<Point, String> {
134    // https://tools.ietf.org/html/rfc8032#section-5.2.3
135    let mut sign: bool = false;
136    let mut b = bb.clone();
137    if b[31] & 0x80 != 0x00 {
138        sign = true;
139        b[31] = b[31] & 0x7F;
140    }
141    let y: BigInt = BigInt::from_bytes_le(Sign::Plus, &b[..]);
142    if y >= Q.clone() {
143        return Err("y outside the Finite Field over R".to_string());
144    }
145    let one: BigInt = One::one();
146
147    // x^2 = (1 - y^2) / (a - d * y^2) (mod p)
148    let den = utils::modinv(
149        &utils::modulus(
150            &(&A.clone() - utils::modulus(&(&D.clone() * (&y * &y)), &Q)),
151            &Q,
152        ),
153        &Q,
154    )?;
155    let mut x: BigInt = utils::modulus(&((one - utils::modulus(&(&y * &y), &Q)) * den), &Q);
156    x = utils::modsqrt(&x, &Q)?;
157
158    if sign && !(&x > &(&Q.clone() >> 1)) || (!sign && (&x > &(&Q.clone() >> 1))) {
159        x = x * -1.to_bigint().unwrap();
160    }
161    x = utils::modulus(&x, &Q);
162    Ok(Point { x: x, y: y })
163}
164
165pub struct Signature {
166    r_b8: Point,
167    s: BigInt,
168}
169
170impl Signature {
171    pub fn compress(&self) -> [u8; 64] {
172        let mut b: Vec<u8> = Vec::new();
173        b.append(&mut self.r_b8.compress().to_vec());
174        let (_, s_bytes) = self.s.to_bytes_le();
175        let mut s_32bytes: [u8; 32] = [0; 32];
176        let len = min(s_bytes.len(), s_32bytes.len());
177        s_32bytes[..len].copy_from_slice(&s_bytes[..len]);
178        b.append(&mut s_32bytes.to_vec());
179        let mut r: [u8; 64] = [0; 64];
180        r[..].copy_from_slice(&b[..]);
181        r
182    }
183}
184
185pub fn decompress_signature(b: &[u8; 64]) -> Result<Signature, String> {
186    let r_b8_bytes: [u8; 32] = *array_ref!(b[..32], 0, 32);
187    let s: BigInt = BigInt::from_bytes_le(Sign::Plus, &b[32..]);
188    let r_b8 = decompress_point(r_b8_bytes);
189    match r_b8 {
190        Result::Err(err) => return Err(err.to_string()),
191        Result::Ok(res) => Ok(Signature {
192            r_b8: res.clone(),
193            s: s,
194        }),
195    }
196}
197
198pub struct PrivateKey {
199    key: BigInt,
200}
201
202impl PrivateKey {
203    pub fn public(&self) -> Result<Point, String> {
204        // https://tools.ietf.org/html/rfc8032#section-5.1.5
205        let pk = B8.mul_scalar(&self.key)?;
206        Ok(pk.clone())
207    }
208
209    pub fn sign_mimc(&self, msg: BigInt) -> Result<Signature, String> {
210        // https://tools.ietf.org/html/rfc8032#section-5.1.6
211        let mut hasher = Blake2b::new();
212        let (_, sk_bytes) = self.key.to_bytes_be();
213        hasher.input(sk_bytes);
214        let mut h = hasher.result(); // h: hash(sk)
215                                     // s: h[32:64]
216        let s = GenericArray::<u8, generic_array::typenum::U32>::from_mut_slice(&mut h[32..64]);
217        let (_, msg_bytes) = msg.to_bytes_be();
218        let r_bytes = utils::concatenate_arrays(s, &msg_bytes);
219        let mut r = BigInt::from_bytes_be(Sign::Plus, &r_bytes[..]);
220        r = utils::modulus(&r, &SUBORDER);
221        let r8: Point = B8.mul_scalar(&r)?;
222        let a = &self.public()?;
223
224        let hm_input = vec![r8.x.clone(), r8.y.clone(), a.x.clone(), a.y.clone(), msg];
225        let mimc7 = Mimc7::new();
226        let hm = mimc7.hash(hm_input)?;
227
228        let mut s = &self.key << 3;
229        s = hm * s;
230        s = r + s;
231        s = s % &SUBORDER.clone();
232
233        Ok(Signature {
234            r_b8: r8.clone(),
235            s: s,
236        })
237    }
238    pub fn sign_poseidon(&self, msg: BigInt) -> Result<Signature, String> {
239        // https://tools.ietf.org/html/rfc8032#section-5.1.6
240        let mut hasher = Blake2b::new();
241        let (_, sk_bytes) = self.key.to_bytes_be();
242        hasher.input(sk_bytes);
243        let mut h = hasher.result(); // h: hash(sk)
244                                     // s: h[32:64]
245        let s = GenericArray::<u8, generic_array::typenum::U32>::from_mut_slice(&mut h[32..64]);
246        let (_, msg_bytes) = msg.to_bytes_be();
247        let r_bytes = utils::concatenate_arrays(s, &msg_bytes);
248        let mut r = BigInt::from_bytes_be(Sign::Plus, &r_bytes[..]);
249        r = utils::modulus(&r, &SUBORDER);
250        let r8: Point = B8.mul_scalar(&r)?;
251        let a = &self.public()?;
252
253        let hm_input = vec![r8.x.clone(), r8.y.clone(), a.x.clone(), a.y.clone(), msg];
254        let poseidon = Poseidon::new();
255        let hm = poseidon.hash(hm_input)?;
256
257        let mut s = &self.key << 3;
258        s = hm * s;
259        s = r + s;
260        s = s % &SUBORDER.clone();
261
262        Ok(Signature {
263            r_b8: r8.clone(),
264            s: s,
265        })
266    }
267
268    pub fn sign_schnorr(&self, m: Vec<u8>) -> Result<(Point, BigInt), String> {
269        // random r
270        let mut rng = rand::thread_rng();
271        let k = rng.gen_biguint(1024).to_bigint().unwrap();
272
273        // r = k·G
274        let r = B8.mul_scalar(&k)?;
275
276        // h = H(x, r, m)
277        let pk = &self.public()?;
278        let h = hash_sig(&pk, m, &r)?;
279
280        // s= k+x·h
281        let s = k + &self.key * &h;
282        Ok((r, s))
283    }
284
285    // https://eprint.iacr.org/2018/068.pdf
286    pub fn sign_aggr(
287        &self,
288        x: Point,
289        r: Point,
290        ri: BigInt,
291        l: Vec<u8>,
292        m: Vec<u8>,
293    ) -> Result<BigInt, String> {
294        let pk = &self.public()?;
295        // a0 = h(l, X0)
296        let ai = hash_agg(&l, pk)?;
297
298        // c = H(x, r, m)
299        let c = hash_sig(&x, m, &r)?;
300        // s0 = r0 + c · a0 · sk0 mod p
301        let si = ri + c * ai * &self.key;
302        Ok(utils::modulus(&si, &Q))
303    }
304}
305pub fn calc_ri() -> Result<(BigInt, Point), String> {
306    // random r
307    let mut rng = rand::thread_rng();
308    let k = rng.gen_biguint(1024).to_bigint().unwrap();
309
310    // r = k·G
311    let r = B8.mul_scalar(&k)?;
312    Ok((k, r))
313}
314pub fn aggr_pks(mut pks: Vec<Point>, ris: Vec<Point>) -> Result<(Point, Point, Vec<u8>), String> {
315    let mut pk_aggr: Vec<u8> = Vec::new();
316    for i in 0..pks.len() {
317        pk_aggr.append(&mut pks[i].compress().to_vec());
318    }
319
320    // (Xi=pk)
321    // l = {X1, X2, X3, ...}
322    let l = pk_aggr.clone();
323
324    // X = sum{ h(l, Xi)·Xi } = sum{ Xi · ai }
325    // a0 = h(l, X0)
326    let ai = hash_agg(&l, &pks[0])?;
327    let mut x: Point = pks[0].mul_scalar(&ai)?;
328    for i in 1..pks.len() {
329        // ai = h(l, Xi)
330        let ai = hash_agg(&l, &pks[i])?;
331        // x = x + ai · xi;
332        let s = pks[i].mul_scalar(&ai)?;
333        x = x.add(&s)?;
334    }
335
336    // r = sum{ ri }
337    let mut r: Point = ris[0].clone();
338    for i in 1..ris.len() {
339        r = r.add(&ris[i])?;
340    }
341
342    Ok((x, r, l))
343}
344pub fn aggr_signatures(sigs: Vec<BigInt>) -> Result<BigInt, String> {
345    let mut s: BigInt = Zero::zero();
346    for i in 0..sigs.len() {
347        // s = utils::modulus(&(s + &sigs[i]), &Q);
348        s = s + &sigs[i];
349    }
350    Ok(utils::modulus(&s, &Q))
351    // Ok(s)
352}
353pub fn verify_schnorr_aggregated(
354    x: Point,
355    r: Point,
356    s: BigInt,
357    m: Vec<u8>,
358) -> Result<bool, String> {
359    // sG = s·G
360    let sg = B8.mul_scalar(&s)?;
361
362    let c = hash_sig(&x, m, &r)?;
363    let x_c = x.mul_scalar(&c)?;
364    let right = r.add(&x_c)?;
365    println!("x:\n{:?}\n{:?}\n", sg.x.to_string(), right.x.to_string());
366    println!("y:\n{:?}\n{:?}\n", sg.y.to_string(), right.y.to_string());
367    Ok(sg.equals(right))
368}
369
370pub fn hash_sig(pk: &Point, m: Vec<u8>, c: &Point) -> Result<BigInt, String> {
371    let b: &mut Vec<u8> = &mut Vec::new();
372
373    // other option could be to do it without compressing the points, and concatenating x|y
374    b.append(&mut pk.compress().to_vec());
375    b.append(&mut c.compress().to_vec());
376    b.append(&mut m.clone());
377
378    let poseidon = Poseidon::new();
379    let h = poseidon.hash_bytes(b.to_vec())?;
380    Ok(h)
381}
382pub fn hash_agg(l: &Vec<u8>, xi: &Point) -> Result<BigInt, String> {
383    let b: &mut Vec<u8> = &mut Vec::new();
384
385    // other option could be to do it without compressing the points, and concatenating x|y
386    b.append(&mut l.clone());
387    b.append(&mut xi.compress().to_vec());
388
389    let poseidon = Poseidon::new();
390    let h = poseidon.hash_bytes(b.to_vec())?;
391    Ok(h)
392}
393
394pub fn verify_schnorr(pk: Point, m: Vec<u8>, r: Point, s: BigInt) -> Result<bool, String> {
395    // sG = s·G
396    let sg = B8.mul_scalar(&s)?;
397
398    // r + h · x
399    let h = hash_sig(&pk, m, &r)?;
400    let pk_h = pk.mul_scalar(&h)?;
401    let r_h_x = r.add(&pk_h)?;
402
403    Ok(sg.equals(r_h_x))
404}
405
406pub fn new_key() -> PrivateKey {
407    // https://tools.ietf.org/html/rfc8032#section-5.1.5
408    let mut rng = rand::thread_rng();
409    let sk_raw = rng.gen_biguint(1024).to_bigint().unwrap();
410
411    let mut hasher = Blake2b::new();
412    let (_, sk_raw_bytes) = sk_raw.to_bytes_be();
413    hasher.input(sk_raw_bytes);
414    let mut h = hasher.result();
415
416    h[0] = h[0] & 0xF8;
417    h[31] = h[31] & 0x7F;
418    h[31] = h[31] | 0x40;
419
420    let sk = BigInt::from_bytes_le(Sign::Plus, &h[..]);
421
422    PrivateKey { key: sk }
423}
424
425pub fn verify_mimc(pk: Point, sig: Signature, msg: BigInt) -> bool {
426    let hm_input = vec![
427        sig.r_b8.x.clone(),
428        sig.r_b8.y.clone(),
429        pk.x.clone(),
430        pk.y.clone(),
431        msg,
432    ];
433    let mimc7 = Mimc7::new();
434    let hm = match mimc7.hash(hm_input) {
435        Result::Err(_) => return false,
436        Result::Ok(hm) => hm,
437    };
438    let l = match B8.mul_scalar(&sig.s) {
439        Result::Err(_) => return false,
440        Result::Ok(l) => l,
441    };
442    let r = match sig
443        .r_b8
444        .add(&pk.mul_scalar(&(8.to_bigint().unwrap() * hm)).unwrap())
445    {
446        Result::Err(_) => return false,
447        Result::Ok(r) => r,
448    };
449    l.equals(r)
450}
451pub fn verify_poseidon(pk: Point, sig: Signature, msg: BigInt) -> bool {
452    let hm_input = vec![
453        sig.r_b8.x.clone(),
454        sig.r_b8.y.clone(),
455        pk.x.clone(),
456        pk.y.clone(),
457        msg,
458    ];
459    let poseidon = Poseidon::new();
460    let hm = match poseidon.hash(hm_input) {
461        Result::Err(_) => return false,
462        Result::Ok(hm) => hm,
463    };
464    let l = match B8.mul_scalar(&sig.s) {
465        Result::Err(_) => return false,
466        Result::Ok(l) => l,
467    };
468    let r = match sig
469        .r_b8
470        .add(&pk.mul_scalar(&(8.to_bigint().unwrap() * hm)).unwrap())
471    {
472        Result::Err(_) => return false,
473        Result::Ok(r) => r,
474    };
475    l.equals(r)
476}
477
478#[cfg(test)]
479mod tests {
480    use super::*;
481    extern crate rustc_hex;
482    use rustc_hex::{FromHex, ToHex};
483
484    /*
485    #[test]
486    fn test_add_same_point() {
487        let p: Point = Point {
488            x: BigInt::parse_bytes(
489                b"17777552123799933955779906779655732241715742912184938656739573121738514868268",
490                10,
491            )
492            .unwrap(),
493            y: BigInt::parse_bytes(
494                b"2626589144620713026669568689430873010625803728049924121243784502389097019475",
495                10,
496            )
497            .unwrap(),
498        };
499        let q: Point = Point {
500            x: BigInt::parse_bytes(
501                b"17777552123799933955779906779655732241715742912184938656739573121738514868268",
502                10,
503            )
504            .unwrap(),
505            y: BigInt::parse_bytes(
506                b"2626589144620713026669568689430873010625803728049924121243784502389097019475",
507                10,
508            )
509            .unwrap(),
510        };
511        let res = p.add(&q).unwrap();
512        assert_eq!(
513            res.x.to_string(),
514            "6890855772600357754907169075114257697580319025794532037257385534741338397365"
515        );
516        assert_eq!(
517            res.y.to_string(),
518            "4338620300185947561074059802482547481416142213883829469920100239455078257889"
519        );
520    }
521    #[test]
522    fn test_add_different_points() {
523        let p: Point = Point {
524            x: BigInt::parse_bytes(
525                b"17777552123799933955779906779655732241715742912184938656739573121738514868268",
526                10,
527            )
528            .unwrap(),
529            y: BigInt::parse_bytes(
530                b"2626589144620713026669568689430873010625803728049924121243784502389097019475",
531                10,
532            )
533            .unwrap(),
534        };
535        let q: Point = Point {
536            x: BigInt::parse_bytes(
537                b"16540640123574156134436876038791482806971768689494387082833631921987005038935",
538                10,
539            )
540            .unwrap(),
541            y: BigInt::parse_bytes(
542                b"20819045374670962167435360035096875258406992893633759881276124905556507972311",
543                10,
544            )
545            .unwrap(),
546        };
547        let res = p.add(&q).unwrap();
548        assert_eq!(
549            res.x.to_string(),
550            "7916061937171219682591368294088513039687205273691143098332585753343424131937"
551        );
552        assert_eq!(
553            res.y.to_string(),
554            "14035240266687799601661095864649209771790948434046947201833777492504781204499"
555        );
556    }
557
558    #[test]
559    fn test_mul_scalar() {
560        let p: Point = Point {
561            x: BigInt::parse_bytes(
562                b"17777552123799933955779906779655732241715742912184938656739573121738514868268",
563                10,
564            )
565            .unwrap(),
566            y: BigInt::parse_bytes(
567                b"2626589144620713026669568689430873010625803728049924121243784502389097019475",
568                10,
569            )
570            .unwrap(),
571        };
572        let res_m = p.mul_scalar(&3.to_bigint().unwrap()).unwrap();
573        let res_a = p.add(&p).unwrap();
574        let res_a = res_a.add(&p).unwrap();
575        assert_eq!(res_m.x, res_a.x);
576        assert_eq!(
577            res_m.x.to_string(),
578            "19372461775513343691590086534037741906533799473648040012278229434133483800898"
579        );
580        assert_eq!(
581            res_m.y.to_string(),
582            "9458658722007214007257525444427903161243386465067105737478306991484593958249"
583        );
584
585        let n = BigInt::parse_bytes(
586            b"14035240266687799601661095864649209771790948434046947201833777492504781204499",
587            10,
588        )
589        .unwrap();
590        let res2 = p.mul_scalar(&n).unwrap();
591        assert_eq!(
592            res2.x.to_string(),
593            "17070357974431721403481313912716834497662307308519659060910483826664480189605"
594        );
595        assert_eq!(
596            res2.y.to_string(),
597            "4014745322800118607127020275658861516666525056516280575712425373174125159339"
598        );
599    }
600
601    #[test]
602    fn test_new_key_sign_verify_mimc_0() {
603        let sk = new_key();
604        let pk = sk.public().unwrap();
605        let msg = 5.to_bigint().unwrap();
606        let sig = sk.sign_mimc(msg.clone()).unwrap();
607        let v = verify_mimc(pk, sig, msg);
608        assert_eq!(v, true);
609    }
610
611    #[test]
612    fn test_new_key_sign_verify_mimc_1() {
613        let sk = new_key();
614        let pk = sk.public().unwrap();
615        let msg = BigInt::parse_bytes(b"123456789012345678901234567890", 10).unwrap();
616        let sig = sk.sign_mimc(msg.clone()).unwrap();
617        let v = verify_mimc(pk, sig, msg);
618        assert_eq!(v, true);
619    }
620    #[test]
621    fn test_new_key_sign_verify_poseidon_0() {
622        let sk = new_key();
623        let pk = sk.public().unwrap();
624        let msg = 5.to_bigint().unwrap();
625        let sig = sk.sign_poseidon(msg.clone()).unwrap();
626        let v = verify_poseidon(pk, sig, msg);
627        assert_eq!(v, true);
628    }
629
630    #[test]
631    fn test_new_key_sign_verify_poseidon_1() {
632        let sk = new_key();
633        let pk = sk.public().unwrap();
634        let msg = BigInt::parse_bytes(b"123456789012345678901234567890", 10).unwrap();
635        let sig = sk.sign_poseidon(msg.clone()).unwrap();
636        let v = verify_poseidon(pk, sig, msg);
637        assert_eq!(v, true);
638    }
639
640    #[test]
641    fn test_point_compress_decompress() {
642        let p: Point = Point {
643            x: BigInt::parse_bytes(
644                b"17777552123799933955779906779655732241715742912184938656739573121738514868268",
645                10,
646            )
647            .unwrap(),
648            y: BigInt::parse_bytes(
649                b"2626589144620713026669568689430873010625803728049924121243784502389097019475",
650                10,
651            )
652            .unwrap(),
653        };
654        let p_comp = p.compress();
655        assert_eq!(
656            p_comp[..].to_hex(),
657            "53b81ed5bffe9545b54016234682e7b2f699bd42a5e9eae27ff4051bc698ce85"
658        );
659        let p2 = decompress_point(p_comp).unwrap();
660        assert_eq!(p.x, p2.x);
661        assert_eq!(p.y, p2.y);
662    }
663
664    #[test]
665    fn test_point_decompress0() {
666        let y_bytes_raw = "b5328f8791d48f20bec6e481d91c7ada235f1facf22547901c18656b6c3e042f"
667            .from_hex()
668            .unwrap();
669        let mut y_bytes: [u8; 32] = [0; 32];
670        y_bytes.copy_from_slice(&y_bytes_raw);
671        let p = decompress_point(y_bytes).unwrap();
672
673        let expected_px_raw = "b86cc8d9c97daef0afe1a4753c54fb2d8a530dc74c7eee4e72b3fdf2496d2113"
674            .from_hex()
675            .unwrap();
676        let mut e_px_bytes: [u8; 32] = [0; 32];
677        e_px_bytes.copy_from_slice(&expected_px_raw);
678        let expected_px: BigInt = BigInt::from_bytes_le(Sign::Plus, &e_px_bytes);
679        assert_eq!(&p.x, &expected_px);
680    }
681
682    #[test]
683    fn test_point_decompress1() {
684        let y_bytes_raw = "70552d3ff548e09266ded29b33ce75139672b062b02aa66bb0d9247ffecf1d0b"
685            .from_hex()
686            .unwrap();
687        let mut y_bytes: [u8; 32] = [0; 32];
688        y_bytes.copy_from_slice(&y_bytes_raw);
689        let p = decompress_point(y_bytes).unwrap();
690
691        let expected_px_raw = "30f1635ba7d56f9cb32c3ffbe6dca508a68c7f43936af11a23c785ce98cb3404"
692            .from_hex()
693            .unwrap();
694        let mut e_px_bytes: [u8; 32] = [0; 32];
695        e_px_bytes.copy_from_slice(&expected_px_raw);
696        let expected_px: BigInt = BigInt::from_bytes_le(Sign::Plus, &e_px_bytes);
697        assert_eq!(&p.x, &expected_px);
698    }
699
700    #[test]
701    fn test_point_decompress_loop() {
702        for _ in 0..5 {
703            let mut rng = rand::thread_rng();
704            let sk_raw = rng.gen_biguint(1024).to_bigint().unwrap();
705            let mut hasher = Blake2b::new();
706            let (_, sk_raw_bytes) = sk_raw.to_bytes_be();
707            hasher.input(sk_raw_bytes);
708            let mut h = hasher.result();
709
710            h[0] = h[0] & 0xF8;
711            h[31] = h[31] & 0x7F;
712            h[31] = h[31] | 0x40;
713
714            let sk = BigInt::from_bytes_le(Sign::Plus, &h[..]);
715            let point = B8.mul_scalar(&sk).unwrap();
716            let cmp_point = point.compress();
717            let dcmp_point = decompress_point(cmp_point).unwrap();
718
719            assert_eq!(&point.x, &dcmp_point.x);
720            assert_eq!(&point.y, &dcmp_point.y);
721        }
722    }
723
724    #[test]
725    fn test_signature_compress_decompress() {
726        let sk = new_key();
727        let pk = sk.public().unwrap();
728
729        for i in 0..5 {
730            let msg_raw = "123456".to_owned() + &i.to_string();
731            let msg = BigInt::parse_bytes(msg_raw.as_bytes(), 10).unwrap();
732            let sig = sk.sign_mimc(msg.clone()).unwrap();
733
734            let compressed_sig = sig.compress();
735            let decompressed_sig = decompress_signature(&compressed_sig).unwrap();
736            assert_eq!(&sig.r_b8.x, &decompressed_sig.r_b8.x);
737            assert_eq!(&sig.r_b8.y, &decompressed_sig.r_b8.y);
738            assert_eq!(&sig.s, &decompressed_sig.s);
739
740            let v = verify_mimc(pk.clone(), decompressed_sig, msg);
741            assert_eq!(v, true);
742        }
743    }
744
745    #[test]
746    fn test_schnorr_signature() {
747        let sk = new_key();
748        let pk = sk.public().unwrap();
749
750        let msg: Vec<u8> = ("123456".to_owned() + &1.to_string()).as_bytes().to_vec();
751        let (s, e) = sk.sign_schnorr(msg.clone()).unwrap();
752        println!("s {:?}", s.x.to_string());
753        println!("s {:?}", s.y.to_string());
754        println!("e {:?}", e.to_string());
755        let verification = verify_schnorr(pk, msg, s, e).unwrap();
756        assert_eq!(true, verification);
757    }
758    */
759    #[test]
760    fn test_aggregated_schnorr_signature() {
761        let m: Vec<u8> = ("123456".to_owned() + &1.to_string()).as_bytes().to_vec();
762
763        let sk0 = new_key();
764        let pk0 = sk0.public().unwrap();
765        let sk1 = new_key();
766        let pk1 = sk1.public().unwrap();
767        let mut pks: Vec<Point> = Vec::new();
768        pks.push(pk0.clone());
769        pks.push(pk1.clone());
770
771        let (k0, r0) = calc_ri().unwrap();
772        let (k1, r1) = calc_ri().unwrap();
773        let mut ris: Vec<Point> = Vec::new();
774        ris.push(r0);
775        ris.push(r1);
776
777        // aggregate public keys
778        let (x, r, l) = aggr_pks(pks, ris).unwrap();
779
780        // perform the signs
781        let sig0 = sk0
782            .sign_aggr(x.clone(), r.clone(), k0, l.clone(), m.clone())
783            .unwrap();
784        let sig1 = sk1
785            .sign_aggr(x.clone(), r.clone(), k1, l.clone(), m.clone())
786            .unwrap();
787
788        // aggregate the signatures
789        let mut sigs: Vec<BigInt> = Vec::new();
790        sigs.push(sig0);
791        sigs.push(sig1);
792        let aggr_sig = aggr_signatures(sigs).unwrap();
793
794        // verify the pk with the aggregated signatures
795        let verification = verify_schnorr_aggregated(x, r, aggr_sig, m).unwrap();
796        assert_eq!(true, verification);
797    }
798}