Skip to content

Commit c8feae3

Browse files
committed
Removed the unsafe_op_in_unsafe_fn workspace lint override
1 parent 23c3608 commit c8feae3

6 files changed

Lines changed: 111 additions & 60 deletions

File tree

Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ rust-version = "1.88"
1414
missing_docs = "warn"
1515
unused_imports = "warn"
1616
unused_must_use = "deny"
17-
unsafe_op_in_unsafe_fn = "allow"
1817

1918
[workspace.dependencies]
2019
clap = { version = "^4.5.54", features = ["derive"] }

crates/fhe-math/src/ntt/native.rs

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -140,31 +140,31 @@ impl NttOperator {
140140
/// This function is not constant time and its timing may reveal information
141141
/// about the value being reduced.
142142
pub(crate) unsafe fn forward_vt_lazy(&self, a_ptr: *mut u64) {
143-
let a = std::slice::from_raw_parts_mut(a_ptr, self.size);
143+
let a = unsafe { std::slice::from_raw_parts_mut(a_ptr, self.size) };
144144

145145
let mut l = self.size >> 1;
146146
let mut m = 1;
147147
let mut k = 1;
148148
while l > 0 {
149149
for i in 0..m {
150-
let omega = *self.omegas.get_unchecked(k);
151-
let omega_shoup = *self.omegas_shoup.get_unchecked(k);
150+
let omega = unsafe { *self.omegas.get_unchecked(k) };
151+
let omega_shoup = unsafe { *self.omegas_shoup.get_unchecked(k) };
152152
k += 1;
153153

154154
let s = 2 * i * l;
155155
match l {
156156
1 => {
157157
// SAFETY: s and s + l are distinct (l > 0) and in-bounds
158158
// (s + l < 2 * m * l = size)
159-
let [x, y] = a.get_disjoint_unchecked_mut([s, s + l]);
160-
self.butterfly_vt(x, y, omega, omega_shoup);
159+
let [x, y] = unsafe { a.get_disjoint_unchecked_mut([s, s + l]) };
160+
unsafe { self.butterfly_vt(x, y, omega, omega_shoup) };
161161
}
162162
_ => {
163163
for j in s..(s + l) {
164164
// SAFETY: j and j + l are distinct (l > 0) and in-bounds
165165
// (j + l < s + 2 * l <= 2 * m * l = size)
166-
let [x, y] = a.get_disjoint_unchecked_mut([j, j + l]);
167-
self.butterfly_vt(x, y, omega, omega_shoup);
166+
let [x, y] = unsafe { a.get_disjoint_unchecked_mut([j, j + l]) };
167+
unsafe { self.butterfly_vt(x, y, omega, omega_shoup) };
168168
}
169169
}
170170
}
@@ -181,10 +181,10 @@ impl NttOperator {
181181
/// This function is not constant time and its timing may reveal information
182182
/// about the value being reduced.
183183
pub unsafe fn forward_vt(&self, a_ptr: *mut u64) {
184-
self.forward_vt_lazy(a_ptr);
185-
let a = std::slice::from_raw_parts_mut(a_ptr, self.size);
184+
unsafe { self.forward_vt_lazy(a_ptr) };
185+
let a = unsafe { std::slice::from_raw_parts_mut(a_ptr, self.size) };
186186
for ai in a.iter_mut() {
187-
*ai = self.reduce3_vt(*ai);
187+
*ai = unsafe { self.reduce3_vt(*ai) };
188188
}
189189
}
190190

@@ -195,30 +195,30 @@ impl NttOperator {
195195
/// This function is not constant time and its timing may reveal information
196196
/// about the value being reduced.
197197
pub unsafe fn backward_vt(&self, a_ptr: *mut u64) {
198-
let a = std::slice::from_raw_parts_mut(a_ptr, self.size);
198+
let a = unsafe { std::slice::from_raw_parts_mut(a_ptr, self.size) };
199199

200200
let mut k = 0;
201201
let mut m = self.size >> 1;
202202
let mut l = 1;
203203
while m > 0 {
204204
for i in 0..m {
205205
let s = 2 * i * l;
206-
let zeta_inv = *self.zetas_inv.get_unchecked(k);
207-
let zeta_inv_shoup = *self.zetas_inv_shoup.get_unchecked(k);
206+
let zeta_inv = unsafe { *self.zetas_inv.get_unchecked(k) };
207+
let zeta_inv_shoup = unsafe { *self.zetas_inv_shoup.get_unchecked(k) };
208208
k += 1;
209209
match l {
210210
1 => {
211211
// SAFETY: s and s + l are distinct (l > 0) and in-bounds
212212
// (s + l < 2 * m * l = size)
213-
let [x, y] = a.get_disjoint_unchecked_mut([s, s + l]);
214-
self.inv_butterfly_vt(x, y, zeta_inv, zeta_inv_shoup);
213+
let [x, y] = unsafe { a.get_disjoint_unchecked_mut([s, s + l]) };
214+
unsafe { self.inv_butterfly_vt(x, y, zeta_inv, zeta_inv_shoup) };
215215
}
216216
_ => {
217217
for j in s..(s + l) {
218218
// SAFETY: j and j + l are distinct (l > 0) and in-bounds
219219
// (j + l < s + 2 * l <= 2 * m * l = size)
220-
let [x, y] = a.get_disjoint_unchecked_mut([j, j + l]);
221-
self.inv_butterfly_vt(x, y, zeta_inv, zeta_inv_shoup);
220+
let [x, y] = unsafe { a.get_disjoint_unchecked_mut([j, j + l]) };
221+
unsafe { self.inv_butterfly_vt(x, y, zeta_inv, zeta_inv_shoup) };
222222
}
223223
}
224224
}
@@ -248,8 +248,8 @@ impl NttOperator {
248248
const unsafe fn reduce3_vt(&self, a: u64) -> u64 {
249249
debug_assert!(a < 4 * self.p.p);
250250

251-
let y = Modulus::reduce1_vt(a, self.p_twice);
252-
Modulus::reduce1_vt(y, self.p.p)
251+
let y = unsafe { Modulus::reduce1_vt(a, self.p_twice) };
252+
unsafe { Modulus::reduce1_vt(y, self.p.p) }
253253
}
254254

255255
/// NTT Butterfly.
@@ -275,7 +275,7 @@ impl NttOperator {
275275
debug_assert!(w < self.p.p);
276276
debug_assert_eq!(self.p.shoup(w), w_shoup);
277277

278-
*x = Modulus::reduce1_vt(*x, self.p_twice);
278+
*x = unsafe { Modulus::reduce1_vt(*x, self.p_twice) };
279279
let t = self.p.lazy_mul_shoup(*y, w, w_shoup);
280280
*y = *x + self.p_twice - t;
281281
*x += t;
@@ -307,7 +307,7 @@ impl NttOperator {
307307
debug_assert_eq!(self.p.shoup(z), z_shoup);
308308

309309
let t = *x;
310-
*x = Modulus::reduce1_vt(*y + t, self.p_twice);
310+
*x = unsafe { Modulus::reduce1_vt(*y + t, self.p_twice) };
311311
*y = self.p.lazy_mul_shoup(self.p_twice + t - *y, z, z_shoup);
312312

313313
debug_assert!(*x < self.p_twice);

crates/fhe-math/src/rq/mod.rs

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,7 @@ impl Poly {
406406
.unwrap()
407407
.clone_from_slice(power_basis_coefficients);
408408
qi.lazy_reduce_vec(p.as_slice_mut().unwrap());
409-
op.forward_vt_lazy(p.as_mut_ptr());
409+
unsafe { op.forward_vt_lazy(p.as_mut_ptr()) };
410410
},
411411
);
412412
Self {
@@ -750,6 +750,33 @@ mod tests {
750750
Ok(())
751751
}
752752

753+
#[test]
754+
fn create_constant_ntt_with_lazy_coefficients_and_variable_time() -> Result<(), Box<dyn Error>>
755+
{
756+
let modulus = MODULI[0];
757+
let ctx = Arc::new(Context::new(&[modulus], 16)?);
758+
let coeffs: Vec<u64> = (0..ctx.degree)
759+
.map(|i| (i as u64).wrapping_mul(modulus).wrapping_add(i as u64))
760+
.collect();
761+
762+
let poly = unsafe {
763+
Poly::create_constant_ntt_polynomial_with_lazy_coefficients_and_variable_time(
764+
&coeffs, &ctx,
765+
)
766+
};
767+
768+
assert_eq!(poly.representation(), &Representation::Ntt);
769+
assert!(poly.allow_variable_time_computations);
770+
assert!(poly.has_lazy_coefficients);
771+
772+
let mut expected = coeffs.clone();
773+
ctx.q[0].lazy_reduce_vec(&mut expected);
774+
unsafe { ctx.ops[0].forward_vt_lazy(expected.as_mut_ptr()) };
775+
assert_eq!(poly.coefficients().as_slice().unwrap(), expected);
776+
777+
Ok(())
778+
}
779+
753780
#[test]
754781
fn change_representation() -> Result<(), Box<dyn Error>> {
755782
let mut rng = rand::rng();

crates/fhe-math/src/zq/mod.rs

Lines changed: 37 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ impl Modulus {
114114
#[must_use]
115115
pub const unsafe fn add_vt(&self, a: u64, b: u64) -> u64 {
116116
debug_assert!(a < self.p && b < self.p);
117-
Self::reduce1_vt(a + b, self.p)
117+
unsafe { Self::reduce1_vt(a + b, self.p) }
118118
}
119119

120120
/// Performs the modular subtraction of a and b in constant time.
@@ -141,7 +141,7 @@ impl Modulus {
141141
/// about the values being multiplied.
142142
const unsafe fn mul_vt(&self, a: u64, b: u64) -> u64 {
143143
debug_assert!(a < self.p && b < self.p);
144-
Self::reduce1_vt(self.lazy_reduce_u128((a as u128) * (b as u128)), self.p)
144+
unsafe { Self::reduce1_vt(self.lazy_reduce_u128((a as u128) * (b as u128)), self.p) }
145145
}
146146

147147
/// Optimized modular multiplication of a and b in constant time.
@@ -165,7 +165,7 @@ impl Modulus {
165165
debug_assert!(self.supports_opt);
166166
debug_assert!(a < self.p && b < self.p);
167167

168-
self.reduce_opt_u128_vt((a as u128) * (b as u128))
168+
unsafe { self.reduce_opt_u128_vt((a as u128) * (b as u128)) }
169169
}
170170

171171
/// Modular negation in constant time.
@@ -185,7 +185,7 @@ impl Modulus {
185185
/// about the value being negated.
186186
const unsafe fn neg_vt(&self, a: u64) -> u64 {
187187
debug_assert!(a < self.p);
188-
Self::reduce1_vt(self.p - a, self.p)
188+
unsafe { Self::reduce1_vt(self.p - a, self.p) }
189189
}
190190

191191
/// Compute the Shoup representation of a.
@@ -213,7 +213,7 @@ impl Modulus {
213213
/// This function is not constant time and its timing may reveal information
214214
/// about the values being multiplied.
215215
const unsafe fn mul_shoup_vt(&self, a: u64, b: u64, b_shoup: u64) -> u64 {
216-
Self::reduce1_vt(self.lazy_mul_shoup(a, b, b_shoup), self.p)
216+
unsafe { Self::reduce1_vt(self.lazy_mul_shoup(a, b, b_shoup), self.p) }
217217
}
218218

219219
/// Lazy Shoup multiplication of a and b in constant time.
@@ -364,7 +364,7 @@ impl Modulus {
364364
let b_shoup = self.shoup(b);
365365
self.arch.dispatch(|| {
366366
a.iter_mut()
367-
.for_each(|ai| *ai = self.mul_shoup_vt(*ai, b, b_shoup))
367+
.for_each(|ai| *ai = unsafe { self.mul_shoup_vt(*ai, b, b_shoup) })
368368
})
369369
}
370370

@@ -380,11 +380,13 @@ impl Modulus {
380380

381381
if self.supports_opt {
382382
self.arch.dispatch(|| {
383-
izip!(a.iter_mut(), b.iter()).for_each(|(ai, bi)| *ai = self.mul_opt_vt(*ai, *bi))
383+
izip!(a.iter_mut(), b.iter())
384+
.for_each(|(ai, bi)| *ai = unsafe { self.mul_opt_vt(*ai, *bi) })
384385
})
385386
} else {
386387
self.arch.dispatch(|| {
387-
izip!(a.iter_mut(), b.iter()).for_each(|(ai, bi)| *ai = self.mul_vt(*ai, *bi))
388+
izip!(a.iter_mut(), b.iter())
389+
.for_each(|(ai, bi)| *ai = unsafe { self.mul_vt(*ai, *bi) })
388390
})
389391
}
390392
}
@@ -426,8 +428,9 @@ impl Modulus {
426428
debug_assert_eq!(&b_shoup, &self.shoup_vec(b));
427429

428430
self.arch.dispatch(|| {
429-
izip!(a.iter_mut(), b.iter(), b_shoup.iter())
430-
.for_each(|(ai, bi, bi_shoup)| *ai = self.mul_shoup_vt(*ai, *bi, *bi_shoup))
431+
izip!(a.iter_mut(), b.iter(), b_shoup.iter()).for_each(|(ai, bi, bi_shoup)| {
432+
*ai = unsafe { self.mul_shoup_vt(*ai, *bi, *bi_shoup) }
433+
})
431434
})
432435
}
433436

@@ -460,8 +463,11 @@ impl Modulus {
460463
/// about the values being centered.
461464
#[must_use]
462465
pub unsafe fn center_vec_vt(&self, a: &[u64]) -> Vec<i64> {
463-
self.arch
464-
.dispatch(|| a.iter().map(|ai| self.center_vt(*ai)).collect_vec())
466+
self.arch.dispatch(|| {
467+
a.iter()
468+
.map(|ai| unsafe { self.center_vt(*ai) })
469+
.collect_vec()
470+
})
465471
}
466472

467473
/// Reduce a vector in place in variable time.
@@ -470,8 +476,10 @@ impl Modulus {
470476
/// This function is not constant time and its timing may reveal information
471477
/// about the values being reduced.
472478
pub unsafe fn reduce_vec_vt(&self, a: &mut [u64]) {
473-
self.arch
474-
.dispatch(|| a.iter_mut().for_each(|ai| *ai = self.reduce_vt(*ai)))
479+
self.arch.dispatch(|| {
480+
a.iter_mut()
481+
.for_each(|ai| *ai = unsafe { self.reduce_vt(*ai) })
482+
})
475483
}
476484

477485
/// Modular reduction of a i64 in constant time.
@@ -485,7 +493,7 @@ impl Modulus {
485493
/// This function is not constant time and its timing may reveal information
486494
/// about the values being reduced.
487495
const unsafe fn reduce_i64_vt(&self, a: i64) -> u64 {
488-
self.reduce_u128_vt((((self.p as i128) << 64) + (a as i128)) as u128)
496+
unsafe { self.reduce_u128_vt((((self.p as i128) << 64) + (a as i128)) as u128) }
489497
}
490498

491499
/// Reduce a vector in place in constant time.
@@ -502,8 +510,11 @@ impl Modulus {
502510
/// about the values being reduced.
503511
#[must_use]
504512
pub unsafe fn reduce_vec_i64_vt(&self, a: &[i64]) -> Vec<u64> {
505-
self.arch
506-
.dispatch(|| a.iter().map(|ai| self.reduce_i64_vt(*ai)).collect())
513+
self.arch.dispatch(|| {
514+
a.iter()
515+
.map(|ai| unsafe { self.reduce_i64_vt(*ai) })
516+
.collect()
517+
})
507518
}
508519

509520
/// Reduce a vector in constant time.
@@ -521,7 +532,7 @@ impl Modulus {
521532
#[must_use]
522533
pub unsafe fn reduce_vec_new_vt(&self, a: &[u64]) -> Vec<u64> {
523534
self.arch
524-
.dispatch(|| a.iter().map(|bi| self.reduce_vt(*bi)).collect())
535+
.dispatch(|| a.iter().map(|bi| unsafe { self.reduce_vt(*bi) }).collect())
525536
}
526537

527538
/// Modular negation of a vector in place in constant time.
@@ -539,8 +550,10 @@ impl Modulus {
539550
/// This function is not constant time and its timing may reveal information
540551
/// about the values being negated.
541552
pub unsafe fn neg_vec_vt(&self, a: &mut [u64]) {
542-
self.arch
543-
.dispatch(|| a.iter_mut().for_each(|ai| *ai = self.neg_vt(*ai)))
553+
self.arch.dispatch(|| {
554+
a.iter_mut()
555+
.for_each(|ai| *ai = unsafe { self.neg_vt(*ai) })
556+
})
544557
}
545558

546559
/// Modular exponentiation in variable time.
@@ -596,7 +609,7 @@ impl Modulus {
596609
/// about the value being reduced.
597610
#[must_use]
598611
pub const unsafe fn reduce_u128_vt(&self, a: u128) -> u64 {
599-
Self::reduce1_vt(self.lazy_reduce_u128(a), self.p)
612+
unsafe { Self::reduce1_vt(self.lazy_reduce_u128(a), self.p) }
600613
}
601614

602615
/// Modular reduction of a u64 in constant time.
@@ -612,7 +625,7 @@ impl Modulus {
612625
/// about the value being reduced.
613626
#[must_use]
614627
pub const unsafe fn reduce_vt(&self, a: u64) -> u64 {
615-
Self::reduce1_vt(self.lazy_reduce(a), self.p)
628+
unsafe { Self::reduce1_vt(self.lazy_reduce(a), self.p) }
616629
}
617630

618631
/// Optimized modular reduction of a u128 in constant time.
@@ -629,7 +642,7 @@ impl Modulus {
629642
/// about the value being reduced.
630643
pub(crate) const unsafe fn reduce_opt_u128_vt(&self, a: u128) -> u64 {
631644
debug_assert!(self.supports_opt);
632-
Self::reduce1_vt(self.lazy_reduce_opt_u128(a), self.p)
645+
unsafe { Self::reduce1_vt(self.lazy_reduce_opt_u128(a), self.p) }
633646
}
634647

635648
/// Optimized modular reduction of a u64 in constant time.
@@ -645,7 +658,7 @@ impl Modulus {
645658
/// about the value being reduced.
646659
#[must_use]
647660
pub const unsafe fn reduce_opt_vt(&self, a: u64) -> u64 {
648-
Self::reduce1_vt(self.lazy_reduce_opt(a), self.p)
661+
unsafe { Self::reduce1_vt(self.lazy_reduce_opt(a), self.p) }
649662
}
650663

651664
/// Return x mod p in constant time.

crates/fhe/src/bfv/ops/dot_product.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,10 @@ unsafe fn fma(out: &mut [u128], x: &[u64], y: &[u64]) {
1717

1818
macro_rules! fma_at {
1919
($idx:expr) => {
20-
*out.get_unchecked_mut($idx) +=
21-
(*x.get_unchecked($idx) as u128) * (*y.get_unchecked($idx) as u128);
20+
unsafe {
21+
*out.get_unchecked_mut($idx) +=
22+
(*x.get_unchecked($idx) as u128) * (*y.get_unchecked($idx) as u128);
23+
}
2224
};
2325
}
2426

@@ -166,6 +168,10 @@ mod tests {
166168
#[test]
167169
fn test_dot_product_scalar() -> Result<(), Box<dyn Error>> {
168170
let mut rng = rng();
171+
let empty_ct: Vec<Ciphertext> = Vec::new();
172+
let empty_pt: Vec<Plaintext> = Vec::new();
173+
assert!(dot_product_scalar(empty_ct.iter(), empty_pt.iter()).is_err());
174+
169175
for params in [
170176
BfvParameters::default_arc(1, 16),
171177
BfvParameters::default_arc(2, 32),

0 commit comments

Comments
 (0)