Skip to content

Commit d682bf7

Browse files
committed
Replace limbs initializer with const from_hex
The current macro initializer is not uniform across architectures, and doesn't work when the number of 64bit limbs is not exactly half that of 32bit limbs, (i.e. 521 bit). This change replaces all limbs! initializers with a new const function with hex string initializers, which is more portable and more ergonomic.
1 parent 244a1de commit d682bf7

File tree

7 files changed

+68
-162
lines changed

7 files changed

+68
-162
lines changed

src/arithmetic.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@
1212
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
1313
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1414

15-
#[macro_use]
16-
pub mod constant;
15+
mod constant;
1716

1817
#[cfg(feature = "alloc")]
1918
pub mod bigint;
@@ -26,3 +25,5 @@ mod nonnegative;
2625

2726
#[allow(dead_code)]
2827
const BIGINT_MODULUS_MAX_LIMBS: usize = 8192 / crate::limb::LIMB_BITS;
28+
29+
pub use constant::limbs_from_hex;

src/arithmetic/constant.rs

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,26 @@
1-
#[cfg(target_pointer_width = "32")]
2-
macro_rules! limbs {
3-
( $($limb:expr),+ ) => {
4-
[ $($limb),+ ]
5-
};
1+
use crate::limb::Limb;
2+
3+
const fn parse_digit(d: u8) -> u8 {
4+
match d.to_ascii_lowercase() {
5+
b'0'..=b'9' => return d - b'0',
6+
b'a'..=b'f' => return d - b'a' + 10,
7+
_ => panic!(),
8+
}
69
}
710

8-
#[cfg(target_pointer_width = "64")]
9-
macro_rules! limbs {
10-
( $($limb_lo:expr, $limb_hi:expr),+) => {
11-
[ $((($limb_hi | 0u64) << 32) | $limb_lo),+ ]
12-
};
11+
// TODO: this would be nicer as a trait, but currently traits don't support const functions
12+
pub const fn limbs_from_hex<const LIMBS: usize>(hex: &str) -> [Limb; LIMBS] {
13+
let hex = hex.as_bytes();
14+
let mut limbs = [0; LIMBS];
15+
let limb_nibbles = core::mem::size_of::<Limb>() * 2;
16+
let mut i = 0;
17+
18+
while i < hex.len() {
19+
let char = hex[hex.len() - 1 - i];
20+
let val = parse_digit(char);
21+
limbs[i / limb_nibbles] |= (val as Limb) << ((i % limb_nibbles) * 4);
22+
i += 1;
23+
}
24+
25+
limbs
1326
}

src/ec/curve25519/scalar.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
1313
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1414

15-
use crate::{digest, error, limb};
15+
use crate::{arithmetic::limbs_from_hex, digest, error, limb};
1616

1717
#[repr(transparent)]
1818
pub struct Scalar([u8; SCALAR_LEN]);
@@ -24,7 +24,7 @@ impl Scalar {
2424
// that not in the range [0, n).
2525
pub fn from_bytes_checked(bytes: [u8; SCALAR_LEN]) -> Result<Self, error::Unspecified> {
2626
const ORDER: [limb::Limb; SCALAR_LEN / limb::LIMB_BYTES] =
27-
limbs![0x5cf5d3ed, 0x5812631a, 0xa2f79cd6, 0x14def9de, 0, 0, 0, 0x10000000];
27+
limbs_from_hex("1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed");
2828

2929
// `bytes` is in little-endian order.
3030
let mut reversed = bytes;

src/ec/suite_b/ops.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
1313
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1414

15-
use crate::{arithmetic::montgomery::*, c, error, limb::*};
15+
use crate::{arithmetic::limbs_from_hex, arithmetic::montgomery::*, c, error, limb::*};
1616
use core::marker::PhantomData;
1717

1818
pub use self::elem::*;
@@ -50,11 +50,7 @@ impl Point {
5050
}
5151
}
5252

53-
static ONE: Elem<Unencoded> = Elem {
54-
limbs: limbs![1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
55-
m: PhantomData,
56-
encoding: PhantomData,
57-
};
53+
const ONE: Elem<Unencoded> = Elem::from_hex("1");
5854

5955
/// Operations and values needed by all curve operations.
6056
pub struct CommonOps {

src/ec/suite_b/ops/elem.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@
1313
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1414

1515
use crate::{
16-
arithmetic::montgomery::{Encoding, ProductEncoding},
16+
arithmetic::{
17+
limbs_from_hex,
18+
montgomery::{Encoding, ProductEncoding},
19+
},
1720
limb::{Limb, LIMB_BITS},
1821
};
1922
use core::marker::PhantomData;
@@ -44,6 +47,14 @@ impl<M, E: Encoding> Elem<M, E> {
4447
encoding: PhantomData,
4548
}
4649
}
50+
51+
pub const fn from_hex(hex: &str) -> Self {
52+
Elem {
53+
limbs: limbs_from_hex(hex),
54+
m: PhantomData,
55+
encoding: PhantomData,
56+
}
57+
}
4758
}
4859

4960
#[inline]

src/ec/suite_b/ops/p256.rs

Lines changed: 11 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -16,53 +16,17 @@ use super::{
1616
elem::{binary_op, binary_op_assign},
1717
elem_sqr_mul, elem_sqr_mul_acc, Modulus, *,
1818
};
19-
use core::marker::PhantomData;
20-
21-
macro_rules! p256_limbs {
22-
[ $($limb:expr),+ ] => {
23-
limbs![$($limb),+, 0, 0, 0, 0]
24-
};
25-
}
2619

2720
pub static COMMON_OPS: CommonOps = CommonOps {
2821
num_limbs: 256 / LIMB_BITS,
2922

3023
q: Modulus {
31-
p: p256_limbs![
32-
0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000001,
33-
0xffffffff
34-
],
35-
rr: p256_limbs![
36-
0x00000003, 0x00000000, 0xffffffff, 0xfffffffb, 0xfffffffe, 0xffffffff, 0xfffffffd,
37-
0x00000004
38-
],
39-
},
40-
41-
n: Elem {
42-
limbs: p256_limbs![
43-
0xfc632551, 0xf3b9cac2, 0xa7179e84, 0xbce6faad, 0xffffffff, 0xffffffff, 0x00000000,
44-
0xffffffff
45-
],
46-
m: PhantomData,
47-
encoding: PhantomData, // Unencoded
48-
},
49-
50-
a: Elem {
51-
limbs: p256_limbs![
52-
0xfffffffc, 0xffffffff, 0xffffffff, 0x00000003, 0x00000000, 0x00000000, 0x00000004,
53-
0xfffffffc
54-
],
55-
m: PhantomData,
56-
encoding: PhantomData, // R
57-
},
58-
b: Elem {
59-
limbs: p256_limbs![
60-
0x29c4bddf, 0xd89cdf62, 0x78843090, 0xacf005cd, 0xf7212ed6, 0xe5a220ab, 0x04874834,
61-
0xdc30061d
62-
],
63-
m: PhantomData,
64-
encoding: PhantomData, // R
24+
p: limbs_from_hex("ffffffff00000001000000000000000000000000ffffffffffffffffffffffff"),
25+
rr: limbs_from_hex("4fffffffdfffffffffffffffefffffffbffffffff0000000000000003"),
6526
},
27+
n: Elem::from_hex("ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551"),
28+
a: Elem::from_hex("fffffffc00000004000000000000000000000003fffffffffffffffffffffffc"),
29+
b: Elem::from_hex("dc30061d04874834e5a220abf7212ed6acf005cd78843090d89cdf6229c4bddf"),
6630

6731
elem_mul_mont: p256_mul_mont,
6832
elem_sqr_mont: p256_sqr_mont,
@@ -151,25 +115,15 @@ pub static PUBLIC_SCALAR_OPS: PublicScalarOps = PublicScalarOps {
151115
scalar_ops: &SCALAR_OPS,
152116
public_key_ops: &PUBLIC_KEY_OPS,
153117
private_key_ops: &PRIVATE_KEY_OPS,
154-
155-
q_minus_n: Elem {
156-
limbs: p256_limbs![0x039cdaae, 0x0c46353d, 0x58e8617b, 0x43190553, 0, 0, 0, 0],
157-
m: PhantomData,
158-
encoding: PhantomData, // Unencoded
159-
},
118+
q_minus_n: Elem::from_hex("4319055358e8617b0c46353d039cdaae"),
160119
};
161120

162121
pub static PRIVATE_SCALAR_OPS: PrivateScalarOps = PrivateScalarOps {
163122
scalar_ops: &SCALAR_OPS,
164123

165-
oneRR_mod_n: Scalar {
166-
limbs: p256_limbs![
167-
0xbe79eea2, 0x83244c95, 0x49bd6fa6, 0x4699799c, 0x2b6bec59, 0x2845b239, 0xf3d95620,
168-
0x66e12d94
169-
],
170-
m: PhantomData,
171-
encoding: PhantomData, // R
172-
},
124+
oneRR_mod_n: Scalar::from_hex(
125+
"66e12d94f3d956202845b2392b6bec594699799c49bd6fa683244c95be79eea2",
126+
),
173127
};
174128

175129
fn p256_scalar_inv_to_mont(a: &Scalar<Unencoded>) -> Scalar<R> {
@@ -210,14 +164,8 @@ fn p256_scalar_inv_to_mont(a: &Scalar<Unencoded>) -> Scalar<R> {
210164
}
211165

212166
fn to_mont(a: &Scalar) -> Scalar<R> {
213-
static N_RR: Scalar<Unencoded> = Scalar {
214-
limbs: p256_limbs![
215-
0xbe79eea2, 0x83244c95, 0x49bd6fa6, 0x4699799c, 0x2b6bec59, 0x2845b239, 0xf3d95620,
216-
0x66e12d94
217-
],
218-
m: PhantomData,
219-
encoding: PhantomData,
220-
};
167+
const N_RR: Scalar<Unencoded> =
168+
Scalar::from_hex("66e12d94f3d956202845b2392b6bec594699799c49bd6fa683244c95be79eea2");
221169
binary_op(p256_scalar_mul_mont, a, &N_RR)
222170
}
223171

src/ec/suite_b/ops/p384.rs

Lines changed: 15 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -12,54 +12,24 @@
1212
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
1313
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1414

15+
use crate::arithmetic::limbs_from_hex;
16+
1517
use super::{
1618
elem::{binary_op, binary_op_assign},
1719
elem_sqr_mul, elem_sqr_mul_acc, Modulus, *,
1820
};
19-
use core::marker::PhantomData;
20-
21-
macro_rules! p384_limbs {
22-
[$($limb:expr),+] => {
23-
limbs![$($limb),+]
24-
};
25-
}
2621

2722
pub static COMMON_OPS: CommonOps = CommonOps {
2823
num_limbs: 384 / LIMB_BITS,
2924

3025
q: Modulus {
31-
p: p384_limbs![
32-
0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0xfffffffe, 0xffffffff, 0xffffffff,
33-
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff
34-
],
35-
rr: p384_limbs![1, 0xfffffffe, 0, 2, 0, 0xfffffffe, 0, 2, 1, 0, 0, 0],
36-
},
37-
n: Elem {
38-
limbs: p384_limbs![
39-
0xccc52973, 0xecec196a, 0x48b0a77a, 0x581a0db2, 0xf4372ddf, 0xc7634d81, 0xffffffff,
40-
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff
41-
],
42-
m: PhantomData,
43-
encoding: PhantomData, // Unencoded
44-
},
45-
46-
a: Elem {
47-
limbs: p384_limbs![
48-
0xfffffffc, 0x00000003, 0x00000000, 0xfffffffc, 0xfffffffb, 0xffffffff, 0xffffffff,
49-
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff
50-
],
51-
m: PhantomData,
52-
encoding: PhantomData, // Unreduced
26+
p: limbs_from_hex("fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffff"),
27+
rr: limbs_from_hex("10000000200000000fffffffe000000000000000200000000fffffffe00000001"),
5328
},
54-
b: Elem {
55-
limbs: p384_limbs![
56-
0x9d412dcc, 0x08118871, 0x7a4c32ec, 0xf729add8, 0x1920022e, 0x77f2209b, 0x94938ae2,
57-
0xe3374bee, 0x1f022094, 0xb62b21f4, 0x604fbff9, 0xcd08114b
58-
],
59-
m: PhantomData,
60-
encoding: PhantomData, // Unreduced
61-
},
62-
29+
n: Elem::from_hex("ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52973"),
30+
a: Elem::from_hex("fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffffffc0000000000000003fffffffc"),
31+
b: Elem::from_hex("cd08114b604fbff9b62b21f41f022094e3374bee94938ae277f2209b1920022ef729add87a4c32ec081188719d412dcc")
32+
,
6333
elem_mul_mont: p384_elem_mul_mont,
6434
elem_sqr_mont: p384_elem_sqr_mont,
6535

@@ -131,23 +101,9 @@ fn p384_elem_inv_squared(a: &Elem<R>) -> Elem<R> {
131101

132102
fn p384_point_mul_base_impl(a: &Scalar) -> Point {
133103
// XXX: Not efficient. TODO: Precompute multiples of the generator.
134-
static GENERATOR: (Elem<R>, Elem<R>) = (
135-
Elem {
136-
limbs: p384_limbs![
137-
0x49c0b528, 0x3dd07566, 0xa0d6ce38, 0x20e378e2, 0x541b4d6e, 0x879c3afc, 0x59a30eff,
138-
0x64548684, 0x614ede2b, 0x812ff723, 0x299e1513, 0x4d3aadc2
139-
],
140-
m: PhantomData,
141-
encoding: PhantomData,
142-
},
143-
Elem {
144-
limbs: p384_limbs![
145-
0x4b03a4fe, 0x23043dad, 0x7bb4a9ac, 0xa1bfa8bf, 0x2e83b050, 0x8bade756, 0x68f4ffd9,
146-
0xc6c35219, 0x3969a840, 0xdd800226, 0x5a15c5e9, 0x2b78abc2
147-
],
148-
m: PhantomData,
149-
encoding: PhantomData,
150-
},
104+
const GENERATOR: (Elem<R>, Elem<R>) = (
105+
Elem::from_hex("4d3aadc2299e1513812ff723614ede2b6454868459a30eff879c3afc541b4d6e20e378e2a0d6ce383dd0756649c0b528"),
106+
Elem::from_hex("2b78abc25a15c5e9dd8002263969a840c6c3521968f4ffd98bade7562e83b050a1bfa8bf7bb4a9ac23043dad4b03a4fe"),
151107
);
152108

153109
PRIVATE_KEY_OPS.point_mul(a, &GENERATOR)
@@ -168,25 +124,13 @@ pub static PUBLIC_SCALAR_OPS: PublicScalarOps = PublicScalarOps {
168124
public_key_ops: &PUBLIC_KEY_OPS,
169125
private_key_ops: &PRIVATE_KEY_OPS,
170126

171-
q_minus_n: Elem {
172-
limbs: p384_limbs![
173-
0x333ad68c, 0x1313e696, 0xb74f5885, 0xa7e5f24c, 0x0bc8d21f, 0x389cb27e, 0, 0, 0, 0, 0,
174-
0
175-
],
176-
177-
m: PhantomData,
178-
encoding: PhantomData, // Unencoded
179-
},
127+
q_minus_n: Elem::from_hex("389cb27e0bc8d21fa7e5f24cb74f58851313e696333ad68c"),
180128
};
181129

182130
pub static PRIVATE_SCALAR_OPS: PrivateScalarOps = PrivateScalarOps {
183131
scalar_ops: &SCALAR_OPS,
184132

185-
oneRR_mod_n: Scalar {
186-
limbs: N_RR_LIMBS,
187-
m: PhantomData,
188-
encoding: PhantomData, // R
189-
},
133+
oneRR_mod_n: Scalar::from_hex(N_RR_HEX),
190134
};
191135

192136
fn p384_scalar_inv_to_mont(a: &Scalar<Unencoded>) -> Scalar<R> {
@@ -232,11 +176,7 @@ fn p384_scalar_inv_to_mont(a: &Scalar<Unencoded>) -> Scalar<R> {
232176
}
233177

234178
fn to_mont(a: &Scalar<Unencoded>) -> Scalar<R> {
235-
static N_RR: Scalar<Unencoded> = Scalar {
236-
limbs: N_RR_LIMBS,
237-
m: PhantomData,
238-
encoding: PhantomData,
239-
};
179+
const N_RR: Scalar<Unencoded> = Scalar::from_hex(N_RR_HEX);
240180
binary_op(p384_scalar_mul_mont, a, &N_RR)
241181
}
242182

@@ -332,10 +272,7 @@ unsafe extern "C" fn p384_elem_sqr_mont(
332272
p384_elem_mul_mont(r, a, a);
333273
}
334274

335-
const N_RR_LIMBS: [Limb; MAX_LIMBS] = p384_limbs![
336-
0x19b409a9, 0x2d319b24, 0xdf1aa419, 0xff3d81e5, 0xfcb82947, 0xbc3e483a, 0x4aab1cc5, 0xd40d4917,
337-
0x28266895, 0x3fb05b7a, 0x2b39bf21, 0x0c84ee01
338-
];
275+
const N_RR_HEX: &str = "0c84ee012b39bf213fb05b7a28266895d40d49174aab1cc5bc3e483afcb82947ff3d81e5df1aa4192d319b2419b409a9";
339276

340277
prefixed_extern! {
341278
fn p384_elem_mul_mont(

0 commit comments

Comments
 (0)