1 // Copyright 2016 Brian Smith.
2 //
3 // Permission to use, copy, modify, and/or distribute this software for any
4 // purpose with or without fee is hereby granted, provided that the above
5 // copyright notice and this permission notice appear in all copies.
6 //
7 // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
8 // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
10 // SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12 // OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13 // CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14 
15 use crate::{arithmetic::montgomery::*, c, error, limb::*};
16 use core::marker::PhantomData;
17 use untrusted;
18 
19 pub use self::elem::*;
20 
21 /// A field element, i.e. an element of ℤ/qℤ for the curve's field modulus
22 /// *q*.
23 pub type Elem<E> = elem::Elem<Q, E>;
24 
25 /// Represents the (prime) order *q* of the curve's prime field.
26 #[derive(Clone, Copy)]
27 pub enum Q {}
28 
29 /// A scalar. Its value is in [0, n). Zero-valued scalars are forbidden in most
30 /// contexts.
31 pub type Scalar<E = Unencoded> = elem::Elem<N, E>;
32 
33 /// Represents the prime order *n* of the curve's group.
34 #[derive(Clone, Copy)]
35 pub enum N {}
36 
37 pub struct Point {
38     // The coordinates are stored in a contiguous array, where the first
39     // `ops.num_limbs` elements are the X coordinate, the next
40     // `ops.num_limbs` elements are the Y coordinate, and the next
41     // `ops.num_limbs` elements are the Z coordinate. This layout is dictated
42     // by the requirements of the GFp_nistz256 code.
43     xyz: [Limb; 3 * MAX_LIMBS],
44 }
45 
46 impl Point {
new_at_infinity() -> Point47     pub fn new_at_infinity() -> Point {
48         Point {
49             xyz: [0; 3 * MAX_LIMBS],
50         }
51     }
52 }
53 
54 static ONE: Elem<Unencoded> = Elem {
55     limbs: limbs![1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
56     m: PhantomData,
57     encoding: PhantomData,
58 };
59 
60 /// Operations and values needed by all curve operations.
61 pub struct CommonOps {
62     pub num_limbs: usize,
63     q: Modulus,
64     pub n: Elem<Unencoded>,
65 
66     pub a: Elem<R>, // Must be -3 mod q
67     pub b: Elem<R>,
68 
69     // In all cases, `r`, `a`, and `b` may all alias each other.
70     elem_add_impl: unsafe extern "C" fn(r: *mut Limb, a: *const Limb, b: *const Limb),
71     elem_mul_mont: unsafe extern "C" fn(r: *mut Limb, a: *const Limb, b: *const Limb),
72     elem_sqr_mont: unsafe extern "C" fn(r: *mut Limb, a: *const Limb),
73 
74     point_add_jacobian_impl: unsafe extern "C" fn(r: *mut Limb, a: *const Limb, b: *const Limb),
75 }
76 
77 impl CommonOps {
78     #[inline]
elem_add<E: Encoding>(&self, a: &mut Elem<E>, b: &Elem<E>)79     pub fn elem_add<E: Encoding>(&self, a: &mut Elem<E>, b: &Elem<E>) {
80         binary_op_assign(self.elem_add_impl, a, b)
81     }
82 
83     #[inline]
elems_are_equal(&self, a: &Elem<R>, b: &Elem<R>) -> LimbMask84     pub fn elems_are_equal(&self, a: &Elem<R>, b: &Elem<R>) -> LimbMask {
85         limbs_equal_limbs_consttime(&a.limbs[..self.num_limbs], &b.limbs[..self.num_limbs])
86     }
87 
88     #[inline]
elem_unencoded(&self, a: &Elem<R>) -> Elem<Unencoded>89     pub fn elem_unencoded(&self, a: &Elem<R>) -> Elem<Unencoded> {
90         self.elem_product(a, &ONE)
91     }
92 
93     #[inline]
elem_mul(&self, a: &mut Elem<R>, b: &Elem<R>)94     pub fn elem_mul(&self, a: &mut Elem<R>, b: &Elem<R>) {
95         binary_op_assign(self.elem_mul_mont, a, b)
96     }
97 
98     #[inline]
elem_product<EA: Encoding, EB: Encoding>( &self, a: &Elem<EA>, b: &Elem<EB>, ) -> Elem<<(EA, EB) as ProductEncoding>::Output> where (EA, EB): ProductEncoding,99     pub fn elem_product<EA: Encoding, EB: Encoding>(
100         &self,
101         a: &Elem<EA>,
102         b: &Elem<EB>,
103     ) -> Elem<<(EA, EB) as ProductEncoding>::Output>
104     where
105         (EA, EB): ProductEncoding,
106     {
107         mul_mont(self.elem_mul_mont, a, b)
108     }
109 
110     #[inline]
elem_square(&self, a: &mut Elem<R>)111     pub fn elem_square(&self, a: &mut Elem<R>) {
112         unary_op_assign(self.elem_sqr_mont, a);
113     }
114 
115     #[inline]
elem_squared(&self, a: &Elem<R>) -> Elem<R>116     pub fn elem_squared(&self, a: &Elem<R>) -> Elem<R> {
117         unary_op(self.elem_sqr_mont, a)
118     }
119 
120     #[inline]
is_zero<M, E: Encoding>(&self, a: &elem::Elem<M, E>) -> bool121     pub fn is_zero<M, E: Encoding>(&self, a: &elem::Elem<M, E>) -> bool {
122         limbs_are_zero_constant_time(&a.limbs[..self.num_limbs]) == LimbMask::True
123     }
124 
elem_verify_is_not_zero(&self, a: &Elem<R>) -> Result<(), error::Unspecified>125     pub fn elem_verify_is_not_zero(&self, a: &Elem<R>) -> Result<(), error::Unspecified> {
126         if self.is_zero(a) {
127             Err(error::Unspecified)
128         } else {
129             Ok(())
130         }
131     }
132 
point_sum(&self, a: &Point, b: &Point) -> Point133     pub fn point_sum(&self, a: &Point, b: &Point) -> Point {
134         let mut r = Point::new_at_infinity();
135         unsafe {
136             (self.point_add_jacobian_impl)(r.xyz.as_mut_ptr(), a.xyz.as_ptr(), b.xyz.as_ptr())
137         }
138         r
139     }
140 
point_x(&self, p: &Point) -> Elem<R>141     pub fn point_x(&self, p: &Point) -> Elem<R> {
142         let mut r = Elem::zero();
143         r.limbs[..self.num_limbs].copy_from_slice(&p.xyz[0..self.num_limbs]);
144         r
145     }
146 
point_y(&self, p: &Point) -> Elem<R>147     pub fn point_y(&self, p: &Point) -> Elem<R> {
148         let mut r = Elem::zero();
149         r.limbs[..self.num_limbs].copy_from_slice(&p.xyz[self.num_limbs..(2 * self.num_limbs)]);
150         r
151     }
152 
point_z(&self, p: &Point) -> Elem<R>153     pub fn point_z(&self, p: &Point) -> Elem<R> {
154         let mut r = Elem::zero();
155         r.limbs[..self.num_limbs]
156             .copy_from_slice(&p.xyz[(2 * self.num_limbs)..(3 * self.num_limbs)]);
157         r
158     }
159 }
160 
161 struct Modulus {
162     p: [Limb; MAX_LIMBS],
163     rr: [Limb; MAX_LIMBS],
164 }
165 
166 /// Operations on private keys, for ECDH and ECDSA signing.
167 pub struct PrivateKeyOps {
168     pub common: &'static CommonOps,
169     elem_inv_squared: fn(a: &Elem<R>) -> Elem<R>,
170     point_mul_base_impl: fn(a: &Scalar) -> Point,
171     point_mul_impl: unsafe extern "C" fn(
172         r: *mut Limb,          // [3][num_limbs]
173         p_scalar: *const Limb, // [num_limbs]
174         p_x: *const Limb,      // [num_limbs]
175         p_y: *const Limb,      // [num_limbs]
176     ),
177 }
178 
179 impl PrivateKeyOps {
180     #[inline(always)]
point_mul_base(&self, a: &Scalar) -> Point181     pub fn point_mul_base(&self, a: &Scalar) -> Point {
182         (self.point_mul_base_impl)(a)
183     }
184 
185     #[inline(always)]
point_mul(&self, p_scalar: &Scalar, (p_x, p_y): &(Elem<R>, Elem<R>)) -> Point186     pub fn point_mul(&self, p_scalar: &Scalar, (p_x, p_y): &(Elem<R>, Elem<R>)) -> Point {
187         let mut r = Point::new_at_infinity();
188         unsafe {
189             (self.point_mul_impl)(
190                 r.xyz.as_mut_ptr(),
191                 p_scalar.limbs.as_ptr(),
192                 p_x.limbs.as_ptr(),
193                 p_y.limbs.as_ptr(),
194             );
195         }
196         r
197     }
198 
199     #[inline]
elem_inverse_squared(&self, a: &Elem<R>) -> Elem<R>200     pub fn elem_inverse_squared(&self, a: &Elem<R>) -> Elem<R> {
201         (self.elem_inv_squared)(a)
202     }
203 }
204 
205 /// Operations and values needed by all operations on public keys (ECDH
206 /// agreement and ECDSA verification).
207 pub struct PublicKeyOps {
208     pub common: &'static CommonOps,
209 }
210 
211 impl PublicKeyOps {
212     // The serialized bytes are in big-endian order, zero-padded. The limbs
213     // of `Elem` are in the native endianness, least significant limb to
214     // most significant limb. Besides the parsing, conversion, this also
215     // implements NIST SP 800-56A Step 2: "Verify that xQ and yQ are integers
216     // in the interval [0, p-1] in the case that q is an odd prime p[.]"
elem_parse(&self, input: &mut untrusted::Reader) -> Result<Elem<R>, error::Unspecified>217     pub fn elem_parse(&self, input: &mut untrusted::Reader) -> Result<Elem<R>, error::Unspecified> {
218         let encoded_value = input.read_bytes(self.common.num_limbs * LIMB_BYTES)?;
219         let parsed = elem_parse_big_endian_fixed_consttime(self.common, encoded_value)?;
220         let mut r = Elem::zero();
221         // Montgomery encode (elem_to_mont).
222         // TODO: do something about this.
223         unsafe {
224             (self.common.elem_mul_mont)(
225                 r.limbs.as_mut_ptr(),
226                 parsed.limbs.as_ptr(),
227                 self.common.q.rr.as_ptr(),
228             )
229         }
230         Ok(r)
231     }
232 }
233 
234 // Operations used by both ECDSA signing and ECDSA verification. In general
235 // these must be side-channel resistant.
236 pub struct ScalarOps {
237     pub common: &'static CommonOps,
238 
239     scalar_inv_to_mont_impl: fn(a: &Scalar) -> Scalar<R>,
240     scalar_mul_mont: unsafe extern "C" fn(r: *mut Limb, a: *const Limb, b: *const Limb),
241 }
242 
243 impl ScalarOps {
244     // The (maximum) length of a scalar, not including any padding.
scalar_bytes_len(&self) -> usize245     pub fn scalar_bytes_len(&self) -> usize {
246         self.common.num_limbs * LIMB_BYTES
247     }
248 
249     /// Returns the modular inverse of `a` (mod `n`). Panics of `a` is zero,
250     /// because zero isn't invertible.
scalar_inv_to_mont(&self, a: &Scalar) -> Scalar<R>251     pub fn scalar_inv_to_mont(&self, a: &Scalar) -> Scalar<R> {
252         assert!(!self.common.is_zero(a));
253         (self.scalar_inv_to_mont_impl)(a)
254     }
255 
256     #[inline]
scalar_product<EA: Encoding, EB: Encoding>( &self, a: &Scalar<EA>, b: &Scalar<EB>, ) -> Scalar<<(EA, EB) as ProductEncoding>::Output> where (EA, EB): ProductEncoding,257     pub fn scalar_product<EA: Encoding, EB: Encoding>(
258         &self,
259         a: &Scalar<EA>,
260         b: &Scalar<EB>,
261     ) -> Scalar<<(EA, EB) as ProductEncoding>::Output>
262     where
263         (EA, EB): ProductEncoding,
264     {
265         mul_mont(self.scalar_mul_mont, a, b)
266     }
267 }
268 
269 /// Operations on public scalars needed by ECDSA signature verification.
270 pub struct PublicScalarOps {
271     pub scalar_ops: &'static ScalarOps,
272     pub public_key_ops: &'static PublicKeyOps,
273 
274     // XXX: `PublicScalarOps` shouldn't depend on `PrivateKeyOps`, but it does
275     // temporarily until `twin_mul` is rewritten.
276     pub private_key_ops: &'static PrivateKeyOps,
277 
278     pub q_minus_n: Elem<Unencoded>,
279 }
280 
281 impl PublicScalarOps {
282     #[inline]
scalar_as_elem(&self, a: &Scalar) -> Elem<Unencoded>283     pub fn scalar_as_elem(&self, a: &Scalar) -> Elem<Unencoded> {
284         Elem {
285             limbs: a.limbs,
286             m: PhantomData,
287             encoding: PhantomData,
288         }
289     }
290 
elem_equals(&self, a: &Elem<Unencoded>, b: &Elem<Unencoded>) -> bool291     pub fn elem_equals(&self, a: &Elem<Unencoded>, b: &Elem<Unencoded>) -> bool {
292         for i in 0..self.public_key_ops.common.num_limbs {
293             if a.limbs[i] != b.limbs[i] {
294                 return false;
295             }
296         }
297         true
298     }
299 
elem_less_than(&self, a: &Elem<Unencoded>, b: &Elem<Unencoded>) -> bool300     pub fn elem_less_than(&self, a: &Elem<Unencoded>, b: &Elem<Unencoded>) -> bool {
301         let num_limbs = self.public_key_ops.common.num_limbs;
302         limbs_less_than_limbs_vartime(&a.limbs[..num_limbs], &b.limbs[..num_limbs])
303     }
304 
305     #[inline]
elem_sum(&self, a: &Elem<Unencoded>, b: &Elem<Unencoded>) -> Elem<Unencoded>306     pub fn elem_sum(&self, a: &Elem<Unencoded>, b: &Elem<Unencoded>) -> Elem<Unencoded> {
307         binary_op(self.public_key_ops.common.elem_add_impl, a, b)
308     }
309 }
310 
311 #[allow(non_snake_case)]
312 pub struct PrivateScalarOps {
313     pub scalar_ops: &'static ScalarOps,
314 
315     pub oneRR_mod_n: Scalar<RR>, // 1 * R**2 (mod n). TOOD: Use One<RR>.
316 }
317 
318 // This assumes n < q < 2*n.
elem_reduced_to_scalar(ops: &CommonOps, elem: &Elem<Unencoded>) -> Scalar<Unencoded>319 pub fn elem_reduced_to_scalar(ops: &CommonOps, elem: &Elem<Unencoded>) -> Scalar<Unencoded> {
320     let num_limbs = ops.num_limbs;
321     let mut r_limbs = elem.limbs;
322     limbs_reduce_once_constant_time(&mut r_limbs[..num_limbs], &ops.n.limbs[..num_limbs]);
323     Scalar {
324         limbs: r_limbs,
325         m: PhantomData,
326         encoding: PhantomData,
327     }
328 }
329 
scalar_sum(ops: &CommonOps, a: &Scalar, b: &Scalar) -> Scalar330 pub fn scalar_sum(ops: &CommonOps, a: &Scalar, b: &Scalar) -> Scalar {
331     let mut r = Scalar::zero();
332     unsafe {
333         LIMBS_add_mod(
334             r.limbs.as_mut_ptr(),
335             a.limbs.as_ptr(),
336             b.limbs.as_ptr(),
337             ops.n.limbs.as_ptr(),
338             ops.num_limbs,
339         )
340     }
341     r
342 }
343 
344 // Returns (`a` squared `squarings` times) * `b`.
elem_sqr_mul(ops: &CommonOps, a: &Elem<R>, squarings: usize, b: &Elem<R>) -> Elem<R>345 fn elem_sqr_mul(ops: &CommonOps, a: &Elem<R>, squarings: usize, b: &Elem<R>) -> Elem<R> {
346     debug_assert!(squarings >= 1);
347     let mut tmp = ops.elem_squared(a);
348     for _ in 1..squarings {
349         ops.elem_square(&mut tmp);
350     }
351     ops.elem_product(&tmp, b)
352 }
353 
354 // Sets `acc` = (`acc` squared `squarings` times) * `b`.
elem_sqr_mul_acc(ops: &CommonOps, acc: &mut Elem<R>, squarings: usize, b: &Elem<R>)355 fn elem_sqr_mul_acc(ops: &CommonOps, acc: &mut Elem<R>, squarings: usize, b: &Elem<R>) {
356     debug_assert!(squarings >= 1);
357     for _ in 0..squarings {
358         ops.elem_square(acc);
359     }
360     ops.elem_mul(acc, b)
361 }
362 
363 #[inline]
elem_parse_big_endian_fixed_consttime( ops: &CommonOps, bytes: untrusted::Input, ) -> Result<Elem<Unencoded>, error::Unspecified>364 pub fn elem_parse_big_endian_fixed_consttime(
365     ops: &CommonOps,
366     bytes: untrusted::Input,
367 ) -> Result<Elem<Unencoded>, error::Unspecified> {
368     parse_big_endian_fixed_consttime(ops, bytes, AllowZero::Yes, &ops.q.p[..ops.num_limbs])
369 }
370 
371 #[inline]
scalar_parse_big_endian_fixed_consttime( ops: &CommonOps, bytes: untrusted::Input, ) -> Result<Scalar, error::Unspecified>372 pub fn scalar_parse_big_endian_fixed_consttime(
373     ops: &CommonOps,
374     bytes: untrusted::Input,
375 ) -> Result<Scalar, error::Unspecified> {
376     parse_big_endian_fixed_consttime(ops, bytes, AllowZero::No, &ops.n.limbs[..ops.num_limbs])
377 }
378 
379 #[inline]
scalar_parse_big_endian_variable( ops: &CommonOps, allow_zero: AllowZero, bytes: untrusted::Input, ) -> Result<Scalar, error::Unspecified>380 pub fn scalar_parse_big_endian_variable(
381     ops: &CommonOps,
382     allow_zero: AllowZero,
383     bytes: untrusted::Input,
384 ) -> Result<Scalar, error::Unspecified> {
385     let mut r = Scalar::zero();
386     parse_big_endian_in_range_and_pad_consttime(
387         bytes,
388         allow_zero,
389         &ops.n.limbs[..ops.num_limbs],
390         &mut r.limbs[..ops.num_limbs],
391     )?;
392     Ok(r)
393 }
394 
scalar_parse_big_endian_partially_reduced_variable_consttime( ops: &CommonOps, allow_zero: AllowZero, bytes: untrusted::Input, ) -> Result<Scalar, error::Unspecified>395 pub fn scalar_parse_big_endian_partially_reduced_variable_consttime(
396     ops: &CommonOps,
397     allow_zero: AllowZero,
398     bytes: untrusted::Input,
399 ) -> Result<Scalar, error::Unspecified> {
400     let mut r = Scalar::zero();
401     parse_big_endian_in_range_partially_reduced_and_pad_consttime(
402         bytes,
403         allow_zero,
404         &ops.n.limbs[..ops.num_limbs],
405         &mut r.limbs[..ops.num_limbs],
406     )?;
407     Ok(r)
408 }
409 
parse_big_endian_fixed_consttime<M>( ops: &CommonOps, bytes: untrusted::Input, allow_zero: AllowZero, max_exclusive: &[Limb], ) -> Result<elem::Elem<M, Unencoded>, error::Unspecified>410 fn parse_big_endian_fixed_consttime<M>(
411     ops: &CommonOps,
412     bytes: untrusted::Input,
413     allow_zero: AllowZero,
414     max_exclusive: &[Limb],
415 ) -> Result<elem::Elem<M, Unencoded>, error::Unspecified> {
416     if bytes.len() != ops.num_limbs * LIMB_BYTES {
417         return Err(error::Unspecified);
418     }
419     let mut r = elem::Elem::zero();
420     parse_big_endian_in_range_and_pad_consttime(
421         bytes,
422         allow_zero,
423         max_exclusive,
424         &mut r.limbs[..ops.num_limbs],
425     )?;
426     Ok(r)
427 }
428 
429 extern "C" {
LIMBS_add_mod( r: *mut Limb, a: *const Limb, b: *const Limb, m: *const Limb, num_limbs: c::size_t, )430     fn LIMBS_add_mod(
431         r: *mut Limb,
432         a: *const Limb,
433         b: *const Limb,
434         m: *const Limb,
435         num_limbs: c::size_t,
436     );
437 }
438 
439 #[cfg(test)]
440 mod tests {
441     use super::*;
442     use crate::test;
443     use alloc::{format, vec, vec::Vec};
444     use untrusted;
445 
446     const ZERO_SCALAR: Scalar = Scalar {
447         limbs: [0; MAX_LIMBS],
448         m: PhantomData,
449         encoding: PhantomData,
450     };
451 
q_minus_n_plus_n_equals_0_test(ops: &PublicScalarOps)452     fn q_minus_n_plus_n_equals_0_test(ops: &PublicScalarOps) {
453         let cops = ops.scalar_ops.common;
454         let mut x = ops.q_minus_n;
455         cops.elem_add(&mut x, &cops.n);
456         assert!(cops.is_zero(&x));
457     }
458 
459     #[test]
p256_q_minus_n_plus_n_equals_0_test()460     fn p256_q_minus_n_plus_n_equals_0_test() {
461         q_minus_n_plus_n_equals_0_test(&p256::PUBLIC_SCALAR_OPS);
462     }
463 
464     #[test]
p384_q_minus_n_plus_n_equals_0_test()465     fn p384_q_minus_n_plus_n_equals_0_test() {
466         q_minus_n_plus_n_equals_0_test(&p384::PUBLIC_SCALAR_OPS);
467     }
468 
469     #[test]
p256_elem_add_test()470     fn p256_elem_add_test() {
471         elem_add_test(
472             &p256::PUBLIC_SCALAR_OPS,
473             test_file!("ops/p256_elem_sum_tests.txt"),
474         );
475     }
476 
477     #[test]
p384_elem_add_test()478     fn p384_elem_add_test() {
479         elem_add_test(
480             &p384::PUBLIC_SCALAR_OPS,
481             test_file!("ops/p384_elem_sum_tests.txt"),
482         );
483     }
484 
elem_add_test(ops: &PublicScalarOps, test_file: test::File)485     fn elem_add_test(ops: &PublicScalarOps, test_file: test::File) {
486         test::run(test_file, |section, test_case| {
487             assert_eq!(section, "");
488 
489             let cops = ops.public_key_ops.common;
490             let a = consume_elem(cops, test_case, "a");
491             let b = consume_elem(cops, test_case, "b");
492             let expected_sum = consume_elem(cops, test_case, "r");
493 
494             let mut actual_sum = a.clone();
495             ops.public_key_ops.common.elem_add(&mut actual_sum, &b);
496             assert_limbs_are_equal(cops, &actual_sum.limbs, &expected_sum.limbs);
497 
498             let mut actual_sum = b.clone();
499             ops.public_key_ops.common.elem_add(&mut actual_sum, &a);
500             assert_limbs_are_equal(cops, &actual_sum.limbs, &expected_sum.limbs);
501 
502             Ok(())
503         })
504     }
505 
506     // XXX: There's no `GFp_nistz256_sub` in *ring*; it's logic is inlined into
507     // the point arithmetic functions. Thus, we can't test it.
508 
509     #[test]
p384_elem_sub_test()510     fn p384_elem_sub_test() {
511         extern "C" {
512             fn GFp_p384_elem_sub(r: *mut Limb, a: *const Limb, b: *const Limb);
513         }
514         elem_sub_test(
515             &p384::COMMON_OPS,
516             GFp_p384_elem_sub,
517             test_file!("ops/p384_elem_sum_tests.txt"),
518         );
519     }
520 
elem_sub_test( ops: &CommonOps, elem_sub: unsafe extern "C" fn(r: *mut Limb, a: *const Limb, b: *const Limb), test_file: test::File, )521     fn elem_sub_test(
522         ops: &CommonOps,
523         elem_sub: unsafe extern "C" fn(r: *mut Limb, a: *const Limb, b: *const Limb),
524         test_file: test::File,
525     ) {
526         test::run(test_file, |section, test_case| {
527             assert_eq!(section, "");
528 
529             let a = consume_elem(ops, test_case, "a");
530             let b = consume_elem(ops, test_case, "b");
531             let r = consume_elem(ops, test_case, "r");
532 
533             let mut actual_difference = Elem::<R>::zero();
534             unsafe {
535                 elem_sub(
536                     actual_difference.limbs.as_mut_ptr(),
537                     r.limbs.as_ptr(),
538                     b.limbs.as_ptr(),
539                 );
540             }
541             assert_limbs_are_equal(ops, &actual_difference.limbs, &a.limbs);
542 
543             let mut actual_difference = Elem::<R>::zero();
544             unsafe {
545                 elem_sub(
546                     actual_difference.limbs.as_mut_ptr(),
547                     r.limbs.as_ptr(),
548                     a.limbs.as_ptr(),
549                 );
550             }
551             assert_limbs_are_equal(ops, &actual_difference.limbs, &b.limbs);
552 
553             Ok(())
554         })
555     }
556 
557     // XXX: There's no `GFp_nistz256_div_by_2` in *ring*; it's logic is inlined
558     // into the point arithmetic functions. Thus, we can't test it.
559 
560     #[test]
p384_elem_div_by_2_test()561     fn p384_elem_div_by_2_test() {
562         extern "C" {
563             fn GFp_p384_elem_div_by_2(r: *mut Limb, a: *const Limb);
564         }
565         elem_div_by_2_test(
566             &p384::COMMON_OPS,
567             GFp_p384_elem_div_by_2,
568             test_file!("ops/p384_elem_div_by_2_tests.txt"),
569         );
570     }
571 
elem_div_by_2_test( ops: &CommonOps, elem_div_by_2: unsafe extern "C" fn(r: *mut Limb, a: *const Limb), test_file: test::File, )572     fn elem_div_by_2_test(
573         ops: &CommonOps,
574         elem_div_by_2: unsafe extern "C" fn(r: *mut Limb, a: *const Limb),
575         test_file: test::File,
576     ) {
577         test::run(test_file, |section, test_case| {
578             assert_eq!(section, "");
579 
580             let a = consume_elem(ops, test_case, "a");
581             let r = consume_elem(ops, test_case, "r");
582 
583             let mut actual_result = Elem::<R>::zero();
584             unsafe {
585                 elem_div_by_2(actual_result.limbs.as_mut_ptr(), a.limbs.as_ptr());
586             }
587             assert_limbs_are_equal(ops, &actual_result.limbs, &r.limbs);
588 
589             Ok(())
590         })
591     }
592 
593     // TODO: Add test vectors that test the range of values above `q`.
594     #[test]
p256_elem_neg_test()595     fn p256_elem_neg_test() {
596         extern "C" {
597             fn GFp_nistz256_neg(r: *mut Limb, a: *const Limb);
598         }
599         elem_neg_test(
600             &p256::COMMON_OPS,
601             GFp_nistz256_neg,
602             test_file!("ops/p256_elem_neg_tests.txt"),
603         );
604     }
605 
606     #[test]
p384_elem_neg_test()607     fn p384_elem_neg_test() {
608         extern "C" {
609             fn GFp_p384_elem_neg(r: *mut Limb, a: *const Limb);
610         }
611         elem_neg_test(
612             &p384::COMMON_OPS,
613             GFp_p384_elem_neg,
614             test_file!("ops/p384_elem_neg_tests.txt"),
615         );
616     }
617 
elem_neg_test( ops: &CommonOps, elem_neg: unsafe extern "C" fn(r: *mut Limb, a: *const Limb), test_file: test::File, )618     fn elem_neg_test(
619         ops: &CommonOps,
620         elem_neg: unsafe extern "C" fn(r: *mut Limb, a: *const Limb),
621         test_file: test::File,
622     ) {
623         test::run(test_file, |section, test_case| {
624             assert_eq!(section, "");
625 
626             let a = consume_elem(ops, test_case, "a");
627             let b = consume_elem(ops, test_case, "b");
628 
629             // Verify -a == b.
630             {
631                 let mut actual_result = Elem::<R>::zero();
632                 unsafe {
633                     elem_neg(actual_result.limbs.as_mut_ptr(), a.limbs.as_ptr());
634                 }
635                 assert_limbs_are_equal(ops, &actual_result.limbs, &b.limbs);
636             }
637 
638             // Verify -b == a.
639             {
640                 let mut actual_result = Elem::<R>::zero();
641                 unsafe {
642                     elem_neg(actual_result.limbs.as_mut_ptr(), b.limbs.as_ptr());
643                 }
644                 assert_limbs_are_equal(ops, &actual_result.limbs, &a.limbs);
645             }
646 
647             Ok(())
648         })
649     }
650 
651     #[test]
p256_elem_mul_test()652     fn p256_elem_mul_test() {
653         elem_mul_test(&p256::COMMON_OPS, test_file!("ops/p256_elem_mul_tests.txt"));
654     }
655 
656     #[test]
p384_elem_mul_test()657     fn p384_elem_mul_test() {
658         elem_mul_test(&p384::COMMON_OPS, test_file!("ops/p384_elem_mul_tests.txt"));
659     }
660 
elem_mul_test(ops: &CommonOps, test_file: test::File)661     fn elem_mul_test(ops: &CommonOps, test_file: test::File) {
662         test::run(test_file, |section, test_case| {
663             assert_eq!(section, "");
664 
665             let mut a = consume_elem(ops, test_case, "a");
666             let b = consume_elem(ops, test_case, "b");
667             let r = consume_elem(ops, test_case, "r");
668             ops.elem_mul(&mut a, &b);
669             assert_limbs_are_equal(ops, &a.limbs, &r.limbs);
670 
671             Ok(())
672         })
673     }
674 
675     #[test]
p256_scalar_mul_test()676     fn p256_scalar_mul_test() {
677         scalar_mul_test(
678             &p256::SCALAR_OPS,
679             test_file!("ops/p256_scalar_mul_tests.txt"),
680         );
681     }
682 
683     #[test]
p384_scalar_mul_test()684     fn p384_scalar_mul_test() {
685         scalar_mul_test(
686             &p384::SCALAR_OPS,
687             test_file!("ops/p384_scalar_mul_tests.txt"),
688         );
689     }
690 
scalar_mul_test(ops: &ScalarOps, test_file: test::File)691     fn scalar_mul_test(ops: &ScalarOps, test_file: test::File) {
692         test::run(test_file, |section, test_case| {
693             assert_eq!(section, "");
694             let cops = ops.common;
695             let mut a = consume_scalar(cops, test_case, "a");
696             let b = consume_scalar_mont(cops, test_case, "b");
697             let expected_result = consume_scalar(cops, test_case, "r");
698             let actual_result = ops.scalar_product(&mut a, &b);
699             assert_limbs_are_equal(cops, &actual_result.limbs, &expected_result.limbs);
700 
701             Ok(())
702         })
703     }
704 
705     #[test]
p256_scalar_square_test()706     fn p256_scalar_square_test() {
707         extern "C" {
708             fn GFp_p256_scalar_sqr_rep_mont(r: *mut Limb, a: *const Limb, rep: Limb);
709         }
710         scalar_square_test(
711             &p256::SCALAR_OPS,
712             GFp_p256_scalar_sqr_rep_mont,
713             test_file!("ops/p256_scalar_square_tests.txt"),
714         );
715     }
716 
717     // XXX: There's no `p384_scalar_square_test()` because there's no dedicated
718     // `GFp_p384_scalar_sqr_rep_mont()`.
719 
scalar_square_test( ops: &ScalarOps, sqr_rep: unsafe extern "C" fn(r: *mut Limb, a: *const Limb, rep: Limb), test_file: test::File, )720     fn scalar_square_test(
721         ops: &ScalarOps,
722         sqr_rep: unsafe extern "C" fn(r: *mut Limb, a: *const Limb, rep: Limb),
723         test_file: test::File,
724     ) {
725         test::run(test_file, |section, test_case| {
726             assert_eq!(section, "");
727             let cops = &ops.common;
728             let a = consume_scalar(cops, test_case, "a");
729             let expected_result = consume_scalar(cops, test_case, "r");
730 
731             {
732                 let mut actual_result: Scalar<R> = Scalar {
733                     limbs: [0; MAX_LIMBS],
734                     m: PhantomData,
735                     encoding: PhantomData,
736                 };
737                 unsafe {
738                     sqr_rep(actual_result.limbs.as_mut_ptr(), a.limbs.as_ptr(), 1);
739                 }
740                 assert_limbs_are_equal(cops, &actual_result.limbs, &expected_result.limbs);
741             }
742 
743             {
744                 let actual_result = ops.scalar_product(&a, &a);
745                 assert_limbs_are_equal(cops, &actual_result.limbs, &expected_result.limbs);
746             }
747 
748             Ok(())
749         })
750     }
751 
752     #[test]
753     #[should_panic(expected = "!self.common.is_zero(a)")]
p256_scalar_inv_to_mont_zero_panic_test()754     fn p256_scalar_inv_to_mont_zero_panic_test() {
755         let _ = p256::SCALAR_OPS.scalar_inv_to_mont(&ZERO_SCALAR);
756     }
757 
758     #[test]
759     #[should_panic(expected = "!self.common.is_zero(a)")]
p384_scalar_inv_to_mont_zero_panic_test()760     fn p384_scalar_inv_to_mont_zero_panic_test() {
761         let _ = p384::SCALAR_OPS.scalar_inv_to_mont(&ZERO_SCALAR);
762     }
763 
764     #[test]
p256_point_sum_test()765     fn p256_point_sum_test() {
766         point_sum_test(
767             &p256::PRIVATE_KEY_OPS,
768             test_file!("ops/p256_point_sum_tests.txt"),
769         );
770     }
771 
772     #[test]
p384_point_sum_test()773     fn p384_point_sum_test() {
774         point_sum_test(
775             &p384::PRIVATE_KEY_OPS,
776             test_file!("ops/p384_point_sum_tests.txt"),
777         );
778     }
779 
point_sum_test(ops: &PrivateKeyOps, test_file: test::File)780     fn point_sum_test(ops: &PrivateKeyOps, test_file: test::File) {
781         test::run(test_file, |section, test_case| {
782             assert_eq!(section, "");
783 
784             let a = consume_jacobian_point(ops, test_case, "a");
785             let b = consume_jacobian_point(ops, test_case, "b");
786             let r_expected = consume_point(ops, test_case, "r");
787 
788             let r_actual = ops.common.point_sum(&a, &b);
789             assert_point_actual_equals_expected(ops, &r_actual, &r_expected);
790 
791             Ok(())
792         });
793     }
794 
795     #[test]
p256_point_sum_mixed_test()796     fn p256_point_sum_mixed_test() {
797         extern "C" {
798             fn GFp_nistz256_point_add_affine(
799                 r: *mut Limb,   // [p256::COMMON_OPS.num_limbs*3]
800                 a: *const Limb, // [p256::COMMON_OPS.num_limbs*3]
801                 b: *const Limb, // [p256::COMMON_OPS.num_limbs*2]
802             );
803         }
804         point_sum_mixed_test(
805             &p256::PRIVATE_KEY_OPS,
806             GFp_nistz256_point_add_affine,
807             test_file!("ops/p256_point_sum_mixed_tests.txt"),
808         );
809     }
810 
811     // XXX: There is no `GFp_nistz384_point_add_affine()`.
812 
point_sum_mixed_test( ops: &PrivateKeyOps, point_add_affine: unsafe extern "C" fn( r: *mut Limb, a: *const Limb, b: *const Limb, ), test_file: test::File, )813     fn point_sum_mixed_test(
814         ops: &PrivateKeyOps,
815         point_add_affine: unsafe extern "C" fn(
816             r: *mut Limb,   // [ops.num_limbs*3]
817             a: *const Limb, // [ops.num_limbs*3]
818             b: *const Limb, // [ops.num_limbs*2]
819         ),
820         test_file: test::File,
821     ) {
822         test::run(test_file, |section, test_case| {
823             assert_eq!(section, "");
824 
825             let a = consume_jacobian_point(ops, test_case, "a");
826             let b = consume_affine_point(ops, test_case, "b");
827             let r_expected = consume_point(ops, test_case, "r");
828 
829             let mut r_actual = Point::new_at_infinity();
830             unsafe {
831                 point_add_affine(r_actual.xyz.as_mut_ptr(), a.xyz.as_ptr(), b.xy.as_ptr());
832             }
833 
834             assert_point_actual_equals_expected(ops, &r_actual, &r_expected);
835 
836             Ok(())
837         });
838     }
839 
840     #[test]
p256_point_double_test()841     fn p256_point_double_test() {
842         extern "C" {
843             fn GFp_nistz256_point_double(
844                 r: *mut Limb,   // [p256::COMMON_OPS.num_limbs*3]
845                 a: *const Limb, // [p256::COMMON_OPS.num_limbs*3]
846             );
847         }
848         point_double_test(
849             &p256::PRIVATE_KEY_OPS,
850             GFp_nistz256_point_double,
851             test_file!("ops/p256_point_double_tests.txt"),
852         );
853     }
854 
855     #[test]
p384_point_double_test()856     fn p384_point_double_test() {
857         extern "C" {
858             fn GFp_nistz384_point_double(
859                 r: *mut Limb,   // [p384::COMMON_OPS.num_limbs*3]
860                 a: *const Limb, // [p384::COMMON_OPS.num_limbs*3]
861             );
862         }
863         point_double_test(
864             &p384::PRIVATE_KEY_OPS,
865             GFp_nistz384_point_double,
866             test_file!("ops/p384_point_double_tests.txt"),
867         );
868     }
869 
point_double_test( ops: &PrivateKeyOps, point_double: unsafe extern "C" fn( r: *mut Limb, a: *const Limb, ), test_file: test::File, )870     fn point_double_test(
871         ops: &PrivateKeyOps,
872         point_double: unsafe extern "C" fn(
873             r: *mut Limb,   // [ops.num_limbs*3]
874             a: *const Limb, // [ops.num_limbs*3]
875         ),
876         test_file: test::File,
877     ) {
878         test::run(test_file, |section, test_case| {
879             assert_eq!(section, "");
880 
881             let a = consume_jacobian_point(ops, test_case, "a");
882             let r_expected = consume_point(ops, test_case, "r");
883 
884             let mut r_actual = Point::new_at_infinity();
885             unsafe {
886                 point_double(r_actual.xyz.as_mut_ptr(), a.xyz.as_ptr());
887             }
888 
889             assert_point_actual_equals_expected(ops, &r_actual, &r_expected);
890 
891             Ok(())
892         });
893     }
894 
895     #[test]
p256_point_mul_test()896     fn p256_point_mul_test() {
897         point_mul_tests(
898             &p256::PRIVATE_KEY_OPS,
899             test_file!("ops/p256_point_mul_tests.txt"),
900         );
901     }
902 
903     #[test]
p384_point_mul_test()904     fn p384_point_mul_test() {
905         point_mul_tests(
906             &p384::PRIVATE_KEY_OPS,
907             test_file!("ops/p384_point_mul_tests.txt"),
908         );
909     }
910 
point_mul_tests(ops: &PrivateKeyOps, test_file: test::File)911     fn point_mul_tests(ops: &PrivateKeyOps, test_file: test::File) {
912         test::run(test_file, |section, test_case| {
913             assert_eq!(section, "");
914             let p_scalar = consume_scalar(ops.common, test_case, "p_scalar");
915             let (x, y) = match consume_point(ops, test_case, "p") {
916                 TestPoint::Infinity => {
917                     panic!("can't be inf.");
918                 }
919                 TestPoint::Affine(x, y) => (x, y),
920             };
921             let expected_result = consume_point(ops, test_case, "r");
922             let actual_result = ops.point_mul(&p_scalar, &(x, y));
923             assert_point_actual_equals_expected(ops, &actual_result, &expected_result);
924             Ok(())
925         })
926     }
927 
928     #[test]
p256_point_mul_serialized_test()929     fn p256_point_mul_serialized_test() {
930         point_mul_serialized_test(
931             &p256::PRIVATE_KEY_OPS,
932             &p256::PUBLIC_KEY_OPS,
933             test_file!("ops/p256_point_mul_serialized_tests.txt"),
934         );
935     }
936 
point_mul_serialized_test( priv_ops: &PrivateKeyOps, pub_ops: &PublicKeyOps, test_file: test::File, )937     fn point_mul_serialized_test(
938         priv_ops: &PrivateKeyOps,
939         pub_ops: &PublicKeyOps,
940         test_file: test::File,
941     ) {
942         let cops = pub_ops.common;
943 
944         test::run(test_file, |section, test_case| {
945             assert_eq!(section, "");
946             let p_scalar = consume_scalar(cops, test_case, "p_scalar");
947 
948             let p = test_case.consume_bytes("p");
949             let p = super::super::public_key::parse_uncompressed_point(
950                 pub_ops,
951                 untrusted::Input::from(&p),
952             )
953             .expect("valid point");
954 
955             let expected_result = test_case.consume_bytes("r");
956 
957             let product = priv_ops.point_mul(&p_scalar, &p);
958 
959             let mut actual_result = vec![4u8; 1 + (2 * (cops.num_limbs * LIMB_BYTES))];
960             {
961                 let (x, y) = actual_result[1..].split_at_mut(cops.num_limbs * LIMB_BYTES);
962                 super::super::private_key::big_endian_affine_from_jacobian(
963                     priv_ops,
964                     Some(x),
965                     Some(y),
966                     &product,
967                 )
968                 .expect("successful encoding");
969             }
970 
971             assert_eq!(expected_result, actual_result);
972 
973             Ok(())
974         })
975     }
976 
977     #[test]
p256_point_mul_base_test()978     fn p256_point_mul_base_test() {
979         point_mul_base_tests(
980             &p256::PRIVATE_KEY_OPS,
981             test_file!("ops/p256_point_mul_base_tests.txt"),
982         );
983     }
984 
985     #[test]
p384_point_mul_base_test()986     fn p384_point_mul_base_test() {
987         point_mul_base_tests(
988             &p384::PRIVATE_KEY_OPS,
989             test_file!("ops/p384_point_mul_base_tests.txt"),
990         );
991     }
992 
point_mul_base_tests(ops: &PrivateKeyOps, test_file: test::File)993     fn point_mul_base_tests(ops: &PrivateKeyOps, test_file: test::File) {
994         test::run(test_file, |section, test_case| {
995             assert_eq!(section, "");
996             let g_scalar = consume_scalar(ops.common, test_case, "g_scalar");
997             let expected_result = consume_point(ops, test_case, "r");
998             let actual_result = ops.point_mul_base(&g_scalar);
999             assert_point_actual_equals_expected(ops, &actual_result, &expected_result);
1000             Ok(())
1001         })
1002     }
1003 
assert_point_actual_equals_expected( ops: &PrivateKeyOps, actual_point: &Point, expected_point: &TestPoint, )1004     fn assert_point_actual_equals_expected(
1005         ops: &PrivateKeyOps,
1006         actual_point: &Point,
1007         expected_point: &TestPoint,
1008     ) {
1009         let cops = ops.common;
1010         let actual_x = &cops.point_x(&actual_point);
1011         let actual_y = &cops.point_y(&actual_point);
1012         let actual_z = &cops.point_z(&actual_point);
1013         match expected_point {
1014             TestPoint::Infinity => {
1015                 let zero = Elem::zero();
1016                 assert_elems_are_equal(cops, &actual_z, &zero);
1017             }
1018             TestPoint::Affine(expected_x, expected_y) => {
1019                 let zz_inv = ops.elem_inverse_squared(&actual_z);
1020                 let x_aff = cops.elem_product(&actual_x, &zz_inv);
1021                 let y_aff = {
1022                     let zzzz_inv = cops.elem_squared(&zz_inv);
1023                     let zzz_inv = cops.elem_product(&actual_z, &zzzz_inv);
1024                     cops.elem_product(&actual_y, &zzz_inv)
1025                 };
1026 
1027                 assert_elems_are_equal(cops, &x_aff, &expected_x);
1028                 assert_elems_are_equal(cops, &y_aff, &expected_y);
1029             }
1030         }
1031     }
1032 
consume_jacobian_point( ops: &PrivateKeyOps, test_case: &mut test::TestCase, name: &str, ) -> Point1033     fn consume_jacobian_point(
1034         ops: &PrivateKeyOps,
1035         test_case: &mut test::TestCase,
1036         name: &str,
1037     ) -> Point {
1038         let input = test_case.consume_string(name);
1039         let elems = input.split(", ").collect::<Vec<&str>>();
1040         assert_eq!(elems.len(), 3);
1041         let mut p = Point::new_at_infinity();
1042         consume_point_elem(ops.common, &mut p.xyz, &elems, 0);
1043         consume_point_elem(ops.common, &mut p.xyz, &elems, 1);
1044         consume_point_elem(ops.common, &mut p.xyz, &elems, 2);
1045         p
1046     }
1047 
1048     struct AffinePoint {
1049         xy: [Limb; 2 * MAX_LIMBS],
1050     }
1051 
consume_affine_point( ops: &PrivateKeyOps, test_case: &mut test::TestCase, name: &str, ) -> AffinePoint1052     fn consume_affine_point(
1053         ops: &PrivateKeyOps,
1054         test_case: &mut test::TestCase,
1055         name: &str,
1056     ) -> AffinePoint {
1057         let input = test_case.consume_string(name);
1058         let elems = input.split(", ").collect::<Vec<&str>>();
1059         assert_eq!(elems.len(), 2);
1060         let mut p = AffinePoint {
1061             xy: [0; 2 * MAX_LIMBS],
1062         };
1063         consume_point_elem(ops.common, &mut p.xy, &elems, 0);
1064         consume_point_elem(ops.common, &mut p.xy, &elems, 1);
1065         p
1066     }
1067 
consume_point_elem(ops: &CommonOps, limbs_out: &mut [Limb], elems: &Vec<&str>, i: usize)1068     fn consume_point_elem(ops: &CommonOps, limbs_out: &mut [Limb], elems: &Vec<&str>, i: usize) {
1069         let bytes = test::from_hex(elems[i]).unwrap();
1070         let bytes = untrusted::Input::from(&bytes);
1071         let r: Elem<Unencoded> = elem_parse_big_endian_fixed_consttime(ops, bytes).unwrap();
1072         // XXX: “Transmute” this to `Elem<R>` limbs.
1073         limbs_out[(i * ops.num_limbs)..((i + 1) * ops.num_limbs)]
1074             .copy_from_slice(&r.limbs[..ops.num_limbs]);
1075     }
1076 
1077     enum TestPoint {
1078         Infinity,
1079         Affine(Elem<R>, Elem<R>),
1080     }
1081 
consume_point(ops: &PrivateKeyOps, test_case: &mut test::TestCase, name: &str) -> TestPoint1082     fn consume_point(ops: &PrivateKeyOps, test_case: &mut test::TestCase, name: &str) -> TestPoint {
1083         fn consume_point_elem(ops: &CommonOps, elems: &Vec<&str>, i: usize) -> Elem<R> {
1084             let bytes = test::from_hex(elems[i]).unwrap();
1085             let bytes = untrusted::Input::from(&bytes);
1086             let unencoded: Elem<Unencoded> =
1087                 elem_parse_big_endian_fixed_consttime(ops, bytes).unwrap();
1088             // XXX: “Transmute” this to `Elem<R>` limbs.
1089             Elem {
1090                 limbs: unencoded.limbs,
1091                 m: PhantomData,
1092                 encoding: PhantomData,
1093             }
1094         }
1095 
1096         let input = test_case.consume_string(name);
1097         if input == "inf" {
1098             return TestPoint::Infinity;
1099         }
1100         let elems = input.split(", ").collect::<Vec<&str>>();
1101         assert_eq!(elems.len(), 2);
1102         let x = consume_point_elem(ops.common, &elems, 0);
1103         let y = consume_point_elem(ops.common, &elems, 1);
1104         TestPoint::Affine(x, y)
1105     }
1106 
assert_elems_are_equal(ops: &CommonOps, a: &Elem<R>, b: &Elem<R>)1107     fn assert_elems_are_equal(ops: &CommonOps, a: &Elem<R>, b: &Elem<R>) {
1108         assert_limbs_are_equal(ops, &a.limbs, &b.limbs)
1109     }
1110 
assert_limbs_are_equal( ops: &CommonOps, actual: &[Limb; MAX_LIMBS], expected: &[Limb; MAX_LIMBS], )1111     fn assert_limbs_are_equal(
1112         ops: &CommonOps,
1113         actual: &[Limb; MAX_LIMBS],
1114         expected: &[Limb; MAX_LIMBS],
1115     ) {
1116         for i in 0..ops.num_limbs {
1117             if actual[i] != expected[i] {
1118                 let mut s = alloc::string::String::new();
1119                 for j in 0..ops.num_limbs {
1120                     let formatted = format!("{:016x}", actual[ops.num_limbs - j - 1]);
1121                     s.push_str(&formatted);
1122                 }
1123                 panic!("Actual != Expected,\nActual = {}", s);
1124             }
1125         }
1126     }
1127 
consume_elem(ops: &CommonOps, test_case: &mut test::TestCase, name: &str) -> Elem<R>1128     fn consume_elem(ops: &CommonOps, test_case: &mut test::TestCase, name: &str) -> Elem<R> {
1129         let bytes = consume_padded_bytes(ops, test_case, name);
1130         let bytes = untrusted::Input::from(&bytes);
1131         let r: Elem<Unencoded> = elem_parse_big_endian_fixed_consttime(ops, bytes).unwrap();
1132         // XXX: “Transmute” this to an `Elem<R>`.
1133         Elem {
1134             limbs: r.limbs,
1135             m: PhantomData,
1136             encoding: PhantomData,
1137         }
1138     }
1139 
consume_scalar(ops: &CommonOps, test_case: &mut test::TestCase, name: &str) -> Scalar1140     fn consume_scalar(ops: &CommonOps, test_case: &mut test::TestCase, name: &str) -> Scalar {
1141         let bytes = test_case.consume_bytes(name);
1142         let bytes = untrusted::Input::from(&bytes);
1143         scalar_parse_big_endian_variable(ops, AllowZero::Yes, bytes).unwrap()
1144     }
1145 
consume_scalar_mont( ops: &CommonOps, test_case: &mut test::TestCase, name: &str, ) -> Scalar<R>1146     fn consume_scalar_mont(
1147         ops: &CommonOps,
1148         test_case: &mut test::TestCase,
1149         name: &str,
1150     ) -> Scalar<R> {
1151         let bytes = test_case.consume_bytes(name);
1152         let bytes = untrusted::Input::from(&bytes);
1153         let s = scalar_parse_big_endian_variable(ops, AllowZero::Yes, bytes).unwrap();
1154         // “Transmute” it to a `Scalar<R>`.
1155         Scalar {
1156             limbs: s.limbs,
1157             m: PhantomData,
1158             encoding: PhantomData,
1159         }
1160     }
1161 
consume_padded_bytes( ops: &CommonOps, test_case: &mut test::TestCase, name: &str, ) -> Vec<u8>1162     fn consume_padded_bytes(
1163         ops: &CommonOps,
1164         test_case: &mut test::TestCase,
1165         name: &str,
1166     ) -> Vec<u8> {
1167         let unpadded_bytes = test_case.consume_bytes(name);
1168         let mut bytes = vec![0; (ops.num_limbs * LIMB_BYTES) - unpadded_bytes.len()];
1169         bytes.extend(&unpadded_bytes);
1170         bytes
1171     }
1172 }
1173 
1174 #[cfg(feature = "internal_benches")]
1175 mod internal_benches {
1176     use super::{Limb, MAX_LIMBS};
1177 
1178     pub const LIMBS_1: [Limb; MAX_LIMBS] = limbs![1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
1179 
1180     pub const LIMBS_ALTERNATING_10: [Limb; MAX_LIMBS] = limbs![
1181         0b10101010_10101010_10101010_10101010,
1182         0b10101010_10101010_10101010_10101010,
1183         0b10101010_10101010_10101010_10101010,
1184         0b10101010_10101010_10101010_10101010,
1185         0b10101010_10101010_10101010_10101010,
1186         0b10101010_10101010_10101010_10101010,
1187         0b10101010_10101010_10101010_10101010,
1188         0b10101010_10101010_10101010_10101010,
1189         0b10101010_10101010_10101010_10101010,
1190         0b10101010_10101010_10101010_10101010,
1191         0b10101010_10101010_10101010_10101010,
1192         0b10101010_10101010_10101010_10101010
1193     ];
1194 }
1195 
1196 #[cfg(feature = "internal_benches")]
1197 macro_rules! bench_curve {
1198     ( $vectors:expr ) => {
1199         use super::super::{Elem, Scalar};
1200         extern crate test;
1201 
1202         #[bench]
1203         fn elem_inverse_squared_bench(bench: &mut test::Bencher) {
1204             // This benchmark assumes that `elem_inverse_squared()` is
1205             // constant-time so inverting 1 mod q is as good of a choice as
1206             // anything.
1207             let mut a = Elem::zero();
1208             a.limbs[0] = 1;
1209             bench.iter(|| {
1210                 let _ = PRIVATE_KEY_OPS.elem_inverse_squared(&a);
1211             });
1212         }
1213 
1214         #[bench]
1215         fn elem_product_bench(bench: &mut test::Bencher) {
1216             // This benchmark assumes that the multiplication is constant-time
1217             // so 0 * 0 is as good of a choice as anything.
1218             let a: Elem<R> = Elem::zero();
1219             let b: Elem<R> = Elem::zero();
1220             bench.iter(|| {
1221                 let _ = COMMON_OPS.elem_product(&a, &b);
1222             });
1223         }
1224 
1225         #[bench]
1226         fn elem_squared_bench(bench: &mut test::Bencher) {
1227             // This benchmark assumes that the squaring is constant-time so
1228             // 0**2 * 0 is as good of a choice as anything.
1229             let a = Elem::zero();
1230             bench.iter(|| {
1231                 let _ = COMMON_OPS.elem_squared(&a);
1232             });
1233         }
1234 
1235         #[bench]
1236         fn scalar_inv_to_mont_bench(bench: &mut test::Bencher) {
1237             const VECTORS: &[Scalar] = $vectors;
1238             let vectors_len = VECTORS.len();
1239             let mut i = 0;
1240             bench.iter(|| {
1241                 let _ = SCALAR_OPS.scalar_inv_to_mont(&VECTORS[i]);
1242 
1243                 i += 1;
1244                 if i == vectors_len {
1245                     i = 0;
1246                 }
1247             });
1248         }
1249     };
1250 }
1251 
1252 mod elem;
1253 pub mod p256;
1254 pub mod p384;
1255