From db9c10e667a162f2f3c96d86ed703baf64fe8178 Mon Sep 17 00:00:00 2001 From: David Palm Date: Fri, 14 Mar 2025 13:07:26 +0100 Subject: [PATCH 1/2] impl ConstantTimeSelect for BoxedMontyForm and BoxedMontyparams --- src/modular/boxed_monty_form.rs | 46 ++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/src/modular/boxed_monty_form.rs b/src/modular/boxed_monty_form.rs index 1ee2abc06..36b056f75 100644 --- a/src/modular/boxed_monty_form.rs +++ b/src/modular/boxed_monty_form.rs @@ -11,7 +11,7 @@ mod sub; use super::{ConstMontyParams, Retrieve, div_by_2}; use mul::BoxedMontyMultiplier; -use crate::{BoxedUint, Limb, Monty, Odd, Word}; +use crate::{BoxedUint, ConstantTimeSelect, Limb, Monty, Odd, Word}; use alloc::sync::Arc; use subtle::Choice; @@ -339,6 +339,29 @@ impl Zeroize for BoxedMontyForm { } } +impl ConstantTimeSelect for BoxedMontyForm { + fn ct_select(a: &Self, b: &Self, choice: Choice) -> Self { + Self { + montgomery_form: BoxedUint::ct_select(&a.montgomery_form, &b.montgomery_form, choice), + params: BoxedMontyParams::ct_select(&a.params, &b.params, choice).into(), + } + } +} + +impl ConstantTimeSelect for BoxedMontyParams { + fn ct_select(a: &Self, b: &Self, choice: Choice) -> Self { + let modulus = BoxedUint::ct_select(&a.modulus().as_ref(), &b.modulus().as_ref(), choice); + Self { + modulus: Odd::new(modulus).expect("both moduli are odd by construction"), + one: BoxedUint::ct_select(&a.one, &b.one, choice), + r2: BoxedUint::ct_select(&a.r2, &b.r2, choice), + r3: BoxedUint::ct_select(&a.r3, &b.r3, choice), + mod_neg_inv: Limb::ct_select(&a.mod_neg_inv, &b.mod_neg_inv, choice), + mod_leading_zeros: u32::ct_select(&a.mod_leading_zeros, &b.mod_leading_zeros, choice), + } + } +} + /// Convert the given integer into the Montgomery domain. #[inline] fn convert_to_montgomery(integer: &mut BoxedUint, params: &BoxedMontyParams) { @@ -348,6 +371,10 @@ fn convert_to_montgomery(integer: &mut BoxedUint, params: &BoxedMontyParams) { #[cfg(test)] mod tests { + use subtle::Choice; + + use crate::ConstantTimeSelect; + use super::{BoxedMontyForm, BoxedMontyParams, BoxedUint, Limb, Odd}; #[test] @@ -369,4 +396,21 @@ mod tests { assert_eq!(zero.div_by_2(), zero); assert_eq!(one.div_by_2().mul(&two), one); } + + #[test] + fn constant_time_select() { + let modulus = Odd::new(BoxedUint::from(9u8)).unwrap(); + let params1 = BoxedMontyParams::new(modulus); + let modulus = Odd::new(BoxedUint::from(19u8)).unwrap(); + let params2 = BoxedMontyParams::new(modulus); + + assert_eq!( + params1, + BoxedMontyParams::ct_select(¶ms1, ¶ms2, Choice::from(0)) + ); + assert_eq!( + params2, + BoxedMontyParams::ct_select(¶ms1, ¶ms2, Choice::from(1)) + ); + } } From fb2c01e05043ac457df3dd621ca855ed2924b4fd Mon Sep 17 00:00:00 2001 From: David Palm Date: Fri, 14 Mar 2025 15:52:56 +0100 Subject: [PATCH 2/2] Clippy fix. --- src/modular/boxed_monty_form.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modular/boxed_monty_form.rs b/src/modular/boxed_monty_form.rs index 36b056f75..d9c6b2142 100644 --- a/src/modular/boxed_monty_form.rs +++ b/src/modular/boxed_monty_form.rs @@ -350,7 +350,7 @@ impl ConstantTimeSelect for BoxedMontyForm { impl ConstantTimeSelect for BoxedMontyParams { fn ct_select(a: &Self, b: &Self, choice: Choice) -> Self { - let modulus = BoxedUint::ct_select(&a.modulus().as_ref(), &b.modulus().as_ref(), choice); + let modulus = BoxedUint::ct_select(a.modulus().as_ref(), b.modulus().as_ref(), choice); Self { modulus: Odd::new(modulus).expect("both moduli are odd by construction"), one: BoxedUint::ct_select(&a.one, &b.one, choice),