Skip to content

Commit e560ad7

Browse files
authored
Add preimage_extend (#5)
1 parent bfb6653 commit e560ad7

File tree

2 files changed

+74
-0
lines changed

2 files changed

+74
-0
lines changed

src/sampler/mod.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,4 +80,15 @@ pub trait PolyTrapdoorSampler {
8080
public_matrix: &Self::M,
8181
target: &Self::M,
8282
) -> Self::M;
83+
84+
// Given a trapdoor of B, an extension matrix C, a target matrix U, return a preimage D s.t.
85+
// [B,C]D = U.
86+
fn preimage_extend(
87+
&self,
88+
params: &<<Self::M as PolyMatrix>::P as Poly>::Params,
89+
trapdoor: &Self::Trapdoor,
90+
public_matrix: &Self::M,
91+
ext_matrix: &Self::M,
92+
target: &Self::M,
93+
) -> Self::M;
8394
}

src/sampler/trapdoor/sampler.rs

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,33 @@ impl PolyTrapdoorSampler for DCRTPolyTrapdoorSampler {
154154
log_mem("z_hat generated");
155155
z_hat_former.concat_rows(&[&z_hat_latter])
156156
}
157+
158+
// Algorithm 5 of https://eprint.iacr.org/2017/601.pdf
159+
fn preimage_extend(
160+
&self,
161+
params: &<<Self::M as PolyMatrix>::P as Poly>::Params,
162+
trapdoor: &Self::Trapdoor,
163+
public_matrix: &Self::M,
164+
ext_matrix: &Self::M,
165+
target: &Self::M,
166+
) -> Self::M {
167+
let d = public_matrix.row_size();
168+
let ext_ncol = ext_matrix.col_size();
169+
let target_ncol = target.col_size();
170+
let n = params.ring_dimension() as usize;
171+
let k = params.modulus_digits();
172+
let s = SPECTRAL_CONSTANT *
173+
(self.base as f64 + 1.0) *
174+
SIGMA *
175+
SIGMA *
176+
(((d * n * k) as f64).sqrt() + ((2 * n) as f64).sqrt() + 4.7);
177+
let dist = DistType::GaussDist { sigma: s };
178+
let uniform_sampler = DCRTPolyUniformSampler::new();
179+
let preimage_right = uniform_sampler.sample_uniform(params, ext_ncol, target_ncol, dist);
180+
let t = target - &(ext_matrix * &preimage_right);
181+
let preimage_left = self.preimage(params, trapdoor, public_matrix, &t);
182+
preimage_left.concat_rows(&[&preimage_right])
183+
}
157184
}
158185

159186
pub(crate) fn decompose_dcrt_gadget(
@@ -502,4 +529,40 @@ mod test {
502529

503530
assert_eq!(product, target, "Product of public matrix and preimage should equal target");
504531
}
532+
533+
#[test]
534+
fn test_preimage_generation_extend() {
535+
let params = DCRTPolyParams::default();
536+
let size = 3;
537+
let k = params.modulus_digits();
538+
let trapdoor_sampler = DCRTPolyTrapdoorSampler::new(&params, SIGMA);
539+
let (trapdoor, public_matrix) = trapdoor_sampler.trapdoor(&params, size);
540+
541+
let uniform_sampler = DCRTPolyUniformSampler::new();
542+
let target = uniform_sampler.sample_uniform(&params, size, 1, DistType::FinRingDist);
543+
let m = size * params.modulus_digits();
544+
let extend = uniform_sampler.sample_uniform(&params, size, m, DistType::FinRingDist);
545+
546+
let preimage =
547+
trapdoor_sampler.preimage_extend(&params, &trapdoor, &public_matrix, &extend, &target);
548+
549+
let expected_rows = size * (k + 2) + m;
550+
let expected_cols = 1;
551+
552+
assert_eq!(
553+
preimage.row_size(),
554+
expected_rows,
555+
"Preimage matrix should have the correct number of rows"
556+
);
557+
558+
assert_eq!(
559+
preimage.col_size(),
560+
expected_cols,
561+
"Preimage matrix should have the correct number of columns"
562+
);
563+
564+
// public_matrix * preimage should be equal to target
565+
let product = public_matrix.concat_columns(&[&extend]) * &preimage;
566+
assert_eq!(product, target, "Product of public matrix and preimage should equal target");
567+
}
505568
}

0 commit comments

Comments
 (0)