From 08cc9a310665837ba82dfb4bf537012081fc7af9 Mon Sep 17 00:00:00 2001 From: Janmajaya Mall Date: Thu, 13 Jun 2024 14:40:09 +0530 Subject: [PATCH] stopping at the moment because non-interactive requires some improvements --- src/backend/mod.rs | 1 + src/multi_party.rs | 152 ++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 151 insertions(+), 2 deletions(-) diff --git a/src/backend/mod.rs b/src/backend/mod.rs index 03e3fdf..332f28f 100644 --- a/src/backend/mod.rs +++ b/src/backend/mod.rs @@ -95,6 +95,7 @@ pub trait GetModulus { pub trait VectorOps { type Element; + /// Sets out as `out[i] = a[i] * b` fn elwise_scalar_mul(&self, out: &mut [Self::Element], a: &[Self::Element], b: &Self::Element); fn elwise_mul(&self, out: &mut [Self::Element], a: &[Self::Element], b: &[Self::Element]); diff --git a/src/multi_party.rs b/src/multi_party.rs index 86fbf60..e57e9c7 100644 --- a/src/multi_party.rs +++ b/src/multi_party.rs @@ -1,9 +1,11 @@ +use itertools::izip; + use crate::{ backend::{GetModulus, VectorOps}, - ntt::Ntt, + ntt::{self, Ntt}, random::{NewWithSeed, RandomFillGaussianInModulus, RandomFillUniformInModulus}, utils::TryConvertFrom1, - Matrix, Row, RowEntity, RowMut, + Decomposer, Matrix, MatrixEntity, MatrixMut, Row, RowEntity, RowMut, }; pub(crate) fn public_key_share< @@ -45,3 +47,149 @@ pub(crate) fn public_key_share< RandomFillGaussianInModulus::random_fill(rng, &q, share_out.as_mut()); modop.elwise_add_mut(share_out.as_mut(), s.as_ref()); // s*e + e } + +fn non_interactive_rgsw_ct< + M: MatrixMut + MatrixEntity, + S, + PRng: RandomFillUniformInModulus<[M::MatElement], ModOp::M>, + Rng: RandomFillGaussianInModulus<[M::MatElement], ModOp::M>, + NttOp: Ntt, + ModOp: VectorOps + GetModulus, +>( + s: &[S], + ephemeral_u: &[S], + m: &[M::MatElement], + gadget_vec: &[M::MatElement], + p_rng: &mut PRng, + rng: &mut Rng, + nttop: &NttOp, + modop: &ModOp, +) -> (M, M) +where + ::R: RowMut + TryConvertFrom1<[S], ModOp::M> + RowEntity, + M::MatElement: Copy, +{ + assert_eq!(s.len(), ephemeral_u.len()); + assert_eq!(s.len(), m.len()); + let q = modop.modulus(); + let d = gadget_vec.len(); + let ring_size = s.len(); + + let mut s_poly_eval = M::R::try_convert_from(s, q); + let mut u_poly_eval = M::R::try_convert_from(ephemeral_u, q); + nttop.forward(s_poly_eval.as_mut()); + nttop.forward(u_poly_eval.as_mut()); + + // encryptions of a_i*u + e + \beta m + let mut enc_beta_m = M::zeros(d, ring_size); + // zero encrypition: a_i*s + e' + let mut zero_encryptions = M::zeros(d, ring_size); + + let mut scratch_space = M::R::zeros(ring_size); + + izip!( + enc_beta_m.iter_rows_mut(), + zero_encryptions.iter_rows_mut(), + gadget_vec.iter() + ) + .for_each(|(e_beta_m, e_zero, beta)| { + // sample a_i + RandomFillUniformInModulus::random_fill(p_rng, q, e_beta_m.as_mut()); + e_zero.as_mut().copy_from_slice(e_beta_m.as_ref()); + + // a_i * u + \beta m + e // + // a_i * u + nttop.forward(e_beta_m.as_mut()); + modop.elwise_mul_mut(e_beta_m.as_mut(), u_poly_eval.as_ref()); + nttop.backward(e_beta_m.as_mut()); + // sample error e + RandomFillGaussianInModulus::random_fill(rng, q, scratch_space.as_mut()); + // a_i * u + e + modop.elwise_add_mut(e_beta_m.as_mut(), scratch_space.as_ref()); + // beta * m + modop.elwise_scalar_mul(scratch_space.as_mut(), m.as_ref(), beta); + // a_i * u + e + \beta m + modop.elwise_add_mut(e_beta_m.as_mut(), scratch_space.as_ref()); + + // a_i * s + e // + // a_i * s + nttop.forward(e_zero.as_mut()); + modop.elwise_mul_mut(e_zero.as_mut(), s_poly_eval.as_ref()); + nttop.backward(e_zero.as_mut()); + // sample error e + RandomFillGaussianInModulus::random_fill(rng, q, scratch_space.as_mut()); + // a_i * s + e + modop.elwise_add_mut(e_zero.as_mut(), scratch_space.as_ref()); + }); + + (enc_beta_m, zero_encryptions) +} + +fn non_interactive_ksk_gen< + M: MatrixMut + MatrixEntity, + S, + PRng: RandomFillUniformInModulus<[M::MatElement], ModOp::M>, + Rng: RandomFillGaussianInModulus<[M::MatElement], ModOp::M>, + NttOp: Ntt, + ModOp: VectorOps + GetModulus, +>( + s: &[S], + ephemeral_u: &[S], + gadget_vec: &[M::MatElement], + p_rng: &mut PRng, + rng: &mut Rng, + nttop: &NttOp, + modop: &ModOp, +) where + ::R: RowMut + TryConvertFrom1<[S], ModOp::M> + RowEntity, + M::MatElement: Copy, +{ + assert_eq!(s.len(), ephemeral_u.len()); + + let q = modop.modulus(); + let d = gadget_vec.len(); + let ring_size = s.len(); + + let mut s_poly_eval = M::R::try_convert_from(s, q); + nttop.forward(s_poly_eval.as_mut()); + let u_poly = M::R::try_convert_from(ephemeral_u, q); + + // a_i * s + \beta u + e + // a_i * s + e + let mut ksk = M::zeros(d, ring_size); + let mut zero_encs = M::zeros(d, ring_size); + + let mut scratch_space = M::R::zeros(ring_size); + + izip!( + ksk.iter_rows_mut(), + zero_encs.iter_rows_mut(), + gadget_vec.iter() + ) + .for_each(|(e_ksk, e_zero, beta)| { + // sample a_i + RandomFillUniformInModulus::random_fill(p_rng, q, e_ksk.as_mut()); + e_zero.as_mut().copy_from_slice(e_ksk.as_ref()); + + // a_i * s + e + beta u + nttop.forward(e_ksk.as_mut()); + modop.elwise_mul_mut(e_ksk.as_mut(), s_poly_eval.as_ref()); + nttop.backward(e_ksk.as_mut()); + // sample error e + RandomFillGaussianInModulus::random_fill(rng, q, scratch_space.as_mut()); + // a_i * s + e + modop.elwise_add_mut(e_ksk.as_mut(), scratch_space.as_ref()); + // \beta * u + modop.elwise_scalar_mul(scratch_space.as_mut(), u_poly.as_ref(), beta); + // a_i * s + e + \beta * u + modop.elwise_add_mut(e_ksk.as_mut(), scratch_space.as_ref()); + + // a_i * s + e + nttop.forward(e_zero.as_mut()); + modop.elwise_mul_mut(e_zero.as_mut(), s_poly_eval.as_ref()); + nttop.backward(e_zero.as_mut()); + // sample error e + RandomFillGaussianInModulus::random_fill(rng, q, scratch_space.as_mut()); + + }); +}