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