Skip to content

Commit 4ccbfb9

Browse files
committed
ec/suite_b: Move scalar multiplication functions from C to Rust.
1 parent d25ff0f commit 4ccbfb9

File tree

7 files changed

+106
-82
lines changed

7 files changed

+106
-82
lines changed

crypto/fipsmodule/ec/gfp_p256.c

Lines changed: 0 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -13,42 +13,3 @@
1313
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
1414

1515
#include "./p256_shared.h"
16-
17-
#include "../../limbs/limbs.h"
18-
19-
#if !defined(OPENSSL_USE_NISTZ256)
20-
21-
typedef Limb ScalarMont[P256_LIMBS];
22-
typedef Limb Scalar[P256_LIMBS];
23-
24-
#include "../bn/internal.h"
25-
26-
static const BN_ULONG N[P256_LIMBS] = {
27-
#if defined(OPENSSL_64_BIT)
28-
0xf3b9cac2fc632551, 0xbce6faada7179e84, 0xffffffffffffffff, 0xffffffff00000000
29-
#else
30-
0xfc632551, 0xf3b9cac2, 0xa7179e84, 0xbce6faad, 0xffffffff, 0xffffffff, 0,
31-
0xffffffff
32-
#endif
33-
};
34-
35-
static const BN_ULONG N_N0[] = {
36-
BN_MONT_CTX_N0(0xccd1c8aa, 0xee00bc4f)
37-
};
38-
39-
void p256_scalar_mul_mont(ScalarMont r, const ScalarMont a,
40-
const ScalarMont b) {
41-
/* XXX: Inefficient. TODO: optimize with dedicated multiplication routine. */
42-
bn_mul_mont_small(r, a, b, N, N_N0, P256_LIMBS);
43-
}
44-
45-
/* XXX: Inefficient. TODO: optimize with dedicated squaring routine. */
46-
void p256_scalar_sqr_rep_mont(ScalarMont r, const ScalarMont a, Limb rep) {
47-
dev_assert_secret(rep >= 1);
48-
p256_scalar_mul_mont(r, a, a);
49-
for (Limb i = 1; i < rep; ++i) {
50-
p256_scalar_mul_mont(r, r, r);
51-
}
52-
}
53-
54-
#endif

crypto/fipsmodule/ec/gfp_p384.c

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -39,16 +39,6 @@ static const BN_ULONG Q[P384_LIMBS] = {
3939
#endif
4040
};
4141

42-
static const BN_ULONG N[P384_LIMBS] = {
43-
#if defined(OPENSSL_64_BIT)
44-
0xecec196accc52973, 0x581a0db248b0a77a, 0xc7634d81f4372ddf, 0xffffffffffffffff,
45-
0xffffffffffffffff, 0xffffffffffffffff
46-
#else
47-
0xccc52973, 0xecec196a, 0x48b0a77a, 0x581a0db2, 0xf4372ddf, 0xc7634d81,
48-
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff
49-
#endif
50-
};
51-
5242
static const BN_ULONG ONE[P384_LIMBS] = {
5343
#if defined(OPENSSL_64_BIT)
5444
0xffffffff00000001, 0xffffffff, 1, 0, 0
@@ -71,10 +61,6 @@ static const BN_ULONG Q_N0[] = {
7161
BN_MONT_CTX_N0(1, 1)
7262
};
7363

74-
static const BN_ULONG N_N0[] = {
75-
BN_MONT_CTX_N0(0x6ed46089, 0xe88fdc45)
76-
};
77-
7864
/* XXX: MSVC for x86 warns when it fails to inline these functions it should
7965
* probably inline. */
8066
#if defined(_MSC_VER) && !defined(__clang__) && defined(OPENSSL_X86)
@@ -212,13 +198,6 @@ void p384_elem_neg(Elem r, const Elem a) {
212198
}
213199

214200

215-
void p384_scalar_mul_mont(ScalarMont r, const ScalarMont a,
216-
const ScalarMont b) {
217-
/* XXX: Inefficient. TODO: Add dedicated multiplication routine. */
218-
bn_mul_mont_small(r, a, b, N, N_N0, P384_LIMBS);
219-
}
220-
221-
222201
/* TODO(perf): Optimize this. */
223202

224203
static void p384_point_select_w5(P384_POINT *out,

src/arithmetic/inout.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,3 +237,36 @@ where
237237
ra.with_potentially_dangling_non_null_pointers_ra(expected_len, |r, a| f(r, a, b.as_ptr()))
238238
}
239239
}
240+
241+
pub struct AliasingSlices3FromRawParts<T> {
242+
r: *mut T,
243+
a: *const T,
244+
b: *const T,
245+
len: NonZeroUsize,
246+
}
247+
248+
impl<T> AliasingSlices3FromRawParts<T> {
249+
#[inline(always)]
250+
pub unsafe fn new_rab_unchecked(
251+
r: *mut T,
252+
a: *const T,
253+
b: *const T,
254+
len: NonZeroUsize,
255+
) -> Self {
256+
Self { r, a, b, len }
257+
}
258+
}
259+
260+
impl<T> AliasingSlices3<T> for AliasingSlices3FromRawParts<T> {
261+
#[inline(always)]
262+
fn with_potentially_dangling_non_null_pointers_rab<R>(
263+
self,
264+
expected_len: usize,
265+
f: impl FnOnce(*mut T, *const T, *const T) -> R,
266+
) -> Result<R, LenMismatchError> {
267+
if expected_len != self.len.get() {
268+
return Err(LenMismatchError::new(self.len.get()));
269+
}
270+
Ok(f(self.r, self.a, self.b))
271+
}
272+
}

src/arithmetic/montgomery.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ impl ProductEncoding for (RRR, RInverse) {
123123
use crate::{bssl, c, limb::Limb};
124124

125125
#[inline(always)]
126-
pub(super) fn limbs_mul_mont(
126+
pub(crate) fn limbs_mul_mont(
127127
in_out: impl AliasingSlices3<Limb>,
128128
n: &[Limb],
129129
n0: &N0,

src/ec/suite_b/ops.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -908,9 +908,7 @@ mod tests {
908908

909909
#[test]
910910
fn p256_scalar_square_test() {
911-
prefixed_extern! {
912-
fn p256_scalar_sqr_rep_mont(r: *mut Limb, a: *const Limb, rep: LeakyWord);
913-
}
911+
use super::p256::p256_scalar_sqr_rep_mont;
914912
scalar_square_test(
915913
&p256::SCALAR_OPS,
916914
p256_scalar_sqr_rep_mont,

src/ec/suite_b/ops/p256.rs

Lines changed: 48 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,54 @@ pub static SCALAR_OPS: ScalarOps = ScalarOps {
121121
scalar_mul_mont: p256_scalar_mul_mont,
122122
};
123123

124+
cfg_if! {
125+
if #[cfg(any(all(target_arch = "aarch64", target_endian = "little"),
126+
target_arch = "x86_64"))] {
127+
prefixed_extern! {
128+
fn p256_scalar_mul_mont(
129+
r: *mut Limb, // [COMMON_OPS.num_limbs]
130+
a: *const Limb, // [COMMON_OPS.num_limbs]
131+
b: *const Limb); // [COMMON_OPS.num_limbs]
132+
pub(super) fn p256_scalar_sqr_rep_mont(
133+
r: *mut Limb, // [COMMON_OPS.num_limbs]
134+
a: *const Limb, // [COMMON_OPS.num_limbs]
135+
rep: LeakyWord);
136+
}
137+
} else {
138+
use crate::arithmetic::{inout::AliasingSlices3FromRawParts, LimbSliceError};
139+
140+
static N_N0: N0 = N0::precalculated(0xccd1c8aa_ee00bc4f);
141+
142+
unsafe extern "C" fn p256_scalar_mul_mont(
143+
r: *mut Limb, // [COMMON_OPS.num_limbs]
144+
a: *const Limb, // [COMMON_OPS.num_limbs]
145+
b: *const Limb, // [COMMON_OPS.num_limbs]
146+
) {
147+
// XXX: Inefficient. TODO: optimize with dedicated multiplication routine
148+
// TODO: Caller should pass in an `impl AliasingSlices3`.
149+
let in_out = unsafe { AliasingSlices3FromRawParts::new_rab_unchecked(r, a, b, NUM_LIMBS) };
150+
let n = &COMMON_OPS.n.limbs[..NUM_LIMBS.get()];
151+
let cpu = cpu::features(); // TODO: caller should supply this
152+
limbs_mul_mont(in_out, n, &N_N0, cpu).unwrap_or_else(|e| match e {
153+
LimbSliceError::LenMismatch(_)
154+
| LimbSliceError::TooShort(_)
155+
| LimbSliceError::TooLong(_) => unreachable!(),
156+
})
157+
}
158+
159+
pub(super) unsafe extern "C" fn p256_scalar_sqr_rep_mont(
160+
r: *mut Limb, // [COMMON_OPS.num_limbs]
161+
a: *const Limb, // [COMMON_OPS.num_limbs]
162+
rep: LeakyWord) {
163+
debug_assert!(rep >= 1);
164+
unsafe { p256_scalar_mul_mont(r, a, a); }
165+
for _ in 1..rep {
166+
unsafe { p256_scalar_mul_mont(r, r, r); }
167+
}
168+
}
169+
}
170+
}
171+
124172
pub static PUBLIC_SCALAR_OPS: PublicScalarOps = PublicScalarOps {
125173
scalar_ops: &SCALAR_OPS,
126174
public_key_ops: &PUBLIC_KEY_OPS,
@@ -309,17 +357,6 @@ prefixed_extern! {
309357
p_x: *const Limb, // [COMMON_OPS.num_limbs]
310358
p_y: *const Limb, // [COMMON_OPS.num_limbs]
311359
);
312-
313-
fn p256_scalar_mul_mont(
314-
r: *mut Limb, // [COMMON_OPS.num_limbs]
315-
a: *const Limb, // [COMMON_OPS.num_limbs]
316-
b: *const Limb, // [COMMON_OPS.num_limbs]
317-
);
318-
fn p256_scalar_sqr_rep_mont(
319-
r: *mut Limb, // [COMMON_OPS.num_limbs]
320-
a: *const Limb, // [COMMON_OPS.num_limbs]
321-
rep: LeakyWord,
322-
);
323360
}
324361

325362
#[cfg(test)]

src/ec/suite_b/ops/p384.rs

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,10 @@ use super::{
1616
elem::{binary_op, binary_op_assign},
1717
elem_sqr_mul, elem_sqr_mul_acc, PublicModulus, *,
1818
};
19-
use crate::polyfill::unwrap_const;
19+
use crate::{
20+
arithmetic::{inout::AliasingSlices3FromRawParts, LimbSliceError},
21+
polyfill::unwrap_const,
22+
};
2023
use core::num::NonZeroUsize;
2124

2225
pub(super) const NUM_LIMBS: NonZeroUsize = unwrap_const(NonZeroUsize::new(384 / LIMB_BITS));
@@ -122,6 +125,25 @@ pub static SCALAR_OPS: ScalarOps = ScalarOps {
122125
scalar_mul_mont: p384_scalar_mul_mont,
123126
};
124127

128+
static N_N0: N0 = N0::precalculated(0x6ed46089_e88fdc45);
129+
130+
unsafe extern "C" fn p384_scalar_mul_mont(
131+
r: *mut Limb, // [COMMON_OPS.num_limbs]
132+
a: *const Limb, // [COMMON_OPS.num_limbs]
133+
b: *const Limb, // [COMMON_OPS.num_limbs]
134+
) {
135+
// XXX: Inefficient. TODO: optimize with dedicated multiplication routine
136+
// TODO: Caller should pass in an `impl AliasingSlices3`.
137+
let in_out = unsafe { AliasingSlices3FromRawParts::new_rab_unchecked(r, a, b, NUM_LIMBS) };
138+
let n = &COMMON_OPS.n.limbs[..NUM_LIMBS.get()];
139+
let cpu = cpu::features(); // TODO: caller should supply this
140+
limbs_mul_mont(in_out, n, &N_N0, cpu).unwrap_or_else(|e| match e {
141+
LimbSliceError::LenMismatch(_)
142+
| LimbSliceError::TooShort(_)
143+
| LimbSliceError::TooLong(_) => unreachable!(),
144+
})
145+
}
146+
125147
pub static PUBLIC_SCALAR_OPS: PublicScalarOps = PublicScalarOps {
126148
scalar_ops: &SCALAR_OPS,
127149
public_key_ops: &PUBLIC_KEY_OPS,
@@ -297,10 +319,4 @@ prefixed_extern! {
297319
p_x: *const Limb, // [COMMON_OPS.num_limbs]
298320
p_y: *const Limb, // [COMMON_OPS.num_limbs]
299321
);
300-
301-
fn p384_scalar_mul_mont(
302-
r: *mut Limb, // [COMMON_OPS.num_limbs]
303-
a: *const Limb, // [COMMON_OPS.num_limbs]
304-
b: *const Limb, // [COMMON_OPS.num_limbs]
305-
);
306322
}

0 commit comments

Comments
 (0)