umbral_rs/
pre.rs

1pub use crate::internal::capsule::{CFrag, Capsule};
2pub use crate::internal::keys::{KeyPair, Signer};
3pub use crate::internal::kfrag::{KFrag, KFragMode};
4
5use crate::internal::curve::Params;
6use crate::internal::curve::{CurveBN, CurvePoint};
7use crate::internal::errors::PreErrors;
8use crate::internal::schemes::{dem_decrypt, dem_encrypt, hash_to_curve_blake, kdf, DEM_MIN_SIZE};
9use crate::internal::utils::{lambda_coeff, new_constant_sorrow, poly_eval};
10use std::rc::Rc;
11
12use openssl::{
13    bn::{BigNum, MsbOption},
14    nid::Nid,
15};
16
17/// Creates the standard parameters needed to operate with this crate, i.e.
18/// the SECP256K1 curve
19pub fn new_standard_params() -> Rc<Params> {
20    Rc::new(Params::new(Nid::SECP256K1)) //Curve
21}
22
23/// Performs an encryption using the DEM schema and encapsulates a key
24/// for the sender using the public key provided.
25///
26/// Returns the ciphertext and the KEM Capsule.
27pub fn encrypt(
28    from_public_key: &CurvePoint,
29    plaintext: &Vec<u8>,
30) -> Result<(Vec<u8>, Capsule), PreErrors> {
31    let (key, capsule) = match _encapsulate(&from_public_key) {
32        Ok(kc) => kc,
33        Err(err) => return Err(err),
34    };
35
36    match dem_encrypt(&key, plaintext, Some(&capsule.to_bytes())) {
37        Ok(ciphertext) => return Ok((ciphertext, capsule)),
38        Err(err) => return Err(err),
39    };
40}
41
42/// Creates a re-encryption key from the delegating public key to the
43/// receiving public key, and splits it in KFrags, using Shamir's Secret Sharing.
44///
45/// Requires a threshold number of KFrags out of N (`n` here).
46///
47/// Returns a list of N KFrags
48/// Note: the name of this function in the paper is ReKeyGen
49pub fn generate_kfrags(
50    delegating_keypair: &KeyPair,
51    receiving_pk: &CurvePoint,
52    threshold: usize,
53    n: usize,
54    signer: &Signer,
55    mode: KFragMode,
56) -> (Result<Vec<KFrag>, PreErrors>, CurvePoint) {
57    // a fake point to return in case of error
58    let fake_point = CurvePoint::from_ec_point(
59        delegating_keypair.public_key().params().u_point(),
60        delegating_keypair.public_key().params(),
61    );
62
63    if threshold <= 0 || threshold > n {
64        return (Err(PreErrors::InvalidKFragThreshold), fake_point);
65    }
66    if !(delegating_keypair
67        .public_key()
68        .params()
69        .eq(receiving_pk.params()))
70    {
71        return (Err(PreErrors::KeysParametersNotEq), fake_point);
72    }
73
74    let params = delegating_keypair.public_key().params();
75
76    /* The precursor point is used as an ephemeral public key in a DH key exchange,
77    and the resulting shared secret 'dh_point' is used to derive other secret values
78    */
79    let precursor = KeyPair::new(params);
80    // Multiply precursor with receiving_pk to obtain DH point
81    let dh_point = receiving_pk * precursor.private_key();
82
83    let mut to_hash = precursor.public_key().to_bytes();
84    to_hash.append(&mut receiving_pk.to_bytes());
85    to_hash.append(&mut dh_point.to_bytes());
86    let to_hash2 = to_hash.clone();
87    to_hash.append(&mut new_constant_sorrow("NON_INTERACTIVE"));
88
89    // Secret value 'd' allows to make Umbral non-interactive
90    let d = hash_to_curve_blake(&to_hash, params);
91
92    /////////////////
93    // Secret sharing
94
95    // Coefficients of the generating polynomial
96    let mut coefficients: Vec<CurveBN> = Vec::with_capacity(threshold);
97    // Coefficient zero
98    let coef_zero = delegating_keypair.private_key() / &d;
99    coefficients.push(coef_zero);
100    for _ in 1..threshold {
101        coefficients.push(CurveBN::rand_curve_bn(params));
102    }
103
104    // Kfrags generation
105    let mut kfrags: Vec<KFrag> = Vec::new();
106    let order_bits_size = params.order().num_bits();
107    for _ in 0..n {
108        let mut kfrag_id = BigNum::new().unwrap();
109        match kfrag_id.rand(order_bits_size, MsbOption::MAYBE_ZERO, false) {
110            Ok(_) => (),
111            Err(_) => {
112                return (Err(PreErrors::GenericError), fake_point);
113            }
114        }
115
116        let mut to_hash_it = to_hash2.clone();
117        to_hash_it.append(&mut new_constant_sorrow("X_COORDINATE"));
118        to_hash_it.append(&mut kfrag_id.to_vec());
119
120        /*
121            The index of the re-encryption key share (which in Shamir's Secret
122            Sharing corresponds to x in the tuple (x, f(x)), with f being the
123            generating polynomial), is used to prevent reconstruction of the
124            re-encryption key without Bob's intervention
125        */
126        let share_index = hash_to_curve_blake(&to_hash_it, params);
127
128        /*
129            The re-encryption key share is the result of evaluating the generating
130            polynomial for the index value
131        */
132        let rk = poly_eval(&coefficients, &share_index);
133
134        let u = CurvePoint::from_ec_point(params.u_point(), params);
135        let commitment_point = &u * &rk;
136
137        // Signing for receiver
138        let mut to_hash_it2 = kfrag_id.to_vec();
139        to_hash_it2.append(&mut delegating_keypair.public_key().to_bytes());
140        to_hash_it2.append(&mut receiving_pk.to_bytes());
141        to_hash_it2.append(&mut commitment_point.to_bytes());
142        to_hash_it2.append(&mut precursor.public_key().to_bytes());
143        let signature_for_receiver = signer.sign_sha2(&to_hash_it2);
144
145        // Signing for proxy
146        let mut to_hash_it3 = kfrag_id.to_vec();
147        to_hash_it3.append(&mut commitment_point.to_bytes());
148        to_hash_it3.append(&mut precursor.public_key().to_bytes());
149        match mode {
150            KFragMode::DelegatingAndReceiving => {
151                to_hash_it3.append(
152                    &mut (KFragMode::DelegatingAndReceiving as u8)
153                        .to_ne_bytes()
154                        .to_vec(),
155                );
156                to_hash_it3.append(&mut delegating_keypair.public_key().to_bytes());
157                to_hash_it3.append(&mut receiving_pk.to_bytes());
158            }
159            KFragMode::DelegatingOnly => {
160                to_hash_it3.append(&mut (KFragMode::DelegatingOnly as u8).to_ne_bytes().to_vec());
161                to_hash_it3.append(&mut delegating_keypair.public_key().to_bytes());
162            }
163            KFragMode::ReceivingOnly => {
164                to_hash_it3.append(&mut (KFragMode::ReceivingOnly as u8).to_ne_bytes().to_vec());
165                to_hash_it3.append(&mut receiving_pk.to_bytes());
166            }
167            KFragMode::NoKey => {
168                to_hash_it3.append(&mut (KFragMode::NoKey as u8).to_ne_bytes().to_vec());
169            }
170        }
171        let signature_for_proxy = signer.sign_sha2(&to_hash_it3);
172
173        kfrags.push(KFrag::new(
174            &kfrag_id,
175            &rk,
176            &commitment_point,
177            &precursor.public_key(),
178            &signature_for_proxy,
179            &signature_for_receiver,
180            mode,
181        ));
182    }
183
184    (Ok(kfrags), dh_point)
185}
186
187/// Performs the re-encryption operation of proxies and produces a capsule
188/// fragment, i.e. a CFrag, from a KFrag given in input.
189pub fn reencrypt(
190    kfrag: &KFrag,
191    capsule: &Capsule,
192    provide_proof: bool,
193    metadata: Option<Vec<u8>>,
194    verify_kfrag: bool,
195) -> Result<CFrag, PreErrors> {
196    if !capsule.verify() {
197        return Err(PreErrors::InvalidCapsule);
198    }
199
200    if verify_kfrag {
201        match kfrag.verify_for_capsule(capsule) {
202            Ok(res) => {
203                if !res {
204                    return Err(PreErrors::InvalidKFrag);
205                }
206            }
207            Err(err) => return Err(err),
208        }
209    }
210
211    let rk = kfrag.re_key_share();
212    let e_i = capsule.e() * rk;
213    let v_i = capsule.v() * rk;
214
215    let mut cfrag = CFrag::new(&e_i, &v_i, kfrag.id(), kfrag.precursor());
216
217    if provide_proof {
218        match cfrag.prove_correctness(capsule, kfrag, metadata) {
219            Ok(_) => (),
220            Err(err) => return Err(err),
221        }
222    }
223
224    return Ok(cfrag);
225}
226
227/// Opens the capsule and gets what's inside. If it is a symmetric key, then
228/// it is used to decrypt the ciphertext and return the resulting cleartext.
229pub fn decrypt(
230    ciphertext: Vec<u8>,
231    capsule: &Capsule,
232    decrypting_keypair: &KeyPair,
233    check_proof: bool,
234) -> Result<Vec<u8>, PreErrors> {
235    if ciphertext.len() < DEM_MIN_SIZE {
236        return Err(PreErrors::CiphertextError);
237    }
238
239    let encapsulated_key = match !capsule.attached_cfrags().is_empty() {
240        //Since there are cfrags attached, we assume this is the receiver opening the Capsule.
241        //(i.e., this is a re-encrypted capsule)
242        true => _open_capsule(capsule, decrypting_keypair, check_proof),
243        //Since there aren't cfrags attached, we assume this is Alice opening the Capsule.
244        //(i.e., this is an original capsule)
245        false => _decapsulate(capsule, decrypting_keypair.private_key()),
246    };
247
248    match encapsulated_key {
249        Ok(key) => dem_decrypt(&key, &ciphertext, Some(&capsule.to_bytes())),
250        Err(err) => Err(err),
251    }
252}
253
254pub fn _encapsulate(from_public_key: &CurvePoint) -> Result<(Vec<u8>, Capsule), PreErrors> {
255    // BN context needed for the heap
256    let params = from_public_key.params();
257
258    // R point generation
259    let r = KeyPair::new(params);
260    let u = KeyPair::new(params);
261
262    // Get sign
263    let mut to_hash = r.public_key().to_bytes();
264    to_hash.append(&mut u.public_key().to_bytes());
265    let h = hash_to_curve_blake(&to_hash, params);
266
267    let s = u.private_key() + &(r.private_key() * &h);
268
269    let shared_key = from_public_key * &(r.private_key() + u.private_key());
270
271    match kdf(&shared_key.to_bytes()) {
272        Ok(key) => Ok((key, Capsule::new(r.public_key(), u.public_key(), &s))),
273        Err(err) => Err(err),
274    }
275}
276
277pub fn _decapsulate(capsule: &Capsule, receiving: &CurveBN) -> Result<Vec<u8>, PreErrors> {
278    if !capsule.verify() {
279        return Err(PreErrors::InvalidCapsule);
280    }
281
282    let shared_key = &(capsule.e() + capsule.v()) * receiving;
283    kdf(&shared_key.to_bytes())
284}
285
286fn _decapsulate_reencrypted(
287    capsule: &Capsule,
288    receiver_keypair: &KeyPair,
289) -> Result<Vec<u8>, PreErrors> {
290    let params = capsule.e().params();
291
292    let pk = receiver_keypair.public_key();
293    let sk = receiver_keypair.private_key();
294
295    let precursor = capsule.attached_cfrags()[0].precursor();
296    let dh_point = precursor * sk;
297
298    // Combination of CFrags via Shamir's Secret Sharing reconstruction
299    let mut xs: Vec<CurveBN> = Vec::new();
300    for cfrag in capsule.attached_cfrags() {
301        let mut to_hash = precursor.to_bytes();
302        to_hash.append(&mut pk.to_bytes());
303        to_hash.append(&mut dh_point.to_bytes());
304        to_hash.append(&mut new_constant_sorrow("X_COORDINATE"));
305        to_hash.append(&mut cfrag.kfrag_id().to_vec());
306
307        xs.push(hash_to_curve_blake(&to_hash, params));
308    }
309
310    let mut e_summands: Vec<CurvePoint> = Vec::new();
311    let mut v_summands: Vec<CurvePoint> = Vec::new();
312    for i in 0..xs.len() {
313        let cfrag = &capsule.attached_cfrags()[i];
314        let x = &xs[i];
315        if !cfrag.precursor().eq(&precursor) {
316            return Err(PreErrors::InvalidCFrag);
317        }
318        let lambda_i = lambda_coeff(x, &xs);
319        e_summands.push(cfrag.e_i_point() * &lambda_i);
320        v_summands.push(cfrag.v_i_point() * &lambda_i);
321    }
322
323    let mut e_prime = e_summands[0].to_owned();
324    let mut v_prime = v_summands[0].to_owned();
325    for i in 1..e_summands.len() {
326        e_prime = &e_prime + &e_summands[i];
327        v_prime = &v_prime + &v_summands[i];
328    }
329
330    // Secret value 'd' allows to make Umbral non-interactive
331    let mut to_hash = precursor.to_bytes();
332    to_hash.append(&mut pk.to_bytes());
333    to_hash.append(&mut dh_point.to_bytes());
334    to_hash.append(&mut new_constant_sorrow("NON_INTERACTIVE"));
335    let d = hash_to_curve_blake(&to_hash, params);
336
337    let (e, v, s) = (capsule.e(), capsule.v(), capsule.sign());
338    let mut to_hash2 = e.to_bytes();
339    to_hash2.append(&mut v.to_bytes());
340    let h = hash_to_curve_blake(&to_hash2, params);
341
342    let orig_pk = match capsule.delegating_key() {
343        Some(d) => d,
344        None => return Err(PreErrors::CapsuleNoCorrectnessProvided),
345    };
346
347    let first = orig_pk * &(s / &d);
348    let second = &(&e_prime * &h) + &v_prime;
349    if !first.eq(&second) {
350        return Err(PreErrors::DecryptionError);
351    }
352
353    let shared_key = &(&e_prime + &v_prime) * &d;
354
355    kdf(&shared_key.to_bytes())
356}
357
358fn _open_capsule(
359    capsule: &Capsule,
360    receiver_keypair: &KeyPair,
361    check_proof: bool,
362) -> Result<Vec<u8>, PreErrors> {
363    if !capsule.verify() {
364        return Err(PreErrors::InvalidCapsule);
365    }
366
367    if check_proof {
368        let mut offending = false;
369        for cfrag in capsule.attached_cfrags() {
370            match cfrag.verify_correctness(capsule) {
371                Ok(correct) => offending = offending && correct,
372                Err(err) => return Err(err),
373            }
374        }
375        if offending {
376            return Err(PreErrors::InvalidCFrag);
377        }
378    }
379
380    _decapsulate_reencrypted(&capsule, &receiver_keypair)
381}
382
383#[cfg(test)]
384mod tests {
385    use super::*;
386    use crate::internal::keys::Signature;
387    //use std::{thread, time};
388
389    #[test]
390    fn encrypt_simple() {
391        let params = new_standard_params();
392        let (alice, _, _) = _generate_credentials(&params);
393
394        // encrypt
395        let plaintext = b"Hello, umbral!".to_vec();
396        match encrypt(&alice.public_key(), &plaintext) {
397            Ok(_) => assert_eq!(true, true),
398            Err(err) => panic!("Error: {}", err),
399        };
400    }
401
402    #[test]
403    fn poly_eval_test() {
404        let params = new_standard_params();
405        let mut coefficients: Vec<CurveBN> = Vec::with_capacity(5);
406        for i in 0..5 {
407            coefficients.push(CurveBN::from_u32(i + 2, &params));
408        }
409        let x = CurveBN::from_u32(2, &params);
410
411        let res = poly_eval(&coefficients, &x);
412        let fin = res.eq(&CurveBN::from_u32(160, &params));
413        assert_eq!(fin, true);
414    }
415
416    #[test]
417    fn kfrags() {
418        let params = new_standard_params();
419        let (alice, signer, bob) = _generate_credentials(&params);
420
421        // keyfrags
422        match generate_kfrags(
423            &alice,
424            &bob.public_key(),
425            2,
426            5,
427            &signer,
428            KFragMode::DelegatingAndReceiving,
429        ) {
430            (Ok(_), _) => assert_eq!(true, true),
431            _ => panic!("Error in generate_kfrags"),
432        };
433    }
434
435    #[test]
436    fn false_verify_kfrag() {
437        let params = new_standard_params();
438        let (alice, signer, bob) = _generate_credentials(&params);
439        let carl = KeyPair::new(&params);
440        let carl_pk = carl.public_key();
441
442        // encrypt
443        let plaintext = b"Hello, umbral!".to_vec();
444        let (_, mut capsule) = match encrypt(&alice.public_key(), &plaintext) {
445            Ok(expr) => expr,
446            Err(err) => panic!("{}", err),
447        };
448
449        //set correctness keys
450        capsule.set_correctness_keys(&alice.public_key(), &carl_pk, &signer.public_key());
451
452        // keyfrags
453        let kfrags = match generate_kfrags(
454            &alice,
455            &bob.public_key(),
456            2,
457            5,
458            &signer,
459            KFragMode::DelegatingAndReceiving,
460        ) {
461            (Ok(ks), _) => ks,
462            _ => panic!("Error in generate_kfrags"),
463        };
464
465        let mut res = false;
466        for kfrag in kfrags {
467            res = res
468                && kfrag
469                    .verify_for_capsule(&capsule)
470                    .expect("Errors in KFrag verifying")
471        }
472
473        assert_eq!(res, false);
474    }
475
476    #[test]
477    fn reencrypt_simple() {
478        let params = new_standard_params();
479        let (alice, signer, bob) = _generate_credentials(&params);
480
481        let plaintext = b"Hello, umbral!".to_vec();
482        let (_, mut capsule) = match encrypt(&alice.public_key(), &plaintext) {
483            Ok(expr) => expr,
484            Err(err) => panic!("{}", err),
485        };
486        //set correctness keys
487        capsule.set_correctness_keys(&alice.public_key(), &bob.public_key(), &signer.public_key());
488
489        //kfrags
490        let kfrags = match generate_kfrags(
491            &alice,
492            &bob.public_key(),
493            2,
494            5,
495            &signer,
496            KFragMode::DelegatingAndReceiving,
497        ) {
498            (Ok(ks), _) => ks,
499            _ => panic!("Error in generate_kfrags"),
500        };
501
502        //reencrypt
503        let r = reencrypt(&kfrags[0], &capsule, true, None, true);
504        assert_eq!(r.is_ok(), true);
505    }
506
507    #[test]
508    fn attach_cfrag() {
509        let params = new_standard_params();
510        let (alice, signer, bob) = _generate_credentials(&params);
511
512        let plaintext = b"Hello, umbral!".to_vec();
513        let (_, mut capsule) = match encrypt(&alice.public_key(), &plaintext) {
514            Ok(expr) => expr,
515            Err(err) => panic!("{}", err),
516        };
517        //set correctness keys
518        capsule.set_correctness_keys(&alice.public_key(), &bob.public_key(), &signer.public_key());
519
520        //kfrags
521        let kfrags = match generate_kfrags(
522            &alice,
523            &bob.public_key(),
524            2,
525            5,
526            &signer,
527            KFragMode::DelegatingAndReceiving,
528        ) {
529            (Ok(ks), _) => ks,
530            _ => panic!("Error in generate_kfrags"),
531        };
532
533        let mut res = true;
534        for kfrag in kfrags {
535            //reencrypt
536            let cfrag = match reencrypt(&kfrag, &capsule, true, None, true) {
537                Ok(expr) => expr,
538                Err(err) => panic!("{}", err),
539            };
540            //attach cfrag
541            res = res && capsule.attach_cfrag(&cfrag).is_ok();
542        }
543        assert_eq!(res, true);
544    }
545
546    #[test]
547    fn decrypt_frags() {
548        let params = new_standard_params();
549        let (alice, signer, bob) = _generate_credentials(&params);
550
551        let plaintext = b"Hello, umbral!".to_vec();
552        let (ciphertext, mut capsule) = match encrypt(&alice.public_key(), &plaintext) {
553            Ok(expr) => expr,
554            Err(err) => panic!("{}", err),
555        };
556
557        //set correctness keys
558        capsule.set_correctness_keys(&alice.public_key(), &bob.public_key(), &signer.public_key());
559
560        //kfrags
561        let kfrags = match generate_kfrags(
562            &alice,
563            &bob.public_key(),
564            2,
565            5,
566            &signer,
567            KFragMode::DelegatingAndReceiving,
568        ) {
569            (Ok(ks), _) => ks,
570            _ => panic!("Error in generate_kfrags"),
571        };
572
573        for kfrag in kfrags {
574            //reencrypt
575            let cfrag = match reencrypt(&kfrag, &capsule, true, None, true) {
576                Ok(expr) => expr,
577                Err(err) => panic!("{}", err),
578            };
579            //attach cfrag
580            match capsule.attach_cfrag(&cfrag) {
581                Ok(_) => (),
582                Err(err) => panic!("{}", err),
583            };
584        }
585
586        let res = decrypt(ciphertext, &capsule, &bob, true);
587        let plaintext_bob = match res {
588            Ok(p) => p,
589            Err(err) => panic!("Error {}", err),
590        };
591        println!("{:?}", String::from_utf8(plaintext_bob.to_owned()).unwrap());
592        assert_eq!(plaintext, plaintext_bob);
593    }
594
595    #[test]
596    fn decrypt_simple() {
597        let params = new_standard_params();
598        let (alice, _, _) = _generate_credentials(&params);
599
600        let plaintext = b"Hello, umbral!".to_vec();
601        let (ciphertext, capsule) = match encrypt(&alice.public_key(), &plaintext) {
602            Ok(expr) => expr,
603            Err(err) => panic!("{}", err),
604        };
605
606        let res = decrypt(ciphertext, &capsule, &alice, true);
607        let plaintext_dec = res.expect("Error in Decryption");
608        println!("{:?}", String::from_utf8(plaintext_dec.to_owned()).unwrap());
609        assert_eq!(plaintext, plaintext_dec);
610    }
611
612    #[test]
613    fn hash_to_bn() {
614        let params = new_standard_params();
615        hash_to_curve_blake(&b"gadhj".to_vec(), &params);
616    }
617
618    #[test]
619    fn curve_bn() {
620        let params = new_standard_params();
621        let one = &CurveBN::from_u32(1, &params);
622        let two = &CurveBN::from_u32(2, &params);
623        let ten = &CurveBN::from_u32(10, &params);
624        let three = one + two;
625        assert_eq!(three.bn().to_vec(), vec![3; 1]);
626
627        let nine = ten - one;
628        assert_eq!(nine.bn().to_vec(), vec![9; 1]);
629
630        let three_again = &nine / &three;
631        assert_eq!(three_again.bn().to_vec(), vec![3; 1]);
632
633        let eighteen = &nine * two;
634        assert_eq!(eighteen.bn().to_vec(), vec![18; 1]);
635    }
636
637    #[test]
638    fn bytes_conv() {
639        let params = new_standard_params();
640        let (alice, signer, bob) = _generate_credentials(&params);
641        // CurveBN and CurvePoint
642        let r = CurveBN::rand_curve_bn(&params);
643        let p = CurvePoint::mul_gen(&r, &params);
644        let r_bytes = r.to_bytes();
645        let p_bytes = p.to_bytes();
646        let p_new = CurvePoint::from_bytes(&p_bytes, &params).expect("Point");
647        assert_eq!(p.eq(&p_new), true);
648        let r_new = CurveBN::from_bytes(&r_bytes, &params).expect("BN");
649        assert_eq!(r.eq(&r_new), true);
650        let p_new2 = CurvePoint::mul_gen(&r_new, &params);
651        assert_eq!(p.eq(&p_new2), true);
652        // Signature
653        let s = signer.sign_sha2(&p_bytes);
654        let s_bytes = s.to_bytes();
655        let s_new = Signature::from_bytes(&s_bytes, &params).expect("Signature");
656        assert_eq!(s.eq(&s_new), true);
657        //KFrags
658        let kfs = match generate_kfrags(
659            &alice,
660            &bob.public_key(),
661            1,
662            1,
663            &signer,
664            KFragMode::DelegatingAndReceiving,
665        ) {
666            (Ok(ks), _) => ks,
667            _ => panic!("Error in generate_kfrags"),
668        };
669        let kf_bytes = kfs[0].to_bytes();
670        let kf_new = KFrag::from_bytes(&kf_bytes, &params).expect("KFrag");
671        assert_eq!(kfs[0].eq(&kf_new), true);
672        // Capsule
673        let (_, mut capsule) = match encrypt(&alice.public_key(), &b"Hello, umbral!".to_vec()) {
674            Ok(expr) => expr,
675            Err(err) => panic!("{}", err),
676        };
677        let capsule_bytes = capsule.to_bytes();
678        let capsule_new = Capsule::from_bytes(&capsule_bytes, &params).expect("Capsule");
679        assert_eq!(capsule.eq(&capsule_new), true);
680        //CFrags
681        capsule.set_correctness_keys(&alice.public_key(), &bob.public_key(), &signer.public_key());
682        let cfrag = match reencrypt(&kf_new, &capsule, true, None, true) {
683            Ok(expr) => expr,
684            Err(err) => panic!("{}", err),
685        };
686        let cfrag_bytes = cfrag.to_bytes();
687        let cfrag_new = CFrag::from_bytes(&cfrag_bytes, &params).expect("CFrag");
688        assert_eq!(cfrag.eq(&cfrag_new), true);
689    }
690
691    fn _generate_credentials(params: &Rc<Params>) -> (KeyPair, Signer, KeyPair) {
692        let alice = KeyPair::new(params);
693        let signer = Signer::new(params);
694        let bob = KeyPair::new(params);
695
696        (alice, signer, bob)
697    }
698    /*
699    #[test]
700    fn new_test_mule_1() {
701      let params = new_standard_params();
702      let (alice, signer, bob) = _generate_credentials(&params);
703
704      //////////// Generate key x
705      // BN context needed for the heap
706      let params = alice.public_key().params();
707      // R point generation
708      let r = KeyPair::new(params);
709      let u = KeyPair::new(params);
710      let shared_key = alice.public_key() * &(r.private_key() + u.private_key());
711      let key_x = match kdf(&shared_key.to_bytes()) {
712        Ok(key) => key,
713        Err(err) => panic!("{}", err),
714      };
715      ////////////
716
717      let sizes: [usize; 7] = [10485, 52428, 104857, 524288, 1048576, 5242880, 10485760];
718
719      for outer in 0..7 {
720        let mut slice_payload = vec![0u8; sizes[outer]].into_boxed_slice();
721        getrandom::getrandom(&mut slice_payload).expect("Error in payload generation");
722        let plaintext = slice_payload.to_vec(); //b"Hello, umbral!".to_vec();
723        let ciphertext = match dem_encrypt(&key_x, &plaintext, None) {
724          Ok(ciphertext) => ciphertext,
725          Err(err) => panic!("{}", err),
726        };
727
728        let tries = 10;
729        let mut duration_enc = 0;
730        let mut duration_dec = 0;
731        for _ in 0..10 {
732          //////////// Encrypt
733          let now_enc = time::Instant::now();
734          // Tender
735          let mut slice_tender = vec![0u8; 150].into_boxed_slice();
736          getrandom::getrandom(&mut slice_tender).expect("Error in tender generation");
737          let tender = slice_tender.to_vec();
738          let tender_signature = signer.sign_sha2(&tender);
739          // Balance
740          let mut slice_balance = vec![0u8; 110].into_boxed_slice();
741          getrandom::getrandom(&mut slice_balance).expect("Error in balance generation");
742          let balance = slice_balance.to_vec();
743          let balance_signature = signer.sign_sha2(&balance);
744          // Address
745          let mut slice_address = vec![0u8; 42].into_boxed_slice();
746          getrandom::getrandom(&mut slice_address).expect("Error in address generation");
747          let address = slice_address.to_vec();
748          let address_signature = signer.sign_sha2(&address);
749          // Shared key
750          let shared_key_alice = bob.public_key() * alice.private_key();
751          let key_alice = match kdf(&shared_key_alice.to_bytes()) {
752            Ok(key) => key,
753            Err(err) => panic!("{}", err),
754          };
755          let other_data = {
756            let mut r = tender.clone();
757            r.extend_from_slice(&tender_signature.to_bytes());
758            r.extend_from_slice(&balance);
759            r.extend_from_slice(&balance_signature.to_bytes());
760            r.extend_from_slice(&address_signature.to_bytes());
761            r
762          };
763          let other_data_ciphertext = match dem_encrypt(&key_alice, &other_data, None) {
764            Ok(ciphertext) => ciphertext,
765            Err(err) => panic!("{}", err),
766          };
767          duration_enc += now_enc.elapsed().as_millis();
768
769          //////////// Decrypt
770          let now_dec = time::Instant::now();
771          let shared_key_bob = alice.public_key() * bob.private_key();
772          let key_bob = match kdf(&shared_key_bob.to_bytes()) {
773            Ok(key) => key,
774            Err(err) => panic!("{}", err),
775          };
776          let other_data_dec = match dem_decrypt(&key_bob, &other_data_ciphertext, None) {
777            Ok(p) => p,
778            Err(err) => panic!("{}", err),
779          };
780          let tender_verification = tender_signature.verify_sha2(&tender, &signer.public_key());
781          assert_eq!(tender_verification, true);
782          let balance_verification = balance_signature.verify_sha2(&balance, &signer.public_key());
783          assert_eq!(balance_verification, true);
784          let address_verification = address_signature.verify_sha2(&address, &signer.public_key());
785          assert_eq!(address_verification, true);
786          duration_dec += now_dec.elapsed().as_millis();
787          assert_eq!(other_data, other_data_dec);
788        }
789        println!(
790          "Enc {:?}, Dec {:?}",
791          duration_enc / tries,
792          duration_dec / tries
793        );
794      }
795    }
796
797    #[test]
798    fn new_test_mule_2() {
799      let params = new_standard_params();
800      let (alice, signerb, bob) = _generate_credentials(&params);
801      let (_, signera, _) = _generate_credentials(&params);
802
803      //////////// Public key encryption
804      // BN context needed for the heap
805      let params = alice.public_key().params();
806      // R point generation
807      let r = KeyPair::new(params);
808      let u = KeyPair::new(params);
809      let shared_key = alice.public_key() * &(r.private_key() + u.private_key());
810      let key_x = match kdf(&shared_key.to_bytes()) {
811        Ok(key) => key,
812        Err(err) => panic!("{}", err),
813      };
814      ////////////
815
816      let sizes: [usize; 7] = [10485, 52428, 104857, 524288, 1048576, 5242880, 10485760];
817
818      for outer in 0..7 {
819        let mut slice_payload = vec![0u8; sizes[outer]].into_boxed_slice();
820        getrandom::getrandom(&mut slice_payload).expect("Error in payload generation");
821        let plaintext = slice_payload.to_vec();
822        //////////// R Public key encryption 2
823        let ciphertext = match dem_encrypt(&key_x, &plaintext, None) {
824          Ok(ciphertext) => ciphertext,
825          Err(err) => panic!("{}", err),
826        };
827        //////////// Bob encryption
828        // Tender
829        let mut slice_tender = vec![0u8; 96].into_boxed_slice();
830        getrandom::getrandom(&mut slice_tender).expect("Error in tender generation");
831        let tender = slice_tender.to_vec();
832        let tender_signature = signerb.sign_sha2(&tender);
833        // Shared key
834        let shared_key_bob = alice.public_key() * bob.private_key();
835        let key_bob = match kdf(&shared_key_bob.to_bytes()) {
836          Ok(key) => key,
837          Err(err) => panic!("{}", err),
838        };
839        let other_data_tender = {
840          let mut r = tender.clone();
841          r.extend_from_slice(&tender_signature.to_bytes());
842          r
843        };
844        let other_data_tender_ciphertext = match dem_encrypt(&key_bob, &other_data_tender, None) {
845          Ok(ciphertext) => ciphertext,
846          Err(err) => panic!("{}", err),
847        };
848
849        let tries = 10;
850        let mut duration_dec_tender = 0;
851        let mut duration_enc_balance = 0;
852        let mut duration_dec_balance = 0;
853        let mut duration_dec_plaintext = 0;
854        for _ in 0..10 {
855          //////////// Tender Decrypt
856          let now_dec = time::Instant::now();
857          let shared_key_alice = bob.public_key() * alice.private_key();
858          let key_alice = match kdf(&shared_key_alice.to_bytes()) {
859            Ok(key) => key,
860            Err(err) => panic!("{}", err),
861          };
862          let other_data_tender_dec =
863            match dem_decrypt(&key_alice, &other_data_tender_ciphertext, None) {
864              Ok(p) => p,
865              Err(err) => panic!("{}", err),
866            };
867          let tender_verification = tender_signature.verify_sha2(&tender, &signerb.public_key());
868          assert_eq!(tender_verification, true);
869          duration_dec_tender += now_dec.elapsed().as_millis();
870          assert_eq!(other_data_tender, other_data_tender_dec);
871
872          //////////// Encrypt
873          let now_enc = time::Instant::now();
874          // Balance
875          let mut slice_balance = vec![0u8; 110].into_boxed_slice();
876          getrandom::getrandom(&mut slice_balance).expect("Error in balance generation");
877          let balance = slice_balance.to_vec();
878          let balance_signature = signera.sign_sha2(&balance);
879          let other_data_balance = {
880            let mut r = balance.clone();
881            r.extend_from_slice(&balance_signature.to_bytes());
882            r
883          };
884          let other_data_balance_ciphertext = match dem_encrypt(&key_alice, &other_data_balance, None)
885          {
886            Ok(ciphertext) => ciphertext,
887            Err(err) => panic!("{}", err),
888          };
889          duration_enc_balance += now_enc.elapsed().as_millis();
890
891          //////////// Bob Decrypt
892          let now_dec_2 = time::Instant::now();
893          let other_data_balance_dec =
894            match dem_decrypt(&key_bob, &other_data_balance_ciphertext, None) {
895              Ok(p) => p,
896              Err(err) => panic!("{}", err),
897            };
898          let balance_verification = balance_signature.verify_sha2(&balance, &signera.public_key());
899          assert_eq!(balance_verification, true);
900          duration_dec_balance += now_dec_2.elapsed().as_millis();
901          assert_eq!(other_data_balance, other_data_balance_dec);
902
903          //////////// Payload Decrypt
904          let now_dec_3 = time::Instant::now();
905          let shared_key_ecies = &(r.public_key() + u.public_key()) * alice.private_key();
906          let key_ecies = match kdf(&shared_key_ecies.to_bytes()) {
907            Ok(key) => key,
908            Err(err) => panic!("{}", err),
909          };
910          let plaintext_dec = match dem_decrypt(&key_ecies, &ciphertext, None) {
911            Ok(p) => p,
912            Err(err) => panic!("{}", err),
913          };
914          duration_dec_plaintext += now_dec_3.elapsed().as_millis();
915          assert_eq!(plaintext, plaintext_dec);
916        }
917        println!(
918          "Dec Tender {:?}, Enc Balance {:?}, Dec Balance {:?}, Dec Payload {:?}",
919          duration_dec_tender / tries,
920          duration_enc_balance / tries,
921          duration_dec_balance / tries,
922          duration_dec_plaintext / tries
923        );
924      }
925    }
926    */
927}