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
17pub fn new_standard_params() -> Rc<Params> {
20 Rc::new(Params::new(Nid::SECP256K1)) }
22
23pub 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
42pub 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 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 let precursor = KeyPair::new(params);
80 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 let d = hash_to_curve_blake(&to_hash, params);
91
92 let mut coefficients: Vec<CurveBN> = Vec::with_capacity(threshold);
97 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 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 let share_index = hash_to_curve_blake(&to_hash_it, params);
127
128 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 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 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
187pub 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
227pub 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 true => _open_capsule(capsule, decrypting_keypair, check_proof),
243 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 let params = from_public_key.params();
257
258 let r = KeyPair::new(params);
260 let u = KeyPair::new(params);
261
262 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 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 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 #[test]
390 fn encrypt_simple() {
391 let params = new_standard_params();
392 let (alice, _, _) = _generate_credentials(¶ms);
393
394 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, ¶ms));
408 }
409 let x = CurveBN::from_u32(2, ¶ms);
410
411 let res = poly_eval(&coefficients, &x);
412 let fin = res.eq(&CurveBN::from_u32(160, ¶ms));
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(¶ms);
420
421 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(¶ms);
439 let carl = KeyPair::new(¶ms);
440 let carl_pk = carl.public_key();
441
442 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 capsule.set_correctness_keys(&alice.public_key(), &carl_pk, &signer.public_key());
451
452 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(¶ms);
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 capsule.set_correctness_keys(&alice.public_key(), &bob.public_key(), &signer.public_key());
488
489 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 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(¶ms);
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 capsule.set_correctness_keys(&alice.public_key(), &bob.public_key(), &signer.public_key());
519
520 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 let cfrag = match reencrypt(&kfrag, &capsule, true, None, true) {
537 Ok(expr) => expr,
538 Err(err) => panic!("{}", err),
539 };
540 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(¶ms);
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 capsule.set_correctness_keys(&alice.public_key(), &bob.public_key(), &signer.public_key());
559
560 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 let cfrag = match reencrypt(&kfrag, &capsule, true, None, true) {
576 Ok(expr) => expr,
577 Err(err) => panic!("{}", err),
578 };
579 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(¶ms);
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(), ¶ms);
616 }
617
618 #[test]
619 fn curve_bn() {
620 let params = new_standard_params();
621 let one = &CurveBN::from_u32(1, ¶ms);
622 let two = &CurveBN::from_u32(2, ¶ms);
623 let ten = &CurveBN::from_u32(10, ¶ms);
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(¶ms);
641 let r = CurveBN::rand_curve_bn(¶ms);
643 let p = CurvePoint::mul_gen(&r, ¶ms);
644 let r_bytes = r.to_bytes();
645 let p_bytes = p.to_bytes();
646 let p_new = CurvePoint::from_bytes(&p_bytes, ¶ms).expect("Point");
647 assert_eq!(p.eq(&p_new), true);
648 let r_new = CurveBN::from_bytes(&r_bytes, ¶ms).expect("BN");
649 assert_eq!(r.eq(&r_new), true);
650 let p_new2 = CurvePoint::mul_gen(&r_new, ¶ms);
651 assert_eq!(p.eq(&p_new2), true);
652 let s = signer.sign_sha2(&p_bytes);
654 let s_bytes = s.to_bytes();
655 let s_new = Signature::from_bytes(&s_bytes, ¶ms).expect("Signature");
656 assert_eq!(s.eq(&s_new), true);
657 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, ¶ms).expect("KFrag");
671 assert_eq!(kfs[0].eq(&kf_new), true);
672 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, ¶ms).expect("Capsule");
679 assert_eq!(capsule.eq(&capsule_new), true);
680 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, ¶ms).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 }