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