Skip to content

Commit

Permalink
Simplify ECC field element addition.
Browse files Browse the repository at this point in the history
Don't require a specialized implementation of field element addition for
each curve; instead share an implementation between RSA and ECC.

Refactor the code to avoid needing `elem_sum`.
  • Loading branch information
briansmith committed Feb 10, 2021
1 parent d00bdbe commit 22040ae
Show file tree
Hide file tree
Showing 7 changed files with 30 additions and 45 deletions.
4 changes: 0 additions & 4 deletions crypto/fipsmodule/ec/gfp_p384.c
Original file line number Diff line number Diff line change
Expand Up @@ -178,10 +178,6 @@ static inline void elem_sqr_mont(Elem r, const Elem a) {
elem_mul_mont(r, a, a);
}

void GFp_p384_elem_add(Elem r, const Elem a, const Elem b) {
elem_add(r, a, b);
}

void GFp_p384_elem_sub(Elem r, const Elem a, const Elem b) {
elem_sub(r, a, b);
}
Expand Down
20 changes: 1 addition & 19 deletions src/arithmetic/bigint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -550,25 +550,7 @@ pub fn elem_widen<Larger, Smaller: SmallerModulus<Larger>>(

// TODO: Document why this works for all Montgomery factors.
pub fn elem_add<M, E>(mut a: Elem<M, E>, b: Elem<M, E>, m: &Modulus<M>) -> Elem<M, E> {
extern "C" {
// `r` and `a` may alias.
fn LIMBS_add_mod(
r: *mut Limb,
a: *const Limb,
b: *const Limb,
m: *const Limb,
num_limbs: c::size_t,
);
}
unsafe {
LIMBS_add_mod(
a.limbs.as_mut_ptr(),
a.limbs.as_ptr(),
b.limbs.as_ptr(),
m.limbs.as_ptr(),
m.limbs.len(),
)
}
limb::limbs_add_assign_mod(&mut a.limbs, &b.limbs, &m.limbs);
a
}

Expand Down
9 changes: 6 additions & 3 deletions src/ec/suite_b/ecdsa/verification.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,13 +152,16 @@ impl EcdsaVerificationAlgorithm {
let x = cops.elem_unencoded(x);
ops.elem_equals(&r_jacobian, &x)
}
let r = self.ops.scalar_as_elem(&r);
let mut r = self.ops.scalar_as_elem(&r);
if sig_r_equals_x(self.ops, &r, &x, &z2) {
return Ok(());
}
if self.ops.elem_less_than(&r, &self.ops.q_minus_n) {
let r_plus_n = self.ops.elem_sum(&r, &public_key_ops.common.n);
if sig_r_equals_x(self.ops, &r_plus_n, &x, &z2) {
self.ops
.private_key_ops
.common
.elem_add(&mut r, &public_key_ops.common.n);
if sig_r_equals_x(self.ops, &r, &x, &z2) {
return Ok(());
}
}
Expand Down
13 changes: 6 additions & 7 deletions src/ec/suite_b/ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ pub struct CommonOps {
pub b: Elem<R>,

// In all cases, `r`, `a`, and `b` may all alias each other.
elem_add_impl: unsafe extern "C" fn(r: *mut Limb, a: *const Limb, b: *const Limb),
elem_mul_mont: unsafe extern "C" fn(r: *mut Limb, a: *const Limb, b: *const Limb),
elem_sqr_mont: unsafe extern "C" fn(r: *mut Limb, a: *const Limb),

Expand All @@ -76,7 +75,12 @@ pub struct CommonOps {
impl CommonOps {
#[inline]
pub fn elem_add<E: Encoding>(&self, a: &mut Elem<E>, b: &Elem<E>) {
binary_op_assign(self.elem_add_impl, a, b)
let num_limbs = self.num_limbs;
limbs_add_assign_mod(
&mut a.limbs[..num_limbs],
&b.limbs[..num_limbs],
&self.q.p[..num_limbs],
);
}

#[inline]
Expand Down Expand Up @@ -300,11 +304,6 @@ impl PublicScalarOps {
let num_limbs = self.public_key_ops.common.num_limbs;
limbs_less_than_limbs_vartime(&a.limbs[..num_limbs], &b.limbs[..num_limbs])
}

#[inline]
pub fn elem_sum(&self, a: &Elem<Unencoded>, b: &Elem<Unencoded>) -> Elem<Unencoded> {
binary_op(self.public_key_ops.common.elem_add_impl, a, b)
}
}

#[allow(non_snake_case)]
Expand Down
6 changes: 0 additions & 6 deletions src/ec/suite_b/ops/p256.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@ pub static COMMON_OPS: CommonOps = CommonOps {
encoding: PhantomData, // R
},

elem_add_impl: GFp_nistz256_add,
elem_mul_mont: GFp_nistz256_mul_mont,
elem_sqr_mont: GFp_nistz256_sqr_mont,

Expand Down Expand Up @@ -338,11 +337,6 @@ fn p256_scalar_inv_to_mont(a: &Scalar<Unencoded>) -> Scalar<R> {
}

extern "C" {
fn GFp_nistz256_add(
r: *mut Limb, // [COMMON_OPS.num_limbs]
a: *const Limb, // [COMMON_OPS.num_limbs]
b: *const Limb, // [COMMON_OPS.num_limbs]
);
fn GFp_nistz256_mul_mont(
r: *mut Limb, // [COMMON_OPS.num_limbs]
a: *const Limb, // [COMMON_OPS.num_limbs]
Expand Down
6 changes: 0 additions & 6 deletions src/ec/suite_b/ops/p384.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ pub static COMMON_OPS: CommonOps = CommonOps {
encoding: PhantomData, // Unreduced
},

elem_add_impl: GFp_p384_elem_add,
elem_mul_mont: GFp_p384_elem_mul_mont,
elem_sqr_mont: GFp_p384_elem_sqr_mont,

Expand Down Expand Up @@ -339,11 +338,6 @@ const N_RR_LIMBS: [Limb; MAX_LIMBS] = p384_limbs![
];

extern "C" {
fn GFp_p384_elem_add(
r: *mut Limb, // [COMMON_OPS.num_limbs]
a: *const Limb, // [COMMON_OPS.num_limbs]
b: *const Limb, // [COMMON_OPS.num_limbs]
);
fn GFp_p384_elem_mul_mont(
r: *mut Limb, // [COMMON_OPS.num_limbs]
a: *const Limb, // [COMMON_OPS.num_limbs]
Expand Down
17 changes: 17 additions & 0 deletions src/limb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,23 @@ pub fn fold_5_bit_windows<R, I: FnOnce(Window) -> R, F: Fn(R, Window) -> R>(
})
}

#[inline]
pub(crate) fn limbs_add_assign_mod(a: &mut [Limb], b: &[Limb], m: &[Limb]) {
debug_assert_eq!(a.len(), m.len());
debug_assert_eq!(b.len(), m.len());
extern "C" {
// `r` and `a` may alias.
fn LIMBS_add_mod(
r: *mut Limb,
a: *const Limb,
b: *const Limb,
m: *const Limb,
num_limbs: c::size_t,
);
}
unsafe { LIMBS_add_mod(a.as_mut_ptr(), a.as_ptr(), b.as_ptr(), m.as_ptr(), m.len()) }
}

extern "C" {
#[cfg(feature = "alloc")]
fn LIMB_shr(a: Limb, shift: c::size_t) -> Limb;
Expand Down

0 comments on commit 22040ae

Please sign in to comment.