• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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     use super::*;
436     use crate::test;
437     use alloc::{format, vec, vec::Vec};
438 
439     const ZERO_SCALAR: Scalar = Scalar {
440         limbs: [0; MAX_LIMBS],
441         m: PhantomData,
442         encoding: PhantomData,
443     };
444 
q_minus_n_plus_n_equals_0_test(ops: &PublicScalarOps)445     fn q_minus_n_plus_n_equals_0_test(ops: &PublicScalarOps) {
446         let cops = ops.scalar_ops.common;
447         let mut x = ops.q_minus_n;
448         cops.elem_add(&mut x, &cops.n);
449         assert!(cops.is_zero(&x));
450     }
451 
452     #[test]
p256_q_minus_n_plus_n_equals_0_test()453     fn p256_q_minus_n_plus_n_equals_0_test() {
454         q_minus_n_plus_n_equals_0_test(&p256::PUBLIC_SCALAR_OPS);
455     }
456 
457     #[test]
p384_q_minus_n_plus_n_equals_0_test()458     fn p384_q_minus_n_plus_n_equals_0_test() {
459         q_minus_n_plus_n_equals_0_test(&p384::PUBLIC_SCALAR_OPS);
460     }
461 
462     #[test]
p256_elem_add_test()463     fn p256_elem_add_test() {
464         elem_add_test(
465             &p256::PUBLIC_SCALAR_OPS,
466             test_file!("ops/p256_elem_sum_tests.txt"),
467         );
468     }
469 
470     #[test]
p384_elem_add_test()471     fn p384_elem_add_test() {
472         elem_add_test(
473             &p384::PUBLIC_SCALAR_OPS,
474             test_file!("ops/p384_elem_sum_tests.txt"),
475         );
476     }
477 
elem_add_test(ops: &PublicScalarOps, test_file: test::File)478     fn elem_add_test(ops: &PublicScalarOps, test_file: test::File) {
479         test::run(test_file, |section, test_case| {
480             assert_eq!(section, "");
481 
482             let cops = ops.public_key_ops.common;
483             let a = consume_elem(cops, test_case, "a");
484             let b = consume_elem(cops, test_case, "b");
485             let expected_sum = consume_elem(cops, test_case, "r");
486 
487             let mut actual_sum = a;
488             ops.public_key_ops.common.elem_add(&mut actual_sum, &b);
489             assert_limbs_are_equal(cops, &actual_sum.limbs, &expected_sum.limbs);
490 
491             let mut actual_sum = b;
492             ops.public_key_ops.common.elem_add(&mut actual_sum, &a);
493             assert_limbs_are_equal(cops, &actual_sum.limbs, &expected_sum.limbs);
494 
495             Ok(())
496         })
497     }
498 
499     // XXX: There's no `p256_sub` in *ring*; it's logic is inlined into
500     // the point arithmetic functions. Thus, we can't test it.
501 
502     #[test]
p384_elem_sub_test()503     fn p384_elem_sub_test() {
504         prefixed_extern! {
505             fn p384_elem_sub(r: *mut Limb, a: *const Limb, b: *const Limb);
506         }
507         elem_sub_test(
508             &p384::COMMON_OPS,
509             p384_elem_sub,
510             test_file!("ops/p384_elem_sum_tests.txt"),
511         );
512     }
513 
elem_sub_test( ops: &CommonOps, elem_sub: unsafe extern "C" fn(r: *mut Limb, a: *const Limb, b: *const Limb), test_file: test::File, )514     fn elem_sub_test(
515         ops: &CommonOps,
516         elem_sub: unsafe extern "C" fn(r: *mut Limb, a: *const Limb, b: *const Limb),
517         test_file: test::File,
518     ) {
519         test::run(test_file, |section, test_case| {
520             assert_eq!(section, "");
521 
522             let a = consume_elem(ops, test_case, "a");
523             let b = consume_elem(ops, test_case, "b");
524             let r = consume_elem(ops, test_case, "r");
525 
526             let mut actual_difference = Elem::<R>::zero();
527             unsafe {
528                 elem_sub(
529                     actual_difference.limbs.as_mut_ptr(),
530                     r.limbs.as_ptr(),
531                     b.limbs.as_ptr(),
532                 );
533             }
534             assert_limbs_are_equal(ops, &actual_difference.limbs, &a.limbs);
535 
536             let mut actual_difference = Elem::<R>::zero();
537             unsafe {
538                 elem_sub(
539                     actual_difference.limbs.as_mut_ptr(),
540                     r.limbs.as_ptr(),
541                     a.limbs.as_ptr(),
542                 );
543             }
544             assert_limbs_are_equal(ops, &actual_difference.limbs, &b.limbs);
545 
546             Ok(())
547         })
548     }
549 
550     // XXX: There's no `p256_div_by_2` in *ring*; it's logic is inlined
551     // into the point arithmetic functions. Thus, we can't test it.
552 
553     #[test]
p384_elem_div_by_2_test()554     fn p384_elem_div_by_2_test() {
555         prefixed_extern! {
556             fn p384_elem_div_by_2(r: *mut Limb, a: *const Limb);
557         }
558         elem_div_by_2_test(
559             &p384::COMMON_OPS,
560             p384_elem_div_by_2,
561             test_file!("ops/p384_elem_div_by_2_tests.txt"),
562         );
563     }
564 
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, )565     fn elem_div_by_2_test(
566         ops: &CommonOps,
567         elem_div_by_2: unsafe extern "C" fn(r: *mut Limb, a: *const Limb),
568         test_file: test::File,
569     ) {
570         test::run(test_file, |section, test_case| {
571             assert_eq!(section, "");
572 
573             let a = consume_elem(ops, test_case, "a");
574             let r = consume_elem(ops, test_case, "r");
575 
576             let mut actual_result = Elem::<R>::zero();
577             unsafe {
578                 elem_div_by_2(actual_result.limbs.as_mut_ptr(), a.limbs.as_ptr());
579             }
580             assert_limbs_are_equal(ops, &actual_result.limbs, &r.limbs);
581 
582             Ok(())
583         })
584     }
585 
586     // There is no `nistz256_neg` on other targets.
587     #[cfg(target_arch = "x86_64")]
588     #[test]
p256_elem_neg_test()589     fn p256_elem_neg_test() {
590         prefixed_extern! {
591             fn nistz256_neg(r: *mut Limb, a: *const Limb);
592         }
593         elem_neg_test(
594             &p256::COMMON_OPS,
595             nistz256_neg,
596             test_file!("ops/p256_elem_neg_tests.txt"),
597         );
598     }
599 
600     #[test]
p384_elem_neg_test()601     fn p384_elem_neg_test() {
602         prefixed_extern! {
603             fn p384_elem_neg(r: *mut Limb, a: *const Limb);
604         }
605         elem_neg_test(
606             &p384::COMMON_OPS,
607             p384_elem_neg,
608             test_file!("ops/p384_elem_neg_tests.txt"),
609         );
610     }
611 
elem_neg_test( ops: &CommonOps, elem_neg: unsafe extern "C" fn(r: *mut Limb, a: *const Limb), test_file: test::File, )612     fn elem_neg_test(
613         ops: &CommonOps,
614         elem_neg: unsafe extern "C" fn(r: *mut Limb, a: *const Limb),
615         test_file: test::File,
616     ) {
617         test::run(test_file, |section, test_case| {
618             assert_eq!(section, "");
619 
620             let a = consume_elem(ops, test_case, "a");
621             let b = consume_elem(ops, test_case, "b");
622 
623             // Verify -a == b.
624             {
625                 let mut actual_result = Elem::<R>::zero();
626                 unsafe {
627                     elem_neg(actual_result.limbs.as_mut_ptr(), a.limbs.as_ptr());
628                 }
629                 assert_limbs_are_equal(ops, &actual_result.limbs, &b.limbs);
630             }
631 
632             // Verify -b == a.
633             {
634                 let mut actual_result = Elem::<R>::zero();
635                 unsafe {
636                     elem_neg(actual_result.limbs.as_mut_ptr(), b.limbs.as_ptr());
637                 }
638                 assert_limbs_are_equal(ops, &actual_result.limbs, &a.limbs);
639             }
640 
641             Ok(())
642         })
643     }
644 
645     #[test]
p256_elem_mul_test()646     fn p256_elem_mul_test() {
647         elem_mul_test(&p256::COMMON_OPS, test_file!("ops/p256_elem_mul_tests.txt"));
648     }
649 
650     #[test]
p384_elem_mul_test()651     fn p384_elem_mul_test() {
652         elem_mul_test(&p384::COMMON_OPS, test_file!("ops/p384_elem_mul_tests.txt"));
653     }
654 
elem_mul_test(ops: &CommonOps, test_file: test::File)655     fn elem_mul_test(ops: &CommonOps, test_file: test::File) {
656         test::run(test_file, |section, test_case| {
657             assert_eq!(section, "");
658 
659             let mut a = consume_elem(ops, test_case, "a");
660             let b = consume_elem(ops, test_case, "b");
661             let r = consume_elem(ops, test_case, "r");
662             ops.elem_mul(&mut a, &b);
663             assert_limbs_are_equal(ops, &a.limbs, &r.limbs);
664 
665             Ok(())
666         })
667     }
668 
669     #[test]
p256_scalar_mul_test()670     fn p256_scalar_mul_test() {
671         scalar_mul_test(
672             &p256::SCALAR_OPS,
673             test_file!("ops/p256_scalar_mul_tests.txt"),
674         );
675     }
676 
677     #[test]
p384_scalar_mul_test()678     fn p384_scalar_mul_test() {
679         scalar_mul_test(
680             &p384::SCALAR_OPS,
681             test_file!("ops/p384_scalar_mul_tests.txt"),
682         );
683     }
684 
scalar_mul_test(ops: &ScalarOps, test_file: test::File)685     fn scalar_mul_test(ops: &ScalarOps, test_file: test::File) {
686         test::run(test_file, |section, test_case| {
687             assert_eq!(section, "");
688             let cops = ops.common;
689             let a = consume_scalar(cops, test_case, "a");
690             let b = consume_scalar_mont(cops, test_case, "b");
691             let expected_result = consume_scalar(cops, test_case, "r");
692             let actual_result = ops.scalar_product(&a, &b);
693             assert_limbs_are_equal(cops, &actual_result.limbs, &expected_result.limbs);
694 
695             Ok(())
696         })
697     }
698 
699     #[test]
p256_scalar_square_test()700     fn p256_scalar_square_test() {
701         prefixed_extern! {
702             fn p256_scalar_sqr_rep_mont(r: *mut Limb, a: *const Limb, rep: Limb);
703         }
704         scalar_square_test(
705             &p256::SCALAR_OPS,
706             p256_scalar_sqr_rep_mont,
707             test_file!("ops/p256_scalar_square_tests.txt"),
708         );
709     }
710 
711     // XXX: There's no `p384_scalar_square_test()` because there's no dedicated
712     // `p384_scalar_sqr_rep_mont()`.
713 
scalar_square_test( ops: &ScalarOps, sqr_rep: unsafe extern "C" fn(r: *mut Limb, a: *const Limb, rep: Limb), test_file: test::File, )714     fn scalar_square_test(
715         ops: &ScalarOps,
716         sqr_rep: unsafe extern "C" fn(r: *mut Limb, a: *const Limb, rep: Limb),
717         test_file: test::File,
718     ) {
719         test::run(test_file, |section, test_case| {
720             assert_eq!(section, "");
721             let cops = &ops.common;
722             let a = consume_scalar(cops, test_case, "a");
723             let expected_result = consume_scalar(cops, test_case, "r");
724 
725             {
726                 let mut actual_result: Scalar<R> = Scalar {
727                     limbs: [0; MAX_LIMBS],
728                     m: PhantomData,
729                     encoding: PhantomData,
730                 };
731                 unsafe {
732                     sqr_rep(actual_result.limbs.as_mut_ptr(), a.limbs.as_ptr(), 1);
733                 }
734                 assert_limbs_are_equal(cops, &actual_result.limbs, &expected_result.limbs);
735             }
736 
737             {
738                 let actual_result = ops.scalar_product(&a, &a);
739                 assert_limbs_are_equal(cops, &actual_result.limbs, &expected_result.limbs);
740             }
741 
742             Ok(())
743         })
744     }
745 
746     #[test]
747     #[should_panic(expected = "!self.common.is_zero(a)")]
p256_scalar_inv_to_mont_zero_panic_test()748     fn p256_scalar_inv_to_mont_zero_panic_test() {
749         let _ = p256::SCALAR_OPS.scalar_inv_to_mont(&ZERO_SCALAR);
750     }
751 
752     #[test]
753     #[should_panic(expected = "!self.common.is_zero(a)")]
p384_scalar_inv_to_mont_zero_panic_test()754     fn p384_scalar_inv_to_mont_zero_panic_test() {
755         let _ = p384::SCALAR_OPS.scalar_inv_to_mont(&ZERO_SCALAR);
756     }
757 
758     #[test]
p256_point_sum_test()759     fn p256_point_sum_test() {
760         point_sum_test(
761             &p256::PRIVATE_KEY_OPS,
762             test_file!("ops/p256_point_sum_tests.txt"),
763         );
764     }
765 
766     #[test]
p384_point_sum_test()767     fn p384_point_sum_test() {
768         point_sum_test(
769             &p384::PRIVATE_KEY_OPS,
770             test_file!("ops/p384_point_sum_tests.txt"),
771         );
772     }
773 
point_sum_test(ops: &PrivateKeyOps, test_file: test::File)774     fn point_sum_test(ops: &PrivateKeyOps, test_file: test::File) {
775         test::run(test_file, |section, test_case| {
776             assert_eq!(section, "");
777 
778             let a = consume_jacobian_point(ops, test_case, "a");
779             let b = consume_jacobian_point(ops, test_case, "b");
780             let r_expected = consume_point(ops, test_case, "r");
781 
782             let r_actual = ops.common.point_sum(&a, &b);
783             assert_point_actual_equals_expected(ops, &r_actual, &r_expected);
784 
785             Ok(())
786         });
787     }
788 
789     #[test]
p256_point_sum_mixed_test()790     fn p256_point_sum_mixed_test() {
791         prefixed_extern! {
792             fn p256_point_add_affine(
793                 r: *mut Limb,   // [p256::COMMON_OPS.num_limbs*3]
794                 a: *const Limb, // [p256::COMMON_OPS.num_limbs*3]
795                 b: *const Limb, // [p256::COMMON_OPS.num_limbs*2]
796             );
797         }
798         point_sum_mixed_test(
799             &p256::PRIVATE_KEY_OPS,
800             p256_point_add_affine,
801             test_file!("ops/p256_point_sum_mixed_tests.txt"),
802         );
803     }
804 
805     // XXX: There is no `nistz384_point_add_affine()`.
806 
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, )807     fn point_sum_mixed_test(
808         ops: &PrivateKeyOps,
809         point_add_affine: unsafe extern "C" fn(
810             r: *mut Limb,   // [ops.num_limbs*3]
811             a: *const Limb, // [ops.num_limbs*3]
812             b: *const Limb, // [ops.num_limbs*2]
813         ),
814         test_file: test::File,
815     ) {
816         test::run(test_file, |section, test_case| {
817             assert_eq!(section, "");
818 
819             let a = consume_jacobian_point(ops, test_case, "a");
820             let b = consume_affine_point(ops, test_case, "b");
821             let r_expected = consume_point(ops, test_case, "r");
822 
823             let mut r_actual = Point::new_at_infinity();
824             unsafe {
825                 point_add_affine(r_actual.xyz.as_mut_ptr(), a.xyz.as_ptr(), b.xy.as_ptr());
826             }
827 
828             assert_point_actual_equals_expected(ops, &r_actual, &r_expected);
829 
830             Ok(())
831         });
832     }
833 
834     #[test]
p256_point_double_test()835     fn p256_point_double_test() {
836         prefixed_extern! {
837             fn p256_point_double(
838                 r: *mut Limb,   // [p256::COMMON_OPS.num_limbs*3]
839                 a: *const Limb, // [p256::COMMON_OPS.num_limbs*3]
840             );
841         }
842         point_double_test(
843             &p256::PRIVATE_KEY_OPS,
844             p256_point_double,
845             test_file!("ops/p256_point_double_tests.txt"),
846         );
847     }
848 
849     #[test]
p384_point_double_test()850     fn p384_point_double_test() {
851         prefixed_extern! {
852             fn nistz384_point_double(
853                 r: *mut Limb,   // [p384::COMMON_OPS.num_limbs*3]
854                 a: *const Limb, // [p384::COMMON_OPS.num_limbs*3]
855             );
856         }
857         point_double_test(
858             &p384::PRIVATE_KEY_OPS,
859             nistz384_point_double,
860             test_file!("ops/p384_point_double_tests.txt"),
861         );
862     }
863 
point_double_test( ops: &PrivateKeyOps, point_double: unsafe extern "C" fn( r: *mut Limb, a: *const Limb, ), test_file: test::File, )864     fn point_double_test(
865         ops: &PrivateKeyOps,
866         point_double: unsafe extern "C" fn(
867             r: *mut Limb,   // [ops.num_limbs*3]
868             a: *const Limb, // [ops.num_limbs*3]
869         ),
870         test_file: test::File,
871     ) {
872         test::run(test_file, |section, test_case| {
873             assert_eq!(section, "");
874 
875             let a = consume_jacobian_point(ops, test_case, "a");
876             let r_expected = consume_point(ops, test_case, "r");
877 
878             let mut r_actual = Point::new_at_infinity();
879             unsafe {
880                 point_double(r_actual.xyz.as_mut_ptr(), a.xyz.as_ptr());
881             }
882 
883             assert_point_actual_equals_expected(ops, &r_actual, &r_expected);
884 
885             Ok(())
886         });
887     }
888 
889     #[test]
p256_point_mul_test()890     fn p256_point_mul_test() {
891         point_mul_tests(
892             &p256::PRIVATE_KEY_OPS,
893             test_file!("ops/p256_point_mul_tests.txt"),
894         );
895     }
896 
897     #[test]
p384_point_mul_test()898     fn p384_point_mul_test() {
899         point_mul_tests(
900             &p384::PRIVATE_KEY_OPS,
901             test_file!("ops/p384_point_mul_tests.txt"),
902         );
903     }
904 
point_mul_tests(ops: &PrivateKeyOps, test_file: test::File)905     fn point_mul_tests(ops: &PrivateKeyOps, test_file: test::File) {
906         test::run(test_file, |section, test_case| {
907             assert_eq!(section, "");
908             let p_scalar = consume_scalar(ops.common, test_case, "p_scalar");
909             let (x, y) = match consume_point(ops, test_case, "p") {
910                 TestPoint::Infinity => {
911                     panic!("can't be inf.");
912                 }
913                 TestPoint::Affine(x, y) => (x, y),
914             };
915             let expected_result = consume_point(ops, test_case, "r");
916             let actual_result = ops.point_mul(&p_scalar, &(x, y));
917             assert_point_actual_equals_expected(ops, &actual_result, &expected_result);
918             Ok(())
919         })
920     }
921 
922     #[test]
p256_point_mul_serialized_test()923     fn p256_point_mul_serialized_test() {
924         point_mul_serialized_test(
925             &p256::PRIVATE_KEY_OPS,
926             &p256::PUBLIC_KEY_OPS,
927             test_file!("ops/p256_point_mul_serialized_tests.txt"),
928         );
929     }
930 
point_mul_serialized_test( priv_ops: &PrivateKeyOps, pub_ops: &PublicKeyOps, test_file: test::File, )931     fn point_mul_serialized_test(
932         priv_ops: &PrivateKeyOps,
933         pub_ops: &PublicKeyOps,
934         test_file: test::File,
935     ) {
936         let cops = pub_ops.common;
937 
938         test::run(test_file, |section, test_case| {
939             assert_eq!(section, "");
940             let p_scalar = consume_scalar(cops, test_case, "p_scalar");
941 
942             let p = test_case.consume_bytes("p");
943             let p = super::super::public_key::parse_uncompressed_point(
944                 pub_ops,
945                 untrusted::Input::from(&p),
946             )
947             .expect("valid point");
948 
949             let expected_result = test_case.consume_bytes("r");
950 
951             let product = priv_ops.point_mul(&p_scalar, &p);
952 
953             let mut actual_result = vec![4u8; 1 + (2 * (cops.num_limbs * LIMB_BYTES))];
954             {
955                 let (x, y) = actual_result[1..].split_at_mut(cops.num_limbs * LIMB_BYTES);
956                 super::super::private_key::big_endian_affine_from_jacobian(
957                     priv_ops,
958                     Some(x),
959                     Some(y),
960                     &product,
961                 )
962                 .expect("successful encoding");
963             }
964 
965             assert_eq!(expected_result, actual_result);
966 
967             Ok(())
968         })
969     }
970 
971     #[test]
p256_point_mul_base_test()972     fn p256_point_mul_base_test() {
973         point_mul_base_tests(
974             &p256::PRIVATE_KEY_OPS,
975             test_file!("ops/p256_point_mul_base_tests.txt"),
976         );
977     }
978 
979     #[test]
p384_point_mul_base_test()980     fn p384_point_mul_base_test() {
981         point_mul_base_tests(
982             &p384::PRIVATE_KEY_OPS,
983             test_file!("ops/p384_point_mul_base_tests.txt"),
984         );
985     }
986 
point_mul_base_tests(ops: &PrivateKeyOps, test_file: test::File)987     fn point_mul_base_tests(ops: &PrivateKeyOps, test_file: test::File) {
988         test::run(test_file, |section, test_case| {
989             assert_eq!(section, "");
990             let g_scalar = consume_scalar(ops.common, test_case, "g_scalar");
991             let expected_result = consume_point(ops, test_case, "r");
992             let actual_result = ops.point_mul_base(&g_scalar);
993             assert_point_actual_equals_expected(ops, &actual_result, &expected_result);
994             Ok(())
995         })
996     }
997 
assert_point_actual_equals_expected( ops: &PrivateKeyOps, actual_point: &Point, expected_point: &TestPoint, )998     fn assert_point_actual_equals_expected(
999         ops: &PrivateKeyOps,
1000         actual_point: &Point,
1001         expected_point: &TestPoint,
1002     ) {
1003         let cops = ops.common;
1004         let actual_x = &cops.point_x(&actual_point);
1005         let actual_y = &cops.point_y(&actual_point);
1006         let actual_z = &cops.point_z(&actual_point);
1007         match expected_point {
1008             TestPoint::Infinity => {
1009                 let zero = Elem::zero();
1010                 assert_elems_are_equal(cops, &actual_z, &zero);
1011             }
1012             TestPoint::Affine(expected_x, expected_y) => {
1013                 let zz_inv = ops.elem_inverse_squared(&actual_z);
1014                 let x_aff = cops.elem_product(&actual_x, &zz_inv);
1015                 let y_aff = {
1016                     let zzzz_inv = cops.elem_squared(&zz_inv);
1017                     let zzz_inv = cops.elem_product(&actual_z, &zzzz_inv);
1018                     cops.elem_product(&actual_y, &zzz_inv)
1019                 };
1020 
1021                 assert_elems_are_equal(cops, &x_aff, &expected_x);
1022                 assert_elems_are_equal(cops, &y_aff, &expected_y);
1023             }
1024         }
1025     }
1026 
consume_jacobian_point( ops: &PrivateKeyOps, test_case: &mut test::TestCase, name: &str, ) -> Point1027     fn consume_jacobian_point(
1028         ops: &PrivateKeyOps,
1029         test_case: &mut test::TestCase,
1030         name: &str,
1031     ) -> Point {
1032         let input = test_case.consume_string(name);
1033         let elems = input.split(", ").collect::<Vec<&str>>();
1034         assert_eq!(elems.len(), 3);
1035         let mut p = Point::new_at_infinity();
1036         consume_point_elem(ops.common, &mut p.xyz, &elems, 0);
1037         consume_point_elem(ops.common, &mut p.xyz, &elems, 1);
1038         consume_point_elem(ops.common, &mut p.xyz, &elems, 2);
1039         p
1040     }
1041 
1042     struct AffinePoint {
1043         xy: [Limb; 2 * MAX_LIMBS],
1044     }
1045 
consume_affine_point( ops: &PrivateKeyOps, test_case: &mut test::TestCase, name: &str, ) -> AffinePoint1046     fn consume_affine_point(
1047         ops: &PrivateKeyOps,
1048         test_case: &mut test::TestCase,
1049         name: &str,
1050     ) -> AffinePoint {
1051         let input = test_case.consume_string(name);
1052         let elems = input.split(", ").collect::<Vec<&str>>();
1053         assert_eq!(elems.len(), 2);
1054         let mut p = AffinePoint {
1055             xy: [0; 2 * MAX_LIMBS],
1056         };
1057         consume_point_elem(ops.common, &mut p.xy, &elems, 0);
1058         consume_point_elem(ops.common, &mut p.xy, &elems, 1);
1059         p
1060     }
1061 
consume_point_elem(ops: &CommonOps, limbs_out: &mut [Limb], elems: &[&str], i: usize)1062     fn consume_point_elem(ops: &CommonOps, limbs_out: &mut [Limb], elems: &[&str], i: usize) {
1063         let bytes = test::from_hex(elems[i]).unwrap();
1064         let bytes = untrusted::Input::from(&bytes);
1065         let r: Elem<Unencoded> = elem_parse_big_endian_fixed_consttime(ops, bytes).unwrap();
1066         // XXX: “Transmute” this to `Elem<R>` limbs.
1067         limbs_out[(i * ops.num_limbs)..((i + 1) * ops.num_limbs)]
1068             .copy_from_slice(&r.limbs[..ops.num_limbs]);
1069     }
1070 
1071     enum TestPoint {
1072         Infinity,
1073         Affine(Elem<R>, Elem<R>),
1074     }
1075 
consume_point(ops: &PrivateKeyOps, test_case: &mut test::TestCase, name: &str) -> TestPoint1076     fn consume_point(ops: &PrivateKeyOps, test_case: &mut test::TestCase, name: &str) -> TestPoint {
1077         fn consume_point_elem(ops: &CommonOps, elems: &[&str], i: usize) -> Elem<R> {
1078             let bytes = test::from_hex(elems[i]).unwrap();
1079             let bytes = untrusted::Input::from(&bytes);
1080             let unencoded: Elem<Unencoded> =
1081                 elem_parse_big_endian_fixed_consttime(ops, bytes).unwrap();
1082             // XXX: “Transmute” this to `Elem<R>` limbs.
1083             Elem {
1084                 limbs: unencoded.limbs,
1085                 m: PhantomData,
1086                 encoding: PhantomData,
1087             }
1088         }
1089 
1090         let input = test_case.consume_string(name);
1091         if input == "inf" {
1092             return TestPoint::Infinity;
1093         }
1094         let elems = input.split(", ").collect::<Vec<&str>>();
1095         assert_eq!(elems.len(), 2);
1096         let x = consume_point_elem(ops.common, &elems, 0);
1097         let y = consume_point_elem(ops.common, &elems, 1);
1098         TestPoint::Affine(x, y)
1099     }
1100 
assert_elems_are_equal(ops: &CommonOps, a: &Elem<R>, b: &Elem<R>)1101     fn assert_elems_are_equal(ops: &CommonOps, a: &Elem<R>, b: &Elem<R>) {
1102         assert_limbs_are_equal(ops, &a.limbs, &b.limbs)
1103     }
1104 
assert_limbs_are_equal( ops: &CommonOps, actual: &[Limb; MAX_LIMBS], expected: &[Limb; MAX_LIMBS], )1105     fn assert_limbs_are_equal(
1106         ops: &CommonOps,
1107         actual: &[Limb; MAX_LIMBS],
1108         expected: &[Limb; MAX_LIMBS],
1109     ) {
1110         if actual[..ops.num_limbs] != expected[..ops.num_limbs] {
1111             let mut actual_s = alloc::string::String::new();
1112             let mut expected_s = alloc::string::String::new();
1113             for j in 0..ops.num_limbs {
1114                 let formatted = format!("{:016x}", actual[ops.num_limbs - j - 1]);
1115                 actual_s.push_str(&formatted);
1116                 let formatted = format!("{:016x}", expected[ops.num_limbs - j - 1]);
1117                 expected_s.push_str(&formatted);
1118             }
1119             panic!(
1120                 "Actual != Expected,\nActual = {}, Expected = {}",
1121                 actual_s, expected_s
1122             );
1123         }
1124     }
1125 
consume_elem(ops: &CommonOps, test_case: &mut test::TestCase, name: &str) -> Elem<R>1126     fn consume_elem(ops: &CommonOps, test_case: &mut test::TestCase, name: &str) -> Elem<R> {
1127         let bytes = consume_padded_bytes(ops, test_case, name);
1128         let bytes = untrusted::Input::from(&bytes);
1129         let r: Elem<Unencoded> = elem_parse_big_endian_fixed_consttime(ops, bytes).unwrap();
1130         // XXX: “Transmute” this to an `Elem<R>`.
1131         Elem {
1132             limbs: r.limbs,
1133             m: PhantomData,
1134             encoding: PhantomData,
1135         }
1136     }
1137 
consume_scalar(ops: &CommonOps, test_case: &mut test::TestCase, name: &str) -> Scalar1138     fn consume_scalar(ops: &CommonOps, test_case: &mut test::TestCase, name: &str) -> Scalar {
1139         let bytes = test_case.consume_bytes(name);
1140         let bytes = untrusted::Input::from(&bytes);
1141         scalar_parse_big_endian_variable(ops, AllowZero::Yes, bytes).unwrap()
1142     }
1143 
consume_scalar_mont( ops: &CommonOps, test_case: &mut test::TestCase, name: &str, ) -> Scalar<R>1144     fn consume_scalar_mont(
1145         ops: &CommonOps,
1146         test_case: &mut test::TestCase,
1147         name: &str,
1148     ) -> Scalar<R> {
1149         let bytes = test_case.consume_bytes(name);
1150         let bytes = untrusted::Input::from(&bytes);
1151         let s = scalar_parse_big_endian_variable(ops, AllowZero::Yes, bytes).unwrap();
1152         // “Transmute” it to a `Scalar<R>`.
1153         Scalar {
1154             limbs: s.limbs,
1155             m: PhantomData,
1156             encoding: PhantomData,
1157         }
1158     }
1159 
consume_padded_bytes( ops: &CommonOps, test_case: &mut test::TestCase, name: &str, ) -> Vec<u8>1160     fn consume_padded_bytes(
1161         ops: &CommonOps,
1162         test_case: &mut test::TestCase,
1163         name: &str,
1164     ) -> Vec<u8> {
1165         let unpadded_bytes = test_case.consume_bytes(name);
1166         let mut bytes = vec![0; (ops.num_limbs * LIMB_BYTES) - unpadded_bytes.len()];
1167         bytes.extend(&unpadded_bytes);
1168         bytes
1169     }
1170 }
1171 
1172 mod elem;
1173 pub mod p256;
1174 pub mod p384;
1175