sapling_crypto_ce/
eddsa.rs

1//! This is an implementation of EdDSA as refered in literature
2//! Generation of randomness is not specified
3
4use bellman::pairing::ff::{Field, PrimeField, PrimeFieldRepr};
5use rand::{Rng};
6use std::io::{self, Read, Write};
7
8use jubjub::{
9    FixedGenerators, 
10    JubjubEngine, 
11    JubjubParams, 
12    Unknown, 
13    edwards::Point,
14    ToUniform};
15
16use util::{hash_to_scalar, hash_to_scalar_s, sha256_hash_to_scalar};
17
18use ::constants::{MATTER_EDDSA_BLAKE2S_PERSONALIZATION};
19
20fn read_scalar<E: JubjubEngine, R: Read>(reader: R) -> io::Result<E::Fs> {
21    let mut s_repr = <E::Fs as PrimeField>::Repr::default();
22    s_repr.read_le(reader)?;
23
24    match E::Fs::from_repr(s_repr) {
25        Ok(s) => Ok(s),
26        Err(_) => Err(io::Error::new(
27            io::ErrorKind::InvalidInput,
28            "scalar is not in field",
29        )),
30    }
31}
32
33fn write_scalar<E: JubjubEngine, W: Write>(s: &E::Fs, writer: W) -> io::Result<()> {
34    s.into_repr().write_le(writer)
35}
36
37fn h_star<E: JubjubEngine>(a: &[u8], b: &[u8]) -> E::Fs {
38    hash_to_scalar::<E>(b"Zcash_RedJubjubH", a, b)
39}
40
41fn h_star_s<E: JubjubEngine>(a: &[u8], b: &[u8]) -> E::Fs {
42    hash_to_scalar_s::<E>(MATTER_EDDSA_BLAKE2S_PERSONALIZATION, a, b)
43}
44
45fn sha256_h_star<E: JubjubEngine>(a: &[u8], b: &[u8]) -> E::Fs {
46    sha256_hash_to_scalar::<E>(&[], a, b)
47}
48
49#[derive(Copy, Clone)]
50pub struct SerializedSignature {
51    rbar: [u8; 32],
52    sbar: [u8; 32],
53}
54
55#[derive(Clone)]
56pub struct Signature<E: JubjubEngine> {
57    pub r: Point<E, Unknown>,
58    pub s: E::Fs,
59}
60
61pub struct PrivateKey<E: JubjubEngine>(pub E::Fs);
62
63#[derive(Clone)]
64pub struct PublicKey<E: JubjubEngine>(pub Point<E, Unknown>);
65
66impl SerializedSignature {
67    pub fn read<R: Read>(mut reader: R) -> io::Result<Self> {
68        let mut rbar = [0u8; 32];
69        let mut sbar = [0u8; 32];
70        reader.read_exact(&mut rbar)?;
71        reader.read_exact(&mut sbar)?;
72        Ok(SerializedSignature { rbar, sbar })
73    }
74
75    pub fn write<W: Write>(&self, mut writer: W) -> io::Result<()> {
76        writer.write_all(&self.rbar)?;
77        writer.write_all(&self.sbar)
78    }
79}
80
81impl<E: JubjubEngine> PrivateKey<E> {
82    pub fn randomize(&self, alpha: E::Fs) -> Self {
83        let mut tmp = self.0;
84        tmp.add_assign(&alpha);
85        PrivateKey(tmp)
86    }
87
88    pub fn read<R: Read>(reader: R) -> io::Result<Self> {
89        let pk = read_scalar::<E, R>(reader)?;
90        Ok(PrivateKey(pk))
91    }
92
93    pub fn write<W: Write>(&self, writer: W) -> io::Result<()> {
94        write_scalar::<E, W>(&self.0, writer)
95    }
96
97    pub fn sign_raw_message<R: Rng>(
98        &self,
99        msg: &[u8],
100        rng: &mut R,
101        p_g: FixedGenerators,
102        params: &E::Params,
103        max_message_size: usize,
104    ) -> Signature<E> {
105        // T = (l_H + 128) bits of randomness
106        // For H*, l_H = 512 bits
107        let mut t = [0u8; 80];
108        rng.fill_bytes(&mut t[..]);
109
110        // Generate randomness using hash function based on some entropy and the message
111        // Generation of randommess is completely off-chain, so we use BLAKE2b!
112        // r = H*(T || M)
113        let r = h_star::<E>(&t[..], msg);
114
115        let pk = PublicKey::from_private(&self, p_g, params);
116        let order_check = pk.0.mul(E::Fs::char(), params);
117        assert!(order_check.eq(&Point::zero()));
118
119        // R = r . P_G
120        let r_g = params.generator(p_g).mul(r, params);
121
122        // In a VERY LIMITED case of messages known to be unique due to application level
123        // and being less than the group order when interpreted as integer, one can sign
124        // the message directly without hashing
125
126        assert!(msg.len() <= max_message_size);
127        assert!(max_message_size * 8 <= E::Fs::CAPACITY as usize);
128        // we also pad message to max size
129
130        // pad with zeroes to match representation length
131        let mut msg_padded : Vec<u8> = msg.iter().cloned().collect();
132        for _ in 0..(32 - msg.len()) {
133            msg_padded.extend(&[0u8;1]);
134        }
135
136        // S = r + M . sk
137        let mut s = E::Fs::to_uniform_32(msg_padded.as_ref());
138        
139        s.mul_assign(&self.0);
140        s.add_assign(&r);
141    
142        let as_unknown = Point::from(r_g);
143        Signature { r: as_unknown, s: s }
144    }
145
146
147    // This is a plain Schnorr signature that does not capture public key into the hash
148    pub fn sign_schnorr_blake2s<R: Rng>(
149        &self,
150        msg: &[u8],
151        rng: &mut R,
152        p_g: FixedGenerators,
153        params: &E::Params,
154    ) -> Signature<E> {
155        // T = (l_H + 128) bits of randomness
156        // For H*, l_H = 512 bits
157        let mut t = [0u8; 80];
158        rng.fill_bytes(&mut t[..]);
159
160        // Generate randomness using hash function based on some entropy and the message
161        // Generation of randommess is completely off-chain, so we use BLAKE2b!
162        // r = H*(T || M)
163        let r = h_star::<E>(&t[..], msg);
164
165        let pk = PublicKey::from_private(&self, p_g, params);
166        let order_check = pk.0.mul(E::Fs::char(), params);
167        assert!(order_check.eq(&Point::zero()));
168
169        // for hash function for a part that is INSIDE the zkSNARK it's 
170        // BLAKE2s has 512 of input and 256 bits of output,
171        // so we use R_X || M as an input to hash only (without public key component),
172        // with a point coordinate padded to 256 bits
173
174        // R = r . P_G
175        let r_g = params.generator(p_g).mul(r, params);
176
177        let (r_g_x, _) = r_g.into_xy();
178        let mut r_g_x_bytes = [0u8; 32];
179        r_g_x.into_repr().write_le(& mut r_g_x_bytes[..]).expect("has serialized r_g_x");
180
181        // we also pad message to 256 bits as LE
182
183        let concatenated: Vec<u8> = r_g_x_bytes.iter().cloned().collect();
184
185        let mut msg_padded : Vec<u8> = msg.iter().cloned().collect();
186        msg_padded.resize(32, 0u8);
187
188        // S = r + H*(R_X || M) . sk
189        let mut s = h_star_s::<E>(&concatenated[..], &msg_padded[..]);
190        s.mul_assign(&self.0);
191        s.add_assign(&r);
192    
193        let as_unknown = Point::from(r_g);
194        Signature { r: as_unknown, s: s }
195    }
196
197    // sign a message by following MuSig protocol, with public key being just a trivial key,
198    // not a multisignature one
199    pub fn musig_sha256_sign<R: Rng>(
200        &self,
201        msg: &[u8],
202        rng: &mut R,
203        p_g: FixedGenerators,
204        params: &E::Params,
205    ) -> Signature<E> {
206        // T = (l_H + 128) bits of randomness
207        // For H*, l_H = 512 bits
208        let mut t = [0u8; 80];
209        rng.fill_bytes(&mut t[..]);
210
211        // Generate randomness using hash function based on some entropy and the message
212        // Generation of randommess is completely off-chain, so we use BLAKE2b!
213        // r = H*(T || M)
214        let r = h_star::<E>(&t[..], msg);
215
216        let pk = PublicKey::from_private(&self, p_g, params);
217        let order_check = pk.0.mul(E::Fs::char(), params);
218        assert!(order_check.eq(&Point::zero()));
219
220        let (pk_x, _) = pk.0.into_xy();
221        let mut pk_x_bytes = [0u8; 32];
222        pk_x.into_repr().write_le(& mut pk_x_bytes[..]).expect("has serialized pk_x");
223
224        // for hash function for a part that is INSIDE the zkSNARK it's 
225        // sha256 that has 3*256 of input and 256 bits of output,
226        // so we use PK_X || R_X || M as an input to hash,
227        // with a point coordinates padded to 256 bits
228
229        // R = r . P_G
230        let r_g = params.generator(p_g).mul(r, params);
231
232        let (r_g_x, _) = r_g.into_xy();
233        let mut r_g_x_bytes = [0u8; 32];
234        r_g_x.into_repr().write_le(& mut r_g_x_bytes[..]).expect("has serialized r_g_x");
235
236        // we also pad message to 256 bits as LE
237
238        let mut concatenated: Vec<u8> = pk_x_bytes.as_ref().to_vec();
239        concatenated.extend(r_g_x_bytes.as_ref().to_vec().into_iter());
240
241        let mut msg_padded : Vec<u8> = msg.iter().cloned().collect();
242        msg_padded.resize(32, 0u8);
243
244        // S = r + H*(PK_X || R_X || M) . sk
245        let mut s = sha256_h_star::<E>(&concatenated[..], &msg_padded[..]);
246        s.mul_assign(&self.0);
247        s.add_assign(&r);
248    
249        let as_unknown = Point::from(r_g);
250        Signature { r: as_unknown, s: s }
251    }
252
253    pub fn sign<R: Rng>(
254        &self,
255        msg: &[u8],
256        rng: &mut R,
257        p_g: FixedGenerators,
258        params: &E::Params,
259    ) -> Signature<E> {
260        // T = (l_H + 128) bits of randomness
261        // For H*, l_H = 512 bits
262        let mut t = [0u8; 80];
263        rng.fill_bytes(&mut t[..]);
264
265        // Generate randomness using hash function based on some entropy and the message
266        // Generation of randommess is completely off-chain, so we use BLAKE2b!
267        // r = H*(T || M)
268        let r = h_star::<E>(&t[..], msg);
269
270        let pk = PublicKey::from_private(&self, p_g, params);
271        let order_check = pk.0.mul(E::Fs::char(), params);
272        assert!(order_check.eq(&Point::zero()));
273
274        // for hash function for a part that is INSIDE the zkSNARK it's 
275        // BLAKE2s has 512 of input and 256 bits of output,
276        // so we use R_X || M as an input to hash only (without public key component), with point coordinates badded to 
277
278        // R = r . P_G
279        let r_g = params.generator(p_g).mul(r, params);
280
281        let (r_g_x, r_g_y) = r_g.into_xy();
282        let mut r_g_x_bytes = [0u8; 32];
283        r_g_x.into_repr().write_le(& mut r_g_x_bytes[..]).expect("has serialized r_g_x");
284
285        let mut r_g_y_bytes = [0u8; 32];
286        r_g_y.into_repr().write_le(& mut r_g_y_bytes[..]).expect("has serialized r_g_y");
287
288        let (pk_x, pk_y) = pk.0.into_xy();
289        let mut pk_x_bytes = [0u8; 32];
290        pk_x.into_repr().write_le(& mut pk_x_bytes[..]).expect("has serialized pk_x");
291
292        let mut pk_y_bytes = [0u8; 32];
293        pk_y.into_repr().write_le(& mut pk_y_bytes[..]).expect("has serialized pk_y");
294
295        let concatenated: Vec<u8> = r_g_x_bytes.iter().chain(r_g_y_bytes.iter()).chain(pk_x_bytes.iter()).chain(pk_y_bytes.iter()).cloned().collect();
296
297        // S = r + H*(Rbar || Pk || M) . sk
298        let mut s = h_star::<E>(&concatenated[..], msg);
299        s.mul_assign(&self.0);
300        s.add_assign(&r);
301    
302        let as_unknown = Point::from(r_g);
303        Signature { r: as_unknown, s: s }
304    }
305}
306
307impl<E: JubjubEngine> PublicKey<E> {
308    pub fn from_private(privkey: &PrivateKey<E>, p_g: FixedGenerators, params: &E::Params) -> Self {
309        let res = params.generator(p_g).mul(privkey.0, params).into();
310        PublicKey(res)
311    }
312
313    pub fn randomize(&self, alpha: E::Fs, p_g: FixedGenerators, params: &E::Params) -> Self {
314        let res: Point<E, Unknown> = params.generator(p_g).mul(alpha, params).into();
315        let res = res.add(&self.0, params);
316        PublicKey(res)
317    }
318
319    pub fn read<R: Read>(reader: R, params: &E::Params) -> io::Result<Self> {
320        let p = Point::read(reader, params)?;
321        Ok(PublicKey(p))
322    }
323
324    pub fn write<W: Write>(&self, writer: W) -> io::Result<()> {
325        self.0.write(writer)
326    }
327
328    pub fn verify(
329        &self,
330        msg: &[u8],
331        sig: &Signature<E>,
332        p_g: FixedGenerators,
333        params: &E::Params,
334    ) -> bool {
335        // c = H*(Rbar || Pk || M)
336        let (r_g_x, r_g_y) = sig.r.into_xy();
337        let mut r_g_x_bytes = [0u8; 32];
338        r_g_x.into_repr().write_le(& mut r_g_x_bytes[..]).expect("has serialized r_g_x");
339
340        let mut r_g_y_bytes = [0u8; 32];
341        r_g_y.into_repr().write_le(& mut r_g_y_bytes[..]).expect("has serialized r_g_y");
342
343        let (pk_x, pk_y) = self.0.into_xy();
344        let mut pk_x_bytes = [0u8; 32];
345        pk_x.into_repr().write_le(& mut pk_x_bytes[..]).expect("has serialized pk_x");
346
347        let mut pk_y_bytes = [0u8; 32];
348        pk_y.into_repr().write_le(& mut pk_y_bytes[..]).expect("has serialized pk_y");
349
350        let concatenated: Vec<u8> = r_g_x_bytes.iter().chain(r_g_y_bytes.iter()).chain(pk_x_bytes.iter()).chain(pk_y_bytes.iter()).cloned().collect();
351
352        let c = h_star::<E>(&concatenated[..], msg);
353
354        // this one is for a simple sanity check. In application purposes the pk will always be in a right group 
355        let order_check_pk = self.0.mul(E::Fs::char(), params);
356        if !order_check_pk.eq(&Point::zero()) {
357            return false;
358        }
359
360        // r is input from user, so always check it!
361        let order_check_r = sig.r.mul(E::Fs::char(), params);
362        if !order_check_r.eq(&Point::zero()) {
363            return false;
364        }
365
366        // 0 = h_G(-S . P_G + R + c . vk)
367        // self.0.mul(c, params).add(&sig.r, params).add(
368        //     &params.generator(p_g).mul(sig.s, params).negate().into(),
369        //     params
370        // ).mul_by_cofactor(params).eq(&Point::zero());
371
372
373        // 0 = -S . P_G + R + c . vk that requires all points to be in the same group
374        self.0.mul(c, params).add(&sig.r, params).add(
375            &params.generator(p_g).mul(sig.s, params).negate().into(),
376            params
377        ).eq(&Point::zero())
378    }
379
380    pub fn verify_for_raw_message(
381        &self,
382        msg: &[u8],
383        sig: &Signature<E>,
384        p_g: FixedGenerators,
385        params: &E::Params,
386        max_message_size: usize,
387    ) -> bool {
388        // c = M
389
390        assert!(msg.len() <= max_message_size);
391        assert!(max_message_size * 8 <= E::Fs::CAPACITY as usize);
392        // assert!(max_message_size * 8 <= E::Fs::Repr::len());
393        // we also pad message to max size
394
395        // pad with zeroes to match representation length
396        let mut msg_padded : Vec<u8> = msg.iter().cloned().collect();
397        msg_padded.resize(32, 0u8);
398
399        let c = E::Fs::to_uniform_32(msg_padded.as_ref());
400
401        // this one is for a simple sanity check. In application purposes the pk will always be in a right group 
402        let order_check_pk = self.0.mul(E::Fs::char(), params);
403        if !order_check_pk.eq(&Point::zero()) {
404            return false;
405        }
406
407        // r is input from user, so always check it!
408        let order_check_r = sig.r.mul(E::Fs::char(), params);
409        if !order_check_r.eq(&Point::zero()) {
410            return false;
411        }
412
413        // 0 = h_G(-S . P_G + R + c . vk)
414        // self.0.mul(c, params).add(&sig.r, params).add(
415        //     &params.generator(p_g).mul(sig.s, params).negate().into(),
416        //     params
417        // ).mul_by_cofactor(params).eq(&Point::zero());
418
419
420        // 0 = -S . P_G + R + c . vk that requires all points to be in the same group
421        self.0.mul(c, params).add(&sig.r, params).add(
422            &params.generator(p_g).mul(sig.s, params).negate().into(),
423            params
424        ).eq(&Point::zero())
425    }
426    
427    pub fn verify_schnorr_blake2s(
428        &self,
429        msg: &[u8],
430        sig: &Signature<E>,
431        p_g: FixedGenerators,
432        params: &E::Params,
433    ) -> bool {
434        // c = H*(R_x || M)
435        let (r_g_x, _) = sig.r.into_xy();
436        let mut r_g_x_bytes = [0u8; 32];
437        r_g_x.into_repr().write_le(& mut r_g_x_bytes[..]).expect("has serialized r_g_x");
438
439        let concatenated: Vec<u8> = r_g_x_bytes.iter().cloned().collect();
440
441        let mut msg_padded : Vec<u8> = msg.iter().cloned().collect();
442        msg_padded.resize(32, 0u8);
443
444        let c = h_star_s::<E>(&concatenated[..], &msg_padded[..]);
445
446        // this one is for a simple sanity check. In application purposes the pk will always be in a right group 
447        let order_check_pk = self.0.mul(E::Fs::char(), params);
448        if !order_check_pk.eq(&Point::zero()) {
449            return false;
450        }
451
452        // r is input from user, so always check it!
453        let order_check_r = sig.r.mul(E::Fs::char(), params);
454        if !order_check_r.eq(&Point::zero()) {
455            return false;
456        }
457
458        // 0 = h_G(-S . P_G + R + c . vk)
459        // self.0.mul(c, params).add(&sig.r, params).add(
460        //     &params.generator(p_g).mul(sig.s, params).negate().into(),
461        //     params
462        // ).mul_by_cofactor(params).eq(&Point::zero());
463
464
465        // 0 = -S . P_G + R + c . vk that requires all points to be in the same group
466        self.0.mul(c, params).add(&sig.r, params).add(
467            &params.generator(p_g).mul(sig.s, params).negate().into(),
468            params
469        ).eq(&Point::zero())
470    }
471
472
473    // verify MuSig. While we are on the Edwards curve with cofactor,
474    // verification will be successful if and only if every element is in the main group
475    pub fn verify_musig_sha256(
476        &self,
477        msg: &[u8],
478        sig: &Signature<E>,
479        p_g: FixedGenerators,
480        params: &E::Params,
481    ) -> bool {
482        // c = H*(PK_x || R_x || M)
483        let (pk_x, _) = self.0.into_xy();
484        let mut pk_x_bytes = [0u8; 32];
485        pk_x.into_repr().write_le(& mut pk_x_bytes[..]).expect("has serialized pk_x");
486
487        let (r_g_x, _) = sig.r.into_xy();
488        let mut r_g_x_bytes = [0u8; 32];
489        r_g_x.into_repr().write_le(& mut r_g_x_bytes[..]).expect("has serialized r_g_x");
490
491        let mut concatenated: Vec<u8> = pk_x_bytes.as_ref().to_vec();
492        concatenated.extend(r_g_x_bytes.as_ref().to_vec().into_iter());
493
494        let mut msg_padded : Vec<u8> = msg.iter().cloned().collect();
495        msg_padded.resize(32, 0u8);
496
497        let c = sha256_h_star::<E>(&concatenated[..], &msg_padded[..]);
498
499        // this one is for a simple sanity check. In application purposes the pk will always be in a right group 
500        let order_check_pk = self.0.mul(E::Fs::char(), params);
501        if !order_check_pk.eq(&Point::zero()) {
502            return false;
503        }
504
505        // r is input from user, so always check it!
506        let order_check_r = sig.r.mul(E::Fs::char(), params);
507        if !order_check_r.eq(&Point::zero()) {
508            return false;
509        }
510
511        // 0 = h_G(-S . P_G + R + c . vk)
512        // self.0.mul(c, params).add(&sig.r, params).add(
513        //     &params.generator(p_g).mul(sig.s, params).negate().into(),
514        //     params
515        // ).mul_by_cofactor(params).eq(&Point::zero());
516
517        // 0 = -S . P_G + R + c . vk that requires all points to be in the same group
518        self.0.mul(c, params).add(&sig.r, params).add(
519            &params.generator(p_g).mul(sig.s, params).negate().into(),
520            params
521        ).eq(&Point::zero())
522    }
523
524    pub fn verify_serialized(
525        &self,
526        msg: &[u8],
527        sig: &SerializedSignature,
528        p_g: FixedGenerators,
529        params: &E::Params,
530    ) -> bool {
531        // c = H*(Rbar || M)
532        let c = h_star::<E>(&sig.rbar[..], msg);
533
534        // Signature checks:
535        // R != invalid
536        let r = match Point::read(&sig.rbar[..], params) {
537            Ok(r) => r,
538            Err(_) => return false,
539        };
540        // S < order(G)
541        // (E::Fs guarantees its representation is in the field)
542        let s = match read_scalar::<E, &[u8]>(&sig.sbar[..]) {
543            Ok(s) => s,
544            Err(_) => return false,
545        };
546        // 0 = h_G(-S . P_G + R + c . vk)
547        self.0.mul(c, params).add(&r, params).add(
548            &params.generator(p_g).mul(s, params).negate().into(),
549            params
550        ).mul_by_cofactor(params).eq(&Point::zero())
551    }
552}
553
554#[cfg(test)]
555mod baby_tests {
556    use bellman::pairing::bn256::Bn256;
557    use rand::thread_rng;
558
559    use alt_babyjubjub::{AltJubjubBn256, fs::Fs, edwards, FixedGenerators};
560
561    use super::*;
562
563    #[test]
564    fn cofactor_check() {
565        let rng = &mut thread_rng();
566        let params = &AltJubjubBn256::new();
567        let zero = edwards::Point::zero();
568        let p_g = FixedGenerators::SpendingKeyGenerator;
569
570        // Get a point of order 8
571        let p8 = loop {
572            let r = edwards::Point::<Bn256, _>::rand(rng, params).mul(Fs::char(), params);
573
574            let r2 = r.double(params);
575            let r4 = r2.double(params);
576            let r8 = r4.double(params);
577
578            if r2 != zero && r4 != zero && r8 == zero {
579                break r;
580            }
581        };
582
583        let sk = PrivateKey::<Bn256>(rng.gen());
584        let vk = PublicKey::from_private(&sk, p_g, params);
585
586        let msg = b"Foo bar";
587        let sig = sk.sign(msg, rng, p_g, params);
588        assert!(vk.verify(msg, &sig, p_g, params));
589
590        // in contrast to redjubjub, in this implementation out-of-group R is NOT allowed!
591        let vktorsion = PublicKey(vk.0.add(&p8, params));
592        assert!(!vktorsion.verify(msg, &sig, p_g, params));
593    }
594
595    // #[test]
596    // fn round_trip_serialization() {
597    //     let rng = &mut thread_rng();
598    //     let p_g = FixedGenerators::SpendingKeyGenerator;
599    //     let params = &AltJubjubBn256::new();
600
601    //     for _ in 0..1000 {
602    //         let sk = PrivateKey::<Bn256>(rng.gen());
603    //         let vk = PublicKey::from_private(&sk, p_g, params);
604    //         let msg = b"Foo bar";
605    //         let sig = sk.sign(msg, rng, p_g, params);
606
607    //         let mut sk_bytes = [0u8; 32];
608    //         let mut vk_bytes = [0u8; 32];
609    //         let mut sig_bytes = [0u8; 64];
610    //         sk.write(&mut sk_bytes[..]).unwrap();
611    //         vk.write(&mut vk_bytes[..]).unwrap();
612    //         sig.write(&mut sig_bytes[..]).unwrap();
613
614    //         let sk_2 = PrivateKey::<Bn256>::read(&sk_bytes[..]).unwrap();
615    //         let vk_2 = PublicKey::from_private(&sk_2, p_g, params);
616    //         let mut vk_2_bytes = [0u8; 32];
617    //         vk_2.write(&mut vk_2_bytes[..]).unwrap();
618    //         assert!(vk_bytes == vk_2_bytes);
619
620    //         let vk_2 = PublicKey::<Bn256>::read(&vk_bytes[..], params).unwrap();
621    //         let sig_2 = Signature::read(&sig_bytes[..]).unwrap();
622    //         assert!(vk.verify(msg, &sig_2, p_g, params));
623    //         assert!(vk_2.verify(msg, &sig, p_g, params));
624    //         assert!(vk_2.verify(msg, &sig_2, p_g, params));
625    //     }
626    // }
627
628    #[test]
629    fn random_signatures() {
630        let rng = &mut thread_rng();
631        let p_g = FixedGenerators::SpendingKeyGenerator;
632        let params = &AltJubjubBn256::new();
633
634        for _ in 0..1000 {
635            let sk = PrivateKey::<Bn256>(rng.gen());
636            let vk = PublicKey::from_private(&sk, p_g, params);
637
638            let msg1 = b"Foo bar";
639            let msg2 = b"Spam eggs";
640
641            let sig1 = sk.sign(msg1, rng, p_g, params);
642            let sig2 = sk.sign(msg2, rng, p_g, params);
643
644            assert!(vk.verify(msg1, &sig1, p_g, params));
645            assert!(vk.verify(msg2, &sig2, p_g, params));
646            assert!(!vk.verify(msg1, &sig2, p_g, params));
647            assert!(!vk.verify(msg2, &sig1, p_g, params));
648
649            let alpha = rng.gen();
650            let rsk = sk.randomize(alpha);
651            let rvk = vk.randomize(alpha, p_g, params);
652
653            let sig1 = rsk.sign(msg1, rng, p_g, params);
654            let sig2 = rsk.sign(msg2, rng, p_g, params);
655
656            assert!(rvk.verify(msg1, &sig1, p_g, params));
657            assert!(rvk.verify(msg2, &sig2, p_g, params));
658            assert!(!rvk.verify(msg1, &sig2, p_g, params));
659            assert!(!rvk.verify(msg2, &sig1, p_g, params));
660        }
661    }
662
663    #[test]
664    fn random_signatures_for_snark() {
665        let rng = &mut thread_rng();
666        let p_g = FixedGenerators::SpendingKeyGenerator;
667        let params = &AltJubjubBn256::new();
668
669        for _ in 0..1000 {
670            let sk = PrivateKey::<Bn256>(rng.gen());
671            let vk = PublicKey::from_private(&sk, p_g, params);
672
673            let msg1 = b"Foo bar";
674            let msg2 = b"Spam eggs";
675
676            let sig1 = sk.sign_schnorr_blake2s(msg1, rng, p_g, params);
677            let sig2 = sk.sign_schnorr_blake2s(msg2, rng, p_g, params);
678
679            assert!(vk.verify_schnorr_blake2s(msg1, &sig1, p_g, params));
680            assert!(vk.verify_schnorr_blake2s(msg2, &sig2, p_g, params));
681            assert!(!vk.verify_schnorr_blake2s(msg1, &sig2, p_g, params));
682            assert!(!vk.verify_schnorr_blake2s(msg2, &sig1, p_g, params));
683
684            let alpha = rng.gen();
685            let rsk = sk.randomize(alpha);
686            let rvk = vk.randomize(alpha, p_g, params);
687
688            let sig1 = rsk.sign_schnorr_blake2s(msg1, rng, p_g, params);
689            let sig2 = rsk.sign_schnorr_blake2s(msg2, rng, p_g, params);
690
691            assert!(rvk.verify_schnorr_blake2s(msg1, &sig1, p_g, params));
692            assert!(rvk.verify_schnorr_blake2s(msg2, &sig2, p_g, params));
693            assert!(!rvk.verify_schnorr_blake2s(msg1, &sig2, p_g, params));
694            assert!(!rvk.verify_schnorr_blake2s(msg2, &sig1, p_g, params));
695        }
696    }
697
698    #[test]
699    fn random_signatures_for_raw_message() {
700        let rng = &mut thread_rng();
701        let p_g = FixedGenerators::SpendingKeyGenerator;
702        let params = &AltJubjubBn256::new();
703
704        for _ in 0..1000 {
705            let sk = PrivateKey::<Bn256>(rng.gen());
706            let vk = PublicKey::from_private(&sk, p_g, params);
707
708            let msg1 = b"Foo bar";
709            let msg2 = b"Spam eggs";
710
711            let max_message_size: usize = 16;
712
713            let sig1 = sk.sign_raw_message(msg1, rng, p_g, params, max_message_size);
714            let sig2 = sk.sign_raw_message(msg2, rng, p_g, params, max_message_size);
715
716            assert!(vk.verify_for_raw_message(msg1, &sig1, p_g, params, max_message_size));
717            assert!(vk.verify_for_raw_message(msg2, &sig2, p_g, params, max_message_size));
718            assert!(!vk.verify_for_raw_message(msg1, &sig2, p_g, params, max_message_size));
719            assert!(!vk.verify_for_raw_message(msg2, &sig1, p_g, params, max_message_size));
720
721            let alpha = rng.gen();
722            let rsk = sk.randomize(alpha);
723            let rvk = vk.randomize(alpha, p_g, params);
724
725            let sig1 = rsk.sign_raw_message(msg1, rng, p_g, params, max_message_size);
726            let sig2 = rsk.sign_raw_message(msg2, rng, p_g, params, max_message_size);
727
728            assert!(rvk.verify_for_raw_message(msg1, &sig1, p_g, params, max_message_size));
729            assert!(rvk.verify_for_raw_message(msg2, &sig2, p_g, params, max_message_size));
730            assert!(!rvk.verify_for_raw_message(msg1, &sig2, p_g, params, max_message_size));
731            assert!(!rvk.verify_for_raw_message(msg2, &sig1, p_g, params, max_message_size));
732        }
733    }
734
735    #[test]
736    fn random_signatures_for_sha256_musig() {
737        let rng = &mut thread_rng();
738        let p_g = FixedGenerators::SpendingKeyGenerator;
739        let params = &AltJubjubBn256::new();
740
741        for _ in 0..1000 {
742            let sk = PrivateKey::<Bn256>(rng.gen());
743            let vk = PublicKey::from_private(&sk, p_g, params);
744
745            let msg1 = b"Foo bar";
746            let msg2 = b"Spam eggs";
747
748            let max_message_size: usize = 16;
749
750            let sig1 = sk.musig_sha256_sign(msg1, rng, p_g, params);
751            let sig2 = sk.musig_sha256_sign(msg2, rng, p_g, params);
752
753            assert!(vk.verify_musig_sha256(msg1, &sig1, p_g, params));
754            assert!(vk.verify_musig_sha256(msg2, &sig2, p_g, params));
755            assert!(!vk.verify_musig_sha256(msg1, &sig2, p_g, params));
756            assert!(!vk.verify_musig_sha256(msg2, &sig1, p_g, params));
757
758            let alpha = rng.gen();
759            let rsk = sk.randomize(alpha);
760            let rvk = vk.randomize(alpha, p_g, params);
761
762            let sig1 = rsk.musig_sha256_sign(msg1, rng, p_g, params);
763            let sig2 = rsk.musig_sha256_sign(msg2, rng, p_g, params);
764
765            assert!(rvk.verify_musig_sha256(msg1, &sig1, p_g, params));
766            assert!(rvk.verify_musig_sha256(msg2, &sig2, p_g, params));
767            assert!(!rvk.verify_musig_sha256(msg1, &sig2, p_g, params));
768            assert!(!rvk.verify_musig_sha256(msg2, &sig1, p_g, params));
769        }
770    }
771
772    #[test]
773    fn get_generator_for_signatures() {
774        let rng = &mut thread_rng();
775        let p_g = FixedGenerators::SpendingKeyGenerator;
776        let params = &AltJubjubBn256::new();
777        let s = <Bn256 as JubjubEngine>::Fs::one();
778        let sk = PrivateKey::<Bn256>(s);
779        let vk = PublicKey::from_private(&sk, p_g, params);
780        let (x, y) = vk.0.into_xy();
781        println!("Public generator x = {}, y = {}", x, y);
782    }
783}