diff --git a/src/field/goldilocks_field.rs b/src/field/goldilocks_field.rs index 7378ea15..a7d46363 100644 --- a/src/field/goldilocks_field.rs +++ b/src/field/goldilocks_field.rs @@ -13,6 +13,7 @@ use crate::field::extension_field::quartic::QuarticExtension; use crate::field::extension_field::Extendable; use crate::field::field_types::{Field, PrimeField, RichField}; use crate::field::inversion::try_inverse_u64; +use crate::util::assume; const EPSILON: u64 = (1 << 32) - 1; @@ -280,6 +281,8 @@ unsafe fn add_with_wraparound(x: u64, y: u64) -> u64 { inlateout(reg) y => adjustment, options(pure, nomem, nostack), ); + assume(x != 0 || (res_wrapped == y && adjustment == 0)); + assume(y != 0 || (res_wrapped == x && adjustment == 0)); res_wrapped.wrapping_add(adjustment) // Add EPSILON == subtract ORDER. } @@ -307,6 +310,7 @@ unsafe fn sub_with_wraparound(x: u64, y: u64) -> u64 { inlateout(reg) y => adjustment, options(pure, nomem, nostack), ); + assume(y != 0 || (res_wrapped == x && adjustment == 0)); res_wrapped.wrapping_sub(adjustment) // Subtract EPSILON == add ORDER. } diff --git a/src/util/mod.rs b/src/util/mod.rs index d8e05a18..94df5141 100644 --- a/src/util/mod.rs +++ b/src/util/mod.rs @@ -1,3 +1,5 @@ +use core::hint::unreachable_unchecked; + use crate::field::field_types::Field; use crate::polynomial::polynomial::PolynomialValues; @@ -195,6 +197,14 @@ pub(crate) fn reverse_bits(n: usize, num_bits: usize) -> usize { .0 } +#[inline(always)] +pub(crate) unsafe fn assume(p: bool) { + debug_assert!(p); + if !p { + unreachable_unchecked(); + } +} + #[cfg(test)] mod tests { use crate::util::{reverse_bits, reverse_index_bits, reverse_index_bits_in_place};