1pub mod integer_arith;
173pub mod polyarith;
174#[cfg(feature = "bench")]
175pub mod rqpoly;
176#[cfg(not(feature = "bench"))]
177mod rqpoly;
178pub mod traits;
179mod serialize;
180mod utils;
181#[cfg(feature = "bench")]
182pub mod randutils;
183#[cfg(not(feature = "bench"))]
184mod randutils;
185
186use integer_arith::scalar::Scalar;
187use integer_arith::{SuperTrait, ArithUtils};
188use traits::*;
189use std::sync::Arc;
190
191pub type FVPlaintext<T> = Vec<T>;
193pub type DefaultFVPlaintext = Vec<u8>;
195pub type FVCiphertext<T> = (RqPoly<T>, RqPoly<T>);
197
198pub type DefaultShemeType = FV<Scalar>;
200
201pub struct SecretKey<T>(RqPoly<T>);
203use rqpoly::{FiniteRingElt, RqPoly, RqPolyContext};
204
205pub fn default() -> DefaultShemeType {
206 FV::<Scalar>::default_2048()
207}
208
209pub fn default_with_plaintext_mod(t: u32) -> DefaultShemeType {
210 FV::<Scalar>::default_2048_with_plaintext_mod(t)
211}
212
213pub struct FV<T>
215where
216 T: ArithUtils<T>,
217{
218 pub n: usize,
219 pub t: T,
220 pub q: T,
221 pub delta: T,
222 pub stdev: f64,
223 pub qdivtwo: T,
224 pub flooding_stdev: f64,
225 context: Arc<RqPolyContext<T>>,
226 poly_multiplier: fn(&RqPoly<T>, &RqPoly<T>) -> RqPoly<T>,
227}
228
229impl<T> FV<T>
230where
231T: ArithUtils<T>{
232 fn convert_pt_u8_to_scalar(&self, pt: &DefaultFVPlaintext) -> FVPlaintext<T>{
233 if T::to_u64(&self.t) != 256u64{
234 panic!("plaintext modulus should be 256")
235 }
236 let mut pt1 = vec![];
237 for pt_coeff in pt.iter(){
238 pt1.push(T::from_u32(*pt_coeff as u32, &self.t));
239 }
240 pt1
241 }
242
243 fn convert_pt_scalar_to_u8(&self, pt: FVPlaintext<T>) -> DefaultFVPlaintext{
244 if T::to_u64(&self.t) != 256u64{
245 panic!("plaintext modulus should be 256")
246 }
247 let mut pt1 = vec![];
248 for pt_coeff in pt.iter(){
249 pt1.push(T::to_u64(pt_coeff) as u8);
250 }
251 pt1
252 }
253}
254
255impl<T> CipherPlainAddition<FVCiphertext<T>, FVPlaintext<T>> for FV<T>
256where
257 RqPoly<T>: FiniteRingElt,
258 T: Clone + ArithUtils<T> + PartialEq,
259{
260 fn add_plain_inplace(&self, ct: &mut FVCiphertext<T>, pt: &FVPlaintext<T>) {
262 for (ct_coeff, pt_coeff) in ct.1.coeffs.iter_mut().zip(pt.iter()) {
263 let temp = T::mul(pt_coeff, &self.delta);
264 *ct_coeff = T::add_mod(ct_coeff, &temp, &self.q);
265 }
266 }
267}
268
269
270impl<T> CipherPlainAddition<FVCiphertext<T>, DefaultFVPlaintext> for FV<T>
271where
272 RqPoly<T>: FiniteRingElt,
273 T: Clone + ArithUtils<T> + PartialEq + From<u32>,
274{
275 fn add_plain_inplace(&self, ct: &mut FVCiphertext<T>, pt: &DefaultFVPlaintext) {
277 for (ct_coeff, pt_coeff) in ct.1.coeffs.iter_mut().zip(pt.iter()) {
278 let temp = T::mul(&T::from(*pt_coeff as u32), &self.delta);
279 *ct_coeff = T::add_mod(ct_coeff, &temp, &self.q);
280 }
281 }
282}
283
284
285impl<T> AdditiveHomomorphicScheme<FVCiphertext<T>, SecretKey<T>> for FV<T>
286where
287 RqPoly<T>: FiniteRingElt,
288 T: SuperTrait<T>,
289{
290 fn add_inplace(&self, ct1: &mut FVCiphertext<T>, ct2: &FVCiphertext<T>) {
291 ct1.0.add_inplace(&ct2.0);
292 ct1.1.add_inplace(&ct2.1);
293 }
294
295 fn rerandomize(&self, ct: &mut FVCiphertext<T>, pk: &FVCiphertext<T>) {
297 let c_mask = self.encrypt_zero(pk);
299 self.add_inplace(ct, &c_mask);
300
301 let elarge =
303 randutils::sample_gaussian_poly(self.context.clone(), self.flooding_stdev);
304 ct.1.add_inplace(&elarge);
305 }
306}
307
308impl<T> FV<T>
310where
311 T: SuperTrait<T>+ PartialEq + Serializable,
312 RqPoly<T>: FiniteRingElt + NTT<T>,
313{
314 pub fn new(n: usize, q: &T) -> Self {
315 Self::new_with_ptxt_mod(n, &T::new_modulus(256), q)
316 }
317
318 pub fn new_with_ptxt_mod(n: usize, t: &T, q: &T) -> Self {
319 let context = Arc::new(RqPolyContext::new(n, q));
320 type RqPolyMultiplier<T> = fn(&RqPoly<T>, &RqPoly<T>) -> RqPoly<T>;
321 let default_multiplier: RqPolyMultiplier<T>;
322 if context.is_ntt_enabled {
323 default_multiplier =
324 |op1: &RqPoly<T>, op2: &RqPoly<T>| -> RqPoly<T> { op1.multiply_fast(op2) };
325 } else {
326 default_multiplier =
327 |op1: &RqPoly<T>, op2: &RqPoly<T>| -> RqPoly<T> { op1.multiply(op2) };
328 }
329 FV {
330 n,
331 t: t.clone(),
332 flooding_stdev: 2f64.powi(40),
333 delta: T::div(q, t), qdivtwo: T::div(q, &T::from(2_u32)), q: q.clone(),
336 stdev: 3.2,
337 context,
338 poly_multiplier: default_multiplier,
339 }
340 }
341
342 pub fn from_bytes(&self, bytes: &Vec<u8>) -> FVCiphertext<T>{
343 let mut ct = FVCiphertext::<T>::from_bytes(bytes);
344 self.set_context(&mut ct);
345 ct
346 }
347
348 fn set_context(&self, ctxt: &mut FVCiphertext<T>){
349 ctxt.0.set_context(self.context.clone());
350 ctxt.1.set_context(self.context.clone());
351 }
352}
353
354impl FV<Scalar> {
355 pub fn default_2048() -> FV<Scalar> {
357 let q = Scalar::new_modulus(18014398492704769u64);
358 Self::new(2048, &q)
359 }
360
361 pub fn default_2048_with_plaintext_mod(t: u32) -> FV<Scalar> {
363 if t > 2u32.pow(10){
364 panic!("plain text modulus should not be more than 10 bits.")
365 }
366 let q = Scalar::new_modulus(18014398492704769u64);
367 let t = Scalar::new_modulus(t as u64);
368 Self::new_with_ptxt_mod(2048, &t, &q)
369 }
370}
371
372#[cfg(feature = "bigint")]
373impl FV<BigInt> {
374 pub fn default_2048() -> FV<BigInt> {
375 let q = BigInt::from_hex("3fffffff000001");
376 let context = Arc::new(RqPolyContext::new(2048, &q));
377 let multiplier = |op1: &RqPoly<BigInt>, op2: &RqPoly<BigInt>| -> RqPoly<BigInt> {
378 op1.multiply_fast(op2)
379 };
380
381 FV {
382 n: 2048,
383 q: q.clone(),
384 delta: &q / 256,
385 qdivtwo: &q / 2,
386 stdev: 3.2,
387 flooding_stdev: 1e40_f64,
388 context: context,
389 poly_multiplier: multiplier,
390 }
391 }
392}
393
394
395impl<T> KeyGeneration<FVCiphertext<T>, SecretKey<T>> for FV<T>
396where
397 RqPoly<T>: FiniteRingElt,
398 T: SuperTrait<T>,
399{
400 fn generate_key(&self) -> SecretKey<T> {
401 let mut skpoly = randutils::sample_ternary_poly(self.context.clone());
402 if self.context.is_ntt_enabled {
403 skpoly.forward_transform();
404 }
405 SecretKey(skpoly)
406 }
407
408 fn generate_keypair(&self) -> (FVCiphertext<T>, SecretKey<T>) {
409 let sk = self.generate_key();
410 let mut pk = self.encrypt_zero_sk(&sk);
411 if self.context.is_ntt_enabled {
412 pk.0.forward_transform();
413 pk.1.forward_transform();
414 }
415 (pk, sk)
416 }
417}
418
419impl<T> EncryptionOfZeros<FVCiphertext<T>, SecretKey<T>> for FV<T>
420where
421 RqPoly<T>: FiniteRingElt,
422 T: SuperTrait<T>,
423{
424 fn encrypt_zero(&self, pk: &FVCiphertext<T>) -> FVCiphertext<T> {
425 let mut u = randutils::sample_ternary_poly_prng(self.context.clone());
426 let e1 = randutils::sample_gaussian_poly(self.context.clone(), self.stdev);
427 let e2 = randutils::sample_gaussian_poly(self.context.clone(), self.stdev);
428
429 if self.context.is_ntt_enabled {
430 u.forward_transform();
431 }
432 let mut c0 = (self.poly_multiplier)(&pk.0, &u);
435 c0.add_inplace(&e1);
436
437 let mut c1 = (self.poly_multiplier)(&pk.1, &u);
441 c1.add_inplace(&e2);
442
443 (c0, c1)
444 }
445
446 fn encrypt_zero_sk(&self, sk: &SecretKey<T>) -> FVCiphertext<T> {
447 let e = randutils::sample_gaussian_poly(self.context.clone(), self.stdev);
448 let a = randutils::sample_uniform_poly(self.context.clone());
449 let mut b = (self.poly_multiplier)(&a, &sk.0);
450 b.add_inplace(&e);
451 (a, b)
452 }
453}
454
455impl<T> PKEncryption<FVCiphertext<T>, FVPlaintext<T>, SecretKey<T>> for FV<T>
456where
457 RqPoly<T>: FiniteRingElt,
458 T: SuperTrait<T>,
459{
460 fn encrypt(&self, pt: &FVPlaintext<T>, pk: &FVCiphertext<T>) -> FVCiphertext<T> {
461 let (c0, mut c1) = self.encrypt_zero(pk);
464 let iter = c1.coeffs.iter_mut().zip(pt.iter());
466 for (x, y) in iter {
467 let temp = T::mul(y, &self.delta);
468 *x = T::add_mod(x, &temp, &self.q);
469 }
470 (c0, c1)
471 }
472}
473
474impl<T> PKEncryption<FVCiphertext<T>, DefaultFVPlaintext, SecretKey<T>> for FV<T>
475where
476 RqPoly<T>: FiniteRingElt,
477 T: SuperTrait<T>,
478{
479 fn encrypt(&self, pt: &DefaultFVPlaintext, pk: &FVCiphertext<T>) -> FVCiphertext<T> {
480 let pt1 = self.convert_pt_u8_to_scalar(pt);
481 self.encrypt(&pt1, pk)
482 }
483}
484
485impl<T> SKEncryption<FVCiphertext<T>, DefaultFVPlaintext, SecretKey<T>> for FV<T>
486where
487 RqPoly<T>: FiniteRingElt,
488 T: SuperTrait<T>,
489{
490 fn encrypt_sk(&self, pt: &DefaultFVPlaintext, sk: &SecretKey<T>) -> FVCiphertext<T>
491 {
492 let pt1 = self.convert_pt_u8_to_scalar(pt);
493 self.encrypt_sk(&pt1, sk)
494 }
495
496 fn decrypt(&self, ct: &FVCiphertext<T>, sk: &SecretKey<T>) -> DefaultFVPlaintext{
497 let pt1 = self.decrypt(ct, sk);
498 self.convert_pt_scalar_to_u8(pt1)
499 }
500}
501
502impl<T> SKEncryption<FVCiphertext<T>, FVPlaintext<T>, SecretKey<T>> for FV<T>
504where
505 RqPoly<T>: FiniteRingElt,
506 T: SuperTrait<T>,
507{
508 fn encrypt_sk(&self, pt: &FVPlaintext<T>, sk: &SecretKey<T>) -> FVCiphertext<T> {
509 let e = randutils::sample_gaussian_poly(self.context.clone(), self.stdev);
510 let a = randutils::sample_uniform_poly(self.context.clone());
511
512
513 let mut b = (self.poly_multiplier)(&a, &sk.0);
514 b.add_inplace(&e);
515
516 let iter = b.coeffs.iter_mut().zip(pt.iter());
518 for (x, y) in iter {
519 let temp = T::mul(y, &self.delta);
520 *x = T::add_mod(x, &temp, &self.q);
521 }
522 (a, b)
523 }
524
525 fn decrypt(&self, ct: &FVCiphertext<T>, sk: &SecretKey<T>) -> FVPlaintext<T> {
526 let temp1 = (self.poly_multiplier)(&ct.0, &sk.0);
527 let mut phase = ct.1.clone();
528 phase.sub_inplace(&temp1);
529 let tt: u64 = self.t.rep();
531 let qq: u64 = self.q.rep();
532 let qdivtwo = qq / 2;
533
534 let my_closure = |elm: &T| -> T{
535 let mut tmp:u64 = elm.rep();
536 tmp *= tt;
537 tmp += qdivtwo;
538 tmp /= qq;
539 tmp %= tt;
540 T::from(tmp)
541 };
542
543 return phase.coeffs.iter()
544 .map(my_closure)
545 .collect();
546 }
547}
548
549#[cfg(test)]
550mod fv_scalar_tests {
551 use super::*;
552 #[test]
553 fn test_sk_encrypt_toy_param_scalar() {
554 let fv = FV::new(16, &Scalar::new_modulus(65537));
555
556 let sk = fv.generate_key();
557
558 let mut v = vec![0; fv.n];
559 for i in 0..fv.n {
560 v[i] = i as u8;
561 }
562 let ct = fv.encrypt_sk(&v, &sk);
563
564 let pt_actual: Vec<u8> = fv.decrypt(&ct, &sk);
565
566 assert_eq!(v, pt_actual);
567 }
568
569 #[test]
570 fn test_sk_encrypt_scalar() {
571 let fv = FV::<Scalar>::default_2048();
572
573 let sk = fv.generate_key();
574
575 let mut v = vec![0; fv.n];
576 for i in 0..fv.n {
577 v[i] = i as u8;
578 }
579 let ct = fv.encrypt_sk(&v, &sk);
580
581 let pt_actual: Vec<u8> = fv.decrypt(&ct, &sk);
582
583 assert_eq!(v, pt_actual);
584 }
585
586 #[test]
587 fn test_encrypt_default_param_scalar() {
588 let fv = FV::<Scalar>::default_2048();
589
590 let (pk, sk) = fv.generate_keypair();
591
592 let mut v = vec![0; fv.n];
593 for i in 0..fv.n {
594 v[i] = i as u8;
595 }
596 let ct = fv.encrypt(&v, &pk);
597
598 let pt_actual: Vec<u8> = fv.decrypt(&ct, &sk);
599
600 assert_eq!(v, pt_actual);
601 }
602
603 #[test]
604 fn test_rerandomize_scalar() {
605 let fv = FV::<Scalar>::default_2048();
606
607 let (pk, sk) = fv.generate_keypair();
608
609 let mut v = vec![0; fv.n];
610 for i in 0..fv.n {
611 v[i] = i as u8;
612 }
613 let mut ct = fv.encrypt(&v, &pk);
614
615 fv.rerandomize(&mut ct, &pk);
616
617 let pt_actual: Vec<u8> = fv.decrypt(&ct, &sk);
618
619 assert_eq!(v, pt_actual);
620 }
621
622 #[test]
623 fn test_add_scalar() {
624 let fv = FV::<Scalar>::default_2048();
625 let (pk, sk) = fv.generate_keypair();
626
627 let mut v = vec![0; fv.n];
628 for i in 0..fv.n {
629 v[i] = i as u8;
630 }
631
632 let mut w: Vec<u8> = vec![];
633 for i in 0..fv.n {
634 w.push((fv.n - i) as u8);
635 }
636
637 let mut vplusw = vec![];
638 for _ in 0..fv.n {
639 vplusw.push(fv.n as u8);
640 }
641 let mut ctv = fv.encrypt_sk(&v, &sk);
643 let ctw = fv.encrypt(&w, &pk);
644
645 fv.add_inplace(&mut ctv, &ctw);
647 let pt_after_add: DefaultFVPlaintext = fv.decrypt(&ctv, &sk);
648 assert_eq!(pt_after_add, vplusw);
649 }
650
651 #[test]
652 fn test_add_plain_scalar() {
653 let fv = FV::<Scalar>::default_2048();
654 let (pk, sk) = fv.generate_keypair();
655
656 let mut v = vec![0; fv.n];
657 for i in 0..fv.n {
658 v[i] = i as u8;
659 }
660
661 let mut w: Vec<u8> = vec![];
662 for i in 0..fv.n {
663 w.push((fv.n - i) as u8);
664 }
665
666 let mut vplusw = vec![];
667 for _ in 0..fv.n {
668 vplusw.push(fv.n as u8);
669 }
670 let mut ct = fv.encrypt(&v, &pk);
672
673 fv.add_plain_inplace(&mut ct, &w);
675
676 let pt_after_add: DefaultFVPlaintext = fv.decrypt(&ct, &sk);
677
678 assert_eq!(pt_after_add, vplusw);
679 }
680
681 #[test]
682 fn test_flexible_plaintext_encrypt() {
683 let t = 199;
684 let fv = crate::default_with_plaintext_mod(t);
685 let (pk, sk) = fv.generate_keypair();
686 let plain_modulus = fv.t.clone();
687 let pt = vec![Scalar::from_u32(t-1, &plain_modulus); fv.n];
688 let ct = fv.encrypt(&pt, &pk);
689 let pt_actual: Vec<Scalar> = fv.decrypt(&ct, &sk);
690 assert_eq!(pt_actual, pt);
691 }
692
693 #[test]
694 fn test_flexible_plaintext_addition() {
695 let t = 199;
696 let fv = crate::default_with_plaintext_mod(t);
697 let (pk, sk) = fv.generate_keypair();
698 let plain_modulus = fv.t.clone();
699 let v = vec![Scalar::from_u32(t-1, &plain_modulus); fv.n];
700 let w = vec![Scalar::from_u32(t-1, &plain_modulus); fv.n];
701 let v_plus_w = vec![Scalar::from_u32(t-2, &plain_modulus); fv.n];
702 let mut ctv = fv.encrypt(&v, &pk);
703 let ctw = fv.encrypt(&w, &pk);
704 fv.add_inplace(&mut ctv, &ctw);
705 let pt_actual: Vec<Scalar>= fv.decrypt(&ctv, &sk);
706 assert_eq!(pt_actual, v_plus_w);
707 }
708
709 #[test]
710 fn test_flexible_plaintext_add_plaintext() {
711 let t = 199;
712 let fv = crate::default_with_plaintext_mod(t);
713 let (pk, sk) = fv.generate_keypair();
714 let plain_modulus = fv.t.clone();
715 let v = vec![Scalar::from_u32(t-1, &plain_modulus); fv.n];
716 let w = vec![Scalar::from_u32(1, &plain_modulus); fv.n];
717 let v_plus_w = vec![Scalar::from_u32(0, &plain_modulus); fv.n];
718 let mut ct = fv.encrypt(&v, &pk);
719 fv.add_plain_inplace(&mut ct, &w);
720 let pt_actual: Vec<Scalar> = fv.decrypt(&ct, &sk);
721 assert_eq!(pt_actual, v_plus_w);
722 }
723}
724
725#[cfg(feature = "bigint")]
727#[cfg(test)]
728mod fv_bigint_tests {
729 use super::*;
730 #[test]
731 fn test_sk_encrypt() {
732 let fv = FV::new(16, &BigInt::from(12289));
733
734 let sk = fv.generate_key();
735
736 let mut v = vec![0; fv.n];
737 for i in 0..fv.n {
738 v[i] = i as u8;
739 }
740 let ct = fv.encrypt_sk(&v, &sk);
741
742 let pt_actual: Vec<u8> = fv.decrypt(&ct, &sk);
743
744 assert_eq!(v, pt_actual);
745 }
746
747 #[test]
748 fn test_encrypt_toy_param() {
749 let fv = FV::new(4, &BigInt::from(65537));
750
751 let (pk, sk) = fv.generate_keypair();
752
753 let mut v = vec![0; fv.n];
754 for i in 0..fv.n {
755 v[i] = i as u8;
756 }
757 for _ in 0..10 {
758 let ct = fv.encrypt(&v, &pk);
759 let pt_actual: Vec<u8> = fv.decrypt(&ct, &sk);
760 assert_eq!(v, pt_actual);
761 }
762 }
763
764 #[test]
765 fn test_encrypt_nonntt_toy_param() {
766 let fv = FV::new(4, &BigInt::from(1000000));
767
768 let (pk, sk) = fv.generate_keypair();
769
770 let mut v = vec![0; fv.n];
771 for i in 0..fv.n {
772 v[i] = i as u8;
773 }
774 for _ in 0..10 {
775 let ct = fv.encrypt(&v, &pk);
776 let pt_actual: Vec<u8> = fv.decrypt(&ct, &sk);
777 assert_eq!(v, pt_actual);
778 }
779 }
780
781 #[test]
782 fn test_encrypt_large_param() {
783 let fv = FV::<BigInt>::default_2048();
784
785 let (pk, sk) = fv.generate_keypair();
786
787 let mut v = vec![0; fv.n];
788 for i in 0..fv.n {
789 v[i] = i as u8;
790 }
791 let ct = fv.encrypt(&v, &pk);
792
793 let pt_actual: Vec<u8> = fv.decrypt(&ct, &sk);
794
795 assert_eq!(v, pt_actual);
796 }
797
798 #[test]
799 fn test_rerandomize() {
800 let fv = FV::<BigInt>::default_2048();
801
802 let (pk, sk) = fv.generate_keypair();
803
804 let mut v = vec![0; fv.n];
805 for i in 0..fv.n {
806 v[i] = i as u8;
807 }
808 let mut ct = fv.encrypt(&v, &pk);
809
810 fv.rerandomize(&mut ct, &pk);
811
812 let pt_actual: Vec<u8> = fv.decrypt(&ct, &sk);
813
814 assert_eq!(v, pt_actual);
815 }
816 #[test]
817 fn test_add() {
818 let fv = FV::new(16, &BigInt::from(12289));
819
820 let sk = fv.generate_key();
821
822 let mut v = vec![0; fv.n];
823 for i in 0..fv.n {
824 v[i] = i as u8;
825 }
826
827 let mut w: Vec<u8> = vec![];
828 for i in 0..fv.n {
829 w.push((fv.n - i) as u8);
830 }
831
832 let mut vplusw = vec![];
833 for _ in 0..fv.n {
834 vplusw.push(fv.n as u8);
835 }
836 let mut ctv = fv.encrypt_sk(&v, &sk);
838 let ctw = fv.encrypt_sk(&w, &sk);
839
840 fv.add_inplace(&mut ctv, &ctw);
842
843 let pt_after_add = fv.decrypt(&ctv, &sk);
844
845 assert_eq!(pt_after_add, vplusw);
846 }
847
848 #[test]
849 fn test_add_plain() {
850 let fv = FV::new(16, &BigInt::from(12289));
851 let sk = fv.generate_key();
852
853 let mut v = vec![0; fv.n];
854 for i in 0..fv.n {
855 v[i] = i as u8;
856 }
857
858 let mut w: Vec<u8> = vec![];
859 for i in 0..fv.n {
860 w.push((fv.n - i) as u8);
861 }
862
863 let mut vplusw = vec![];
864 for _ in 0..fv.n {
865 vplusw.push(fv.n as u8);
866 }
867 let mut ct = fv.encrypt_sk(&v, &sk);
869
870 fv.add_plain_inplace(&mut ct, &w);
872
873 let pt_after_add = fv.decrypt(&ct, &sk);
874
875 assert_eq!(pt_after_add, vplusw);
876 }
877}