arnaucube
arnaucube/babyjubjub-arkPublic Self-hosted repository
babyjubjub-ark/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
 20pub mod 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    pub 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}
126
127pub fn decompress_point(bb: [u8; 32]) -> Result<Point, String> {
128    // https://tools.ietf.org/html/rfc8032#section-5.2.3
129    let mut sign: bool = false;
130    let mut b = bb.clone();
131    if b[31] & 0x80 != 0x00 {
132        sign = true;
133        b[31] = b[31] & 0x7F;
134    }
135    let y: BigInt = BigInt::from_bytes_le(Sign::Plus, &b[..]);
136    if y >= Q.clone() {
137        return Err("y outside the Finite Field over R".to_string());
138    }
139    let one: BigInt = One::one();
140
141    // x^2 = (1 - y^2) / (a - d * y^2) (mod p)
142    let den = utils::modinv(
143        &utils::modulus(
144            &(&A.clone() - utils::modulus(&(&D.clone() * (&y * &y)), &Q)),
145            &Q,
146        ),
147        &Q,
148    )?;
149    let mut x: BigInt = utils::modulus(&((one - utils::modulus(&(&y * &y), &Q)) * den), &Q);
150    x = utils::modsqrt(&x, &Q)?;
151
152    if sign && !(&x > &(&Q.clone() >> 1)) || (!sign && (&x > &(&Q.clone() >> 1))) {
153        x = x * -1.to_bigint().unwrap();
154    }
155    x = utils::modulus(&x, &Q);
156    Ok(Point { x: x, y: y })
157}
158
159#[derive(Debug, Clone)]
160pub struct Signature {
161    r_b8: Point,
162    s: BigInt,
163}
164
165impl Signature {
166    pub fn compress(&self) -> [u8; 64] {
167        let mut b: Vec<u8> = Vec::new();
168        b.append(&mut self.r_b8.compress().to_vec());
169        let (_, s_bytes) = self.s.to_bytes_le();
170        let mut s_32bytes: [u8; 32] = [0; 32];
171        let len = min(s_bytes.len(), s_32bytes.len());
172        s_32bytes[..len].copy_from_slice(&s_bytes[..len]);
173        b.append(&mut s_32bytes.to_vec());
174        let mut r: [u8; 64] = [0; 64];
175        r[..].copy_from_slice(&b[..]);
176        r
177    }
178}
179
180pub fn decompress_signature(b: &[u8; 64]) -> Result<Signature, String> {
181    let r_b8_bytes: [u8; 32] = *array_ref!(b[..32], 0, 32);
182    let s: BigInt = BigInt::from_bytes_le(Sign::Plus, &b[32..]);
183    let r_b8 = decompress_point(r_b8_bytes);
184    match r_b8 {
185        Result::Err(err) => return Err(err.to_string()),
186        Result::Ok(res) => Ok(Signature {
187            r_b8: res.clone(),
188            s: s,
189        }),
190    }
191}
192
193pub struct PrivateKey {
194    key: BigInt,
195}
196
197impl PrivateKey {
198    pub fn public(&self) -> Result<Point, String> {
199        // https://tools.ietf.org/html/rfc8032#section-5.1.5
200        let pk = B8.mul_scalar(&self.key)?;
201        Ok(pk.clone())
202    }
203
204    pub fn sign_mimc(&self, msg: BigInt) -> Result<Signature, String> {
205        // https://tools.ietf.org/html/rfc8032#section-5.1.6
206        let mut hasher = Blake2b::new();
207        let (_, sk_bytes) = self.key.to_bytes_be();
208        hasher.input(sk_bytes);
209        let mut h = hasher.result(); // h: hash(sk)
210                                     // s: h[32:64]
211        let s = GenericArray::<u8, generic_array::typenum::U32>::from_mut_slice(&mut h[32..64]);
212        let (_, msg_bytes) = msg.to_bytes_be();
213        let r_bytes = utils::concatenate_arrays(s, &msg_bytes);
214        let mut r = BigInt::from_bytes_be(Sign::Plus, &r_bytes[..]);
215        r = utils::modulus(&r, &SUBORDER);
216        let r8: Point = B8.mul_scalar(&r)?;
217        let a = &self.public()?;
218
219        let hm_input = vec![r8.x.clone(), r8.y.clone(), a.x.clone(), a.y.clone(), msg];
220        let mimc7 = Mimc7::new();
221        let hm = mimc7.hash(hm_input)?;
222
223        let mut s = &self.key << 3;
224        s = hm * s;
225        s = r + s;
226        s = s % &SUBORDER.clone();
227
228        Ok(Signature {
229            r_b8: r8.clone(),
230            s: s,
231        })
232    }
233    pub fn sign_poseidon(&self, msg: BigInt) -> Result<Signature, String> {
234        // https://tools.ietf.org/html/rfc8032#section-5.1.6
235        let mut hasher = Blake2b::new();
236        let (_, sk_bytes) = self.key.to_bytes_be();
237        hasher.input(sk_bytes);
238        let mut h = hasher.result(); // h: hash(sk)
239                                     // s: h[32:64]
240        let s = GenericArray::<u8, generic_array::typenum::U32>::from_mut_slice(&mut h[32..64]);
241        let (_, msg_bytes) = msg.to_bytes_be();
242        let r_bytes = utils::concatenate_arrays(s, &msg_bytes);
243        let mut r = BigInt::from_bytes_be(Sign::Plus, &r_bytes[..]);
244        r = utils::modulus(&r, &SUBORDER);
245        let r8: Point = B8.mul_scalar(&r)?;
246        let a = &self.public()?;
247
248        let hm_input = vec![r8.x.clone(), r8.y.clone(), a.x.clone(), a.y.clone(), msg];
249        let poseidon = Poseidon::new();
250        let hm = poseidon.hash(hm_input)?;
251
252        let mut s = &self.key << 3;
253        s = hm * s;
254        s = r + s;
255        s = s % &SUBORDER.clone();
256
257        Ok(Signature {
258            r_b8: r8.clone(),
259            s: s,
260        })
261    }
262
263    pub fn sign_schnorr(&self, m: Vec<u8>) -> Result<(Point, BigInt), String> {
264        // random r
265        let mut rng = rand::thread_rng();
266        let k = rng.gen_biguint(1024).to_bigint().unwrap();
267
268        // r = k·G
269        let r = B8.mul_scalar(&k)?;
270
271        // h = H(x, r, m)
272        let pk = &self.public()?;
273        let h = schnorr_hash(&pk, m, &r)?;
274
275        // s= k+x·h
276        let s = k + &self.key * &h;
277        Ok((r, s))
278    }
279}
280
281pub fn schnorr_hash(pk: &Point, m: Vec<u8>, c: &Point) -> Result<BigInt, String> {
282    let b: &mut Vec<u8> = &mut Vec::new();
283
284    // other option could be to do it without compressing the points, and concatenating x|y
285    b.append(&mut pk.compress().to_vec());
286    b.append(&mut c.compress().to_vec());
287    b.append(&mut m.clone());
288
289    let poseidon = Poseidon::new();
290    let h = poseidon.hash_bytes(b.to_vec())?;
291    println!("h {:?}", h.to_string());
292    Ok(h)
293}
294
295pub fn verify_schnorr(pk: Point, m: Vec<u8>, r: Point, s: BigInt) -> Result<bool, String> {
296    // sG = s·G
297    let sg = B8.mul_scalar(&s)?;
298
299    // r + h · x
300    let h = schnorr_hash(&pk, m, &r)?;
301    let pk_h = pk.mul_scalar(&h)?;
302    let right = r.add(&pk_h)?;
303
304    Ok(sg.equals(right))
305}
306
307pub fn new_key() -> PrivateKey {
308    // https://tools.ietf.org/html/rfc8032#section-5.1.5
309    let mut rng = rand::thread_rng();
310    let sk_raw = rng.gen_biguint(1024).to_bigint().unwrap();
311
312    let mut hasher = Blake2b::new();
313    let (_, sk_raw_bytes) = sk_raw.to_bytes_be();
314    hasher.input(sk_raw_bytes);
315    let mut h = hasher.result();
316
317    h[0] = h[0] & 0xF8;
318    h[31] = h[31] & 0x7F;
319    h[31] = h[31] | 0x40;
320
321    let sk = BigInt::from_bytes_le(Sign::Plus, &h[..]);
322
323    PrivateKey { key: sk }
324}
325
326pub fn verify_mimc(pk: Point, sig: Signature, msg: BigInt) -> bool {
327    let hm_input = vec![
328        sig.r_b8.x.clone(),
329        sig.r_b8.y.clone(),
330        pk.x.clone(),
331        pk.y.clone(),
332        msg,
333    ];
334    let mimc7 = Mimc7::new();
335    let hm = match mimc7.hash(hm_input) {
336        Result::Err(_) => return false,
337        Result::Ok(hm) => hm,
338    };
339    let l = match B8.mul_scalar(&sig.s) {
340        Result::Err(_) => return false,
341        Result::Ok(l) => l,
342    };
343    let r = match sig
344        .r_b8
345        .add(&pk.mul_scalar(&(8.to_bigint().unwrap() * hm)).unwrap())
346    {
347        Result::Err(_) => return false,
348        Result::Ok(r) => r,
349    };
350    l.equals(r)
351}
352pub fn verify_poseidon(pk: Point, sig: Signature, msg: BigInt) -> bool {
353    let hm_input = vec![
354        sig.r_b8.x.clone(),
355        sig.r_b8.y.clone(),
356        pk.x.clone(),
357        pk.y.clone(),
358        msg,
359    ];
360    let poseidon = Poseidon::new();
361    let hm = match poseidon.hash(hm_input) {
362        Result::Err(_) => return false,
363        Result::Ok(hm) => hm,
364    };
365    let l = match B8.mul_scalar(&sig.s) {
366        Result::Err(_) => return false,
367        Result::Ok(l) => l,
368    };
369    let r = match sig
370        .r_b8
371        .add(&pk.mul_scalar(&(8.to_bigint().unwrap() * hm)).unwrap())
372    {
373        Result::Err(_) => return false,
374        Result::Ok(r) => r,
375    };
376    l.equals(r)
377}
378
379#[cfg(test)]
380mod tests {
381    use super::*;
382    extern crate rustc_hex;
383    use rustc_hex::{FromHex, ToHex};
384
385    #[test]
386    fn test_add_same_point() {
387        let p: Point = Point {
388            x: BigInt::parse_bytes(
389                b"17777552123799933955779906779655732241715742912184938656739573121738514868268",
390                10,
391            )
392            .unwrap(),
393            y: BigInt::parse_bytes(
394                b"2626589144620713026669568689430873010625803728049924121243784502389097019475",
395                10,
396            )
397            .unwrap(),
398        };
399        let q: Point = Point {
400            x: BigInt::parse_bytes(
401                b"17777552123799933955779906779655732241715742912184938656739573121738514868268",
402                10,
403            )
404            .unwrap(),
405            y: BigInt::parse_bytes(
406                b"2626589144620713026669568689430873010625803728049924121243784502389097019475",
407                10,
408            )
409            .unwrap(),
410        };
411        let res = p.add(&q).unwrap();
412        assert_eq!(
413            res.x.to_string(),
414            "6890855772600357754907169075114257697580319025794532037257385534741338397365"
415        );
416        assert_eq!(
417            res.y.to_string(),
418            "4338620300185947561074059802482547481416142213883829469920100239455078257889"
419        );
420    }
421    #[test]
422    fn test_add_different_points() {
423        let p: Point = Point {
424            x: BigInt::parse_bytes(
425                b"17777552123799933955779906779655732241715742912184938656739573121738514868268",
426                10,
427            )
428            .unwrap(),
429            y: BigInt::parse_bytes(
430                b"2626589144620713026669568689430873010625803728049924121243784502389097019475",
431                10,
432            )
433            .unwrap(),
434        };
435        let q: Point = Point {
436            x: BigInt::parse_bytes(
437                b"16540640123574156134436876038791482806971768689494387082833631921987005038935",
438                10,
439            )
440            .unwrap(),
441            y: BigInt::parse_bytes(
442                b"20819045374670962167435360035096875258406992893633759881276124905556507972311",
443                10,
444            )
445            .unwrap(),
446        };
447        let res = p.add(&q).unwrap();
448        assert_eq!(
449            res.x.to_string(),
450            "7916061937171219682591368294088513039687205273691143098332585753343424131937"
451        );
452        assert_eq!(
453            res.y.to_string(),
454            "14035240266687799601661095864649209771790948434046947201833777492504781204499"
455        );
456    }
457
458    #[test]
459    fn test_mul_scalar() {
460        let p: Point = Point {
461            x: BigInt::parse_bytes(
462                b"17777552123799933955779906779655732241715742912184938656739573121738514868268",
463                10,
464            )
465            .unwrap(),
466            y: BigInt::parse_bytes(
467                b"2626589144620713026669568689430873010625803728049924121243784502389097019475",
468                10,
469            )
470            .unwrap(),
471        };
472        let res_m = p.mul_scalar(&3.to_bigint().unwrap()).unwrap();
473        let res_a = p.add(&p).unwrap();
474        let res_a = res_a.add(&p).unwrap();
475        assert_eq!(res_m.x, res_a.x);
476        assert_eq!(
477            res_m.x.to_string(),
478            "19372461775513343691590086534037741906533799473648040012278229434133483800898"
479        );
480        assert_eq!(
481            res_m.y.to_string(),
482            "9458658722007214007257525444427903161243386465067105737478306991484593958249"
483        );
484
485        let n = BigInt::parse_bytes(
486            b"14035240266687799601661095864649209771790948434046947201833777492504781204499",
487            10,
488        )
489        .unwrap();
490        let res2 = p.mul_scalar(&n).unwrap();
491        assert_eq!(
492            res2.x.to_string(),
493            "17070357974431721403481313912716834497662307308519659060910483826664480189605"
494        );
495        assert_eq!(
496            res2.y.to_string(),
497            "4014745322800118607127020275658861516666525056516280575712425373174125159339"
498        );
499    }
500
501    // #[test]
502    // fn test_new_key_sign_verify_mimc_0() {
503    //     let sk = new_key();
504    //     let pk = sk.public().unwrap();
505    //     let msg = 5.to_bigint().unwrap();
506    //     let sig = sk.sign_mimc(msg.clone()).unwrap();
507    //     let v = verify_mimc(pk, sig, msg);
508    //     assert_eq!(v, true);
509    // }
510    //
511    // #[test]
512    // fn test_new_key_sign_verify_mimc_1() {
513    //     let sk = new_key();
514    //     let pk = sk.public().unwrap();
515    //     let msg = BigInt::parse_bytes(b"123456789012345678901234567890", 10).unwrap();
516    //     let sig = sk.sign_mimc(msg.clone()).unwrap();
517    //     let v = verify_mimc(pk, sig, msg);
518    //     assert_eq!(v, true);
519    // }
520    #[test]
521    fn test_new_key_sign_verify_poseidon_0() {
522        let sk = new_key();
523        let pk = sk.public().unwrap();
524        let msg = 5.to_bigint().unwrap();
525        let sig = sk.sign_poseidon(msg.clone()).unwrap();
526        let v = verify_poseidon(pk, sig, msg);
527        assert_eq!(v, true);
528    }
529
530    #[test]
531    fn test_new_key_sign_verify_poseidon_1() {
532        let sk = new_key();
533        let pk = sk.public().unwrap();
534        let msg = BigInt::parse_bytes(b"123456789012345678901234567890", 10).unwrap();
535        let sig = sk.sign_poseidon(msg.clone()).unwrap();
536        let v = verify_poseidon(pk, sig, msg);
537        assert_eq!(v, true);
538    }
539
540    #[test]
541    fn test_point_compress_decompress() {
542        let p: Point = Point {
543            x: BigInt::parse_bytes(
544                b"17777552123799933955779906779655732241715742912184938656739573121738514868268",
545                10,
546            )
547            .unwrap(),
548            y: BigInt::parse_bytes(
549                b"2626589144620713026669568689430873010625803728049924121243784502389097019475",
550                10,
551            )
552            .unwrap(),
553        };
554        let p_comp = p.compress();
555        assert_eq!(
556            p_comp[..].to_hex(),
557            "53b81ed5bffe9545b54016234682e7b2f699bd42a5e9eae27ff4051bc698ce85"
558        );
559        let p2 = decompress_point(p_comp).unwrap();
560        assert_eq!(p.x, p2.x);
561        assert_eq!(p.y, p2.y);
562    }
563
564    #[test]
565    fn test_point_decompress0() {
566        let y_bytes_raw = "b5328f8791d48f20bec6e481d91c7ada235f1facf22547901c18656b6c3e042f"
567            .from_hex()
568            .unwrap();
569        let mut y_bytes: [u8; 32] = [0; 32];
570        y_bytes.copy_from_slice(&y_bytes_raw);
571        let p = decompress_point(y_bytes).unwrap();
572
573        let expected_px_raw = "b86cc8d9c97daef0afe1a4753c54fb2d8a530dc74c7eee4e72b3fdf2496d2113"
574            .from_hex()
575            .unwrap();
576        let mut e_px_bytes: [u8; 32] = [0; 32];
577        e_px_bytes.copy_from_slice(&expected_px_raw);
578        let expected_px: BigInt = BigInt::from_bytes_le(Sign::Plus, &e_px_bytes);
579        assert_eq!(&p.x, &expected_px);
580    }
581
582    #[test]
583    fn test_point_decompress1() {
584        let y_bytes_raw = "70552d3ff548e09266ded29b33ce75139672b062b02aa66bb0d9247ffecf1d0b"
585            .from_hex()
586            .unwrap();
587        let mut y_bytes: [u8; 32] = [0; 32];
588        y_bytes.copy_from_slice(&y_bytes_raw);
589        let p = decompress_point(y_bytes).unwrap();
590
591        let expected_px_raw = "30f1635ba7d56f9cb32c3ffbe6dca508a68c7f43936af11a23c785ce98cb3404"
592            .from_hex()
593            .unwrap();
594        let mut e_px_bytes: [u8; 32] = [0; 32];
595        e_px_bytes.copy_from_slice(&expected_px_raw);
596        let expected_px: BigInt = BigInt::from_bytes_le(Sign::Plus, &e_px_bytes);
597        assert_eq!(&p.x, &expected_px);
598    }
599
600    // #[test]
601    // fn test_point_decompress_loop() {
602    //     for _ in 0..5 {
603    //         let mut rng = rand::thread_rng();
604    //         let sk_raw = rng.gen_biguint(1024).to_bigint().unwrap();
605    //         let mut hasher = Blake2b::new();
606    //         let (_, sk_raw_bytes) = sk_raw.to_bytes_be();
607    //         hasher.input(sk_raw_bytes);
608    //         let mut h = hasher.result();
609    //
610    //         h[0] = h[0] & 0xF8;
611    //         h[31] = h[31] & 0x7F;
612    //         h[31] = h[31] | 0x40;
613    //
614    //         let sk = BigInt::from_bytes_le(Sign::Plus, &h[..]);
615    //         let point = B8.mul_scalar(&sk).unwrap();
616    //         let cmp_point = point.compress();
617    //         let dcmp_point = decompress_point(cmp_point).unwrap();
618    //
619    //         assert_eq!(&point.x, &dcmp_point.x);
620    //         assert_eq!(&point.y, &dcmp_point.y);
621    //     }
622    // }
623
624    // #[test]
625    // fn test_signature_compress_decompress() {
626    //     let sk = new_key();
627    //     let pk = sk.public().unwrap();
628    //
629    //     for i in 0..5 {
630    //         let msg_raw = "123456".to_owned() + &i.to_string();
631    //         let msg = BigInt::parse_bytes(msg_raw.as_bytes(), 10).unwrap();
632    //         let sig = sk.sign_mimc(msg.clone()).unwrap();
633    //
634    //         let compressed_sig = sig.compress();
635    //         let decompressed_sig = decompress_signature(&compressed_sig).unwrap();
636    //         assert_eq!(&sig.r_b8.x, &decompressed_sig.r_b8.x);
637    //         assert_eq!(&sig.r_b8.y, &decompressed_sig.r_b8.y);
638    //         assert_eq!(&sig.s, &decompressed_sig.s);
639    //
640    //         let v = verify_mimc(pk.clone(), decompressed_sig, msg);
641    //         assert_eq!(v, true);
642    //     }
643    // }
644
645    #[test]
646    fn test_schnorr_signature() {
647        let sk = new_key();
648        let pk = sk.public().unwrap();
649
650        let msg: Vec<u8> = ("123456".to_owned() + &1.to_string()).as_bytes().to_vec();
651        let (s, e) = sk.sign_schnorr(msg.clone()).unwrap();
652        println!("s {:?}", s.x.to_string());
653        println!("s {:?}", s.y.to_string());
654        println!("e {:?}", e.to_string());
655        let verification = verify_schnorr(pk, msg, s, e).unwrap();
656        assert_eq!(true, verification);
657    }
658}