1 // -*- mode: rust; -*-
2 //
3 // This file is part of curve25519-dalek.
4 // Copyright (c) 2016-2021 isis agora lovecruft
5 // Copyright (c) 2016-2019 Henry de Valence
6 // See LICENSE for licensing information.
7 //
8 // Authors:
9 // - Isis Agora Lovecruft <isis@patternsinthevoid.net>
10 // - Henry de Valence <hdevalence@hdevalence.ca>
11 
12 //! Field arithmetic modulo \\(p = 2\^{255} - 19\\).
13 //!
14 //! The `curve25519_dalek::field` module provides a type alias
15 //! `curve25519_dalek::field::FieldElement` to a field element type
16 //! defined in the `backend` module; either `FieldElement51` or
17 //! `FieldElement2625`.
18 //!
19 //! Field operations defined in terms of machine
20 //! operations, such as field multiplication or squaring, are defined in
21 //! the backend implementation.
22 //!
23 //! Field operations defined in terms of other field operations, such as
24 //! field inversion or square roots, are defined here.
25 
26 use core::cmp::{Eq, PartialEq};
27 
28 use subtle::ConditionallySelectable;
29 use subtle::ConditionallyNegatable;
30 use subtle::Choice;
31 use subtle::ConstantTimeEq;
32 
33 use constants;
34 use backend;
35 
36 #[cfg(feature = "fiat_u32_backend")]
37 pub use backend::serial::fiat_u32::field::*;
38 #[cfg(feature = "fiat_u64_backend")]
39 pub use backend::serial::fiat_u64::field::*;
40 /// A `FieldElement` represents an element of the field
41 /// \\( \mathbb Z / (2\^{255} - 19)\\).
42 ///
43 /// The `FieldElement` type is an alias for one of the platform-specific
44 /// implementations.
45 /// Using formally-verified field arithmetic from fiat-crypto
46 #[cfg(feature = "fiat_u32_backend")]
47 pub type FieldElement = backend::serial::fiat_u32::field::FieldElement2625;
48 #[cfg(feature = "fiat_u64_backend")]
49 pub type FieldElement = backend::serial::fiat_u64::field::FieldElement51;
50 
51 #[cfg(feature = "u64_backend")]
52 pub use backend::serial::u64::field::*;
53 /// A `FieldElement` represents an element of the field
54 /// \\( \mathbb Z / (2\^{255} - 19)\\).
55 ///
56 /// The `FieldElement` type is an alias for one of the platform-specific
57 /// implementations.
58 #[cfg(feature = "u64_backend")]
59 pub type FieldElement = backend::serial::u64::field::FieldElement51;
60 
61 #[cfg(feature = "u32_backend")]
62 pub use backend::serial::u32::field::*;
63 /// A `FieldElement` represents an element of the field
64 /// \\( \mathbb Z / (2\^{255} - 19)\\).
65 ///
66 /// The `FieldElement` type is an alias for one of the platform-specific
67 /// implementations.
68 #[cfg(feature = "u32_backend")]
69 pub type FieldElement = backend::serial::u32::field::FieldElement2625;
70 
71 impl Eq for FieldElement {}
72 
73 impl PartialEq for FieldElement {
eq(&self, other: &FieldElement) -> bool74     fn eq(&self, other: &FieldElement) -> bool {
75         self.ct_eq(other).unwrap_u8() == 1u8
76     }
77 }
78 
79 impl ConstantTimeEq for FieldElement {
80     /// Test equality between two `FieldElement`s.  Since the
81     /// internal representation is not canonical, the field elements
82     /// are normalized to wire format before comparison.
ct_eq(&self, other: &FieldElement) -> Choice83     fn ct_eq(&self, other: &FieldElement) -> Choice {
84         self.to_bytes().ct_eq(&other.to_bytes())
85     }
86 }
87 
88 impl FieldElement {
89     /// Determine if this `FieldElement` is negative, in the sense
90     /// used in the ed25519 paper: `x` is negative if the low bit is
91     /// set.
92     ///
93     /// # Return
94     ///
95     /// If negative, return `Choice(1)`.  Otherwise, return `Choice(0)`.
is_negative(&self) -> Choice96     pub fn is_negative(&self) -> Choice {
97         let bytes = self.to_bytes();
98         (bytes[0] & 1).into()
99     }
100 
101     /// Determine if this `FieldElement` is zero.
102     ///
103     /// # Return
104     ///
105     /// If zero, return `Choice(1)`.  Otherwise, return `Choice(0)`.
is_zero(&self) -> Choice106     pub fn is_zero(&self) -> Choice {
107         let zero = [0u8; 32];
108         let bytes = self.to_bytes();
109 
110         bytes.ct_eq(&zero)
111     }
112 
113     /// Compute (self^(2^250-1), self^11), used as a helper function
114     /// within invert() and pow22523().
pow22501(&self) -> (FieldElement, FieldElement)115     fn pow22501(&self) -> (FieldElement, FieldElement) {
116         // Instead of managing which temporary variables are used
117         // for what, we define as many as we need and leave stack
118         // allocation to the compiler
119         //
120         // Each temporary variable t_i is of the form (self)^e_i.
121         // Squaring t_i corresponds to multiplying e_i by 2,
122         // so the pow2k function shifts e_i left by k places.
123         // Multiplying t_i and t_j corresponds to adding e_i + e_j.
124         //
125         // Temporary t_i                      Nonzero bits of e_i
126         //
127         let t0  = self.square();           // 1         e_0 = 2^1
128         let t1  = t0.square().square();    // 3         e_1 = 2^3
129         let t2  = self * &t1;              // 3,0       e_2 = 2^3 + 2^0
130         let t3  = &t0 * &t2;               // 3,1,0
131         let t4  = t3.square();             // 4,2,1
132         let t5  = &t2 * &t4;               // 4,3,2,1,0
133         let t6  = t5.pow2k(5);             // 9,8,7,6,5
134         let t7  = &t6 * &t5;               // 9,8,7,6,5,4,3,2,1,0
135         let t8  = t7.pow2k(10);            // 19..10
136         let t9  = &t8 * &t7;               // 19..0
137         let t10 = t9.pow2k(20);            // 39..20
138         let t11 = &t10 * &t9;              // 39..0
139         let t12 = t11.pow2k(10);           // 49..10
140         let t13 = &t12 * &t7;              // 49..0
141         let t14 = t13.pow2k(50);           // 99..50
142         let t15 = &t14 * &t13;             // 99..0
143         let t16 = t15.pow2k(100);          // 199..100
144         let t17 = &t16 * &t15;             // 199..0
145         let t18 = t17.pow2k(50);           // 249..50
146         let t19 = &t18 * &t13;             // 249..0
147 
148         (t19, t3)
149     }
150 
151     /// Given a slice of public `FieldElements`, replace each with its inverse.
152     ///
153     /// All input `FieldElements` **MUST** be nonzero.
154     #[cfg(feature = "alloc")]
batch_invert(inputs: &mut [FieldElement])155     pub fn batch_invert(inputs: &mut [FieldElement]) {
156         // Montgomery’s Trick and Fast Implementation of Masked AES
157         // Genelle, Prouff and Quisquater
158         // Section 3.2
159 
160         let n = inputs.len();
161         let mut scratch = vec![FieldElement::one(); n];
162 
163         // Keep an accumulator of all of the previous products
164         let mut acc = FieldElement::one();
165 
166         // Pass through the input vector, recording the previous
167         // products in the scratch space
168         for (input, scratch) in inputs.iter().zip(scratch.iter_mut()) {
169             *scratch = acc;
170             acc = &acc * input;
171         }
172 
173 	// acc is nonzero iff all inputs are nonzero
174         assert_eq!(acc.is_zero().unwrap_u8(), 0);
175 
176         // Compute the inverse of all products
177         acc = acc.invert();
178 
179         // Pass through the vector backwards to compute the inverses
180         // in place
181         for (input, scratch) in inputs.iter_mut().rev().zip(scratch.into_iter().rev()) {
182             let tmp = &acc * input;
183             *input = &acc * &scratch;
184             acc = tmp;
185         }
186     }
187 
188     /// Given a nonzero field element, compute its inverse.
189     ///
190     /// The inverse is computed as self^(p-2), since
191     /// x^(p-2)x = x^(p-1) = 1 (mod p).
192     ///
193     /// This function returns zero on input zero.
invert(&self) -> FieldElement194     pub fn invert(&self) -> FieldElement {
195         // The bits of p-2 = 2^255 -19 -2 are 11010111111...11.
196         //
197         //                                 nonzero bits of exponent
198         let (t19, t3) = self.pow22501();   // t19: 249..0 ; t3: 3,1,0
199         let t20 = t19.pow2k(5);            // 254..5
200         let t21 = &t20 * &t3;              // 254..5,3,1,0
201 
202         t21
203     }
204 
205     /// Raise this field element to the power (p-5)/8 = 2^252 -3.
pow_p58(&self) -> FieldElement206     fn pow_p58(&self) -> FieldElement {
207         // The bits of (p-5)/8 are 101111.....11.
208         //
209         //                                 nonzero bits of exponent
210         let (t19, _) = self.pow22501();    // 249..0
211         let t20 = t19.pow2k(2);            // 251..2
212         let t21 = self * &t20;             // 251..2,0
213 
214         t21
215     }
216 
217     /// Given `FieldElements` `u` and `v`, compute either `sqrt(u/v)`
218     /// or `sqrt(i*u/v)` in constant time.
219     ///
220     /// This function always returns the nonnegative square root.
221     ///
222     /// # Return
223     ///
224     /// - `(Choice(1), +sqrt(u/v))  ` if `v` is nonzero and `u/v` is square;
225     /// - `(Choice(1), zero)        ` if `u` is zero;
226     /// - `(Choice(0), zero)        ` if `v` is zero and `u` is nonzero;
227     /// - `(Choice(0), +sqrt(i*u/v))` if `u/v` is nonsquare (so `i*u/v` is square).
228     ///
sqrt_ratio_i(u: &FieldElement, v: &FieldElement) -> (Choice, FieldElement)229     pub fn sqrt_ratio_i(u: &FieldElement, v: &FieldElement) -> (Choice, FieldElement) {
230         // Using the same trick as in ed25519 decoding, we merge the
231         // inversion, the square root, and the square test as follows.
232         //
233         // To compute sqrt(α), we can compute β = α^((p+3)/8).
234         // Then β^2 = ±α, so multiplying β by sqrt(-1) if necessary
235         // gives sqrt(α).
236         //
237         // To compute 1/sqrt(α), we observe that
238         //    1/β = α^(p-1 - (p+3)/8) = α^((7p-11)/8)
239         //                            = α^3 * (α^7)^((p-5)/8).
240         //
241         // We can therefore compute sqrt(u/v) = sqrt(u)/sqrt(v)
242         // by first computing
243         //    r = u^((p+3)/8) v^(p-1-(p+3)/8)
244         //      = u u^((p-5)/8) v^3 (v^7)^((p-5)/8)
245         //      = (uv^3) (uv^7)^((p-5)/8).
246         //
247         // If v is nonzero and u/v is square, then r^2 = ±u/v,
248         //                                     so vr^2 = ±u.
249         // If vr^2 =  u, then sqrt(u/v) = r.
250         // If vr^2 = -u, then sqrt(u/v) = r*sqrt(-1).
251         //
252         // If v is zero, r is also zero.
253 
254         let v3 = &v.square()  * v;
255         let v7 = &v3.square() * v;
256         let mut r = &(u * &v3) * &(u * &v7).pow_p58();
257         let check = v * &r.square();
258 
259         let i = &constants::SQRT_M1;
260 
261         let correct_sign_sqrt   = check.ct_eq(        u);
262         let flipped_sign_sqrt   = check.ct_eq(     &(-u));
263         let flipped_sign_sqrt_i = check.ct_eq(&(&(-u)*i));
264 
265         let r_prime = &constants::SQRT_M1 * &r;
266         r.conditional_assign(&r_prime, flipped_sign_sqrt | flipped_sign_sqrt_i);
267 
268         // Choose the nonnegative square root.
269         let r_is_negative = r.is_negative();
270         r.conditional_negate(r_is_negative);
271 
272         let was_nonzero_square = correct_sign_sqrt | flipped_sign_sqrt;
273 
274         (was_nonzero_square, r)
275     }
276 
277     /// Attempt to compute `sqrt(1/self)` in constant time.
278     ///
279     /// Convenience wrapper around `sqrt_ratio_i`.
280     ///
281     /// This function always returns the nonnegative square root.
282     ///
283     /// # Return
284     ///
285     /// - `(Choice(1), +sqrt(1/self))  ` if `self` is a nonzero square;
286     /// - `(Choice(0), zero)           ` if `self` is zero;
287     /// - `(Choice(0), +sqrt(i/self))  ` if `self` is a nonzero nonsquare;
288     ///
invsqrt(&self) -> (Choice, FieldElement)289     pub fn invsqrt(&self) -> (Choice, FieldElement) {
290         FieldElement::sqrt_ratio_i(&FieldElement::one(), self)
291     }
292 }
293 
294 #[cfg(test)]
295 mod test {
296     use field::*;
297     use subtle::ConditionallyNegatable;
298 
299     /// Random element a of GF(2^255-19), from Sage
300     /// a = 1070314506888354081329385823235218444233221\
301     ///     2228051251926706380353716438957572
302     static A_BYTES: [u8; 32] =
303         [ 0x04, 0xfe, 0xdf, 0x98, 0xa7, 0xfa, 0x0a, 0x68,
304           0x84, 0x92, 0xbd, 0x59, 0x08, 0x07, 0xa7, 0x03,
305           0x9e, 0xd1, 0xf6, 0xf2, 0xe1, 0xd9, 0xe2, 0xa4,
306           0xa4, 0x51, 0x47, 0x36, 0xf3, 0xc3, 0xa9, 0x17];
307 
308     /// Byte representation of a**2
309     static ASQ_BYTES: [u8; 32] =
310         [ 0x75, 0x97, 0x24, 0x9e, 0xe6, 0x06, 0xfe, 0xab,
311           0x24, 0x04, 0x56, 0x68, 0x07, 0x91, 0x2d, 0x5d,
312           0x0b, 0x0f, 0x3f, 0x1c, 0xb2, 0x6e, 0xf2, 0xe2,
313           0x63, 0x9c, 0x12, 0xba, 0x73, 0x0b, 0xe3, 0x62];
314 
315     /// Byte representation of 1/a
316     static AINV_BYTES: [u8; 32] =
317         [0x96, 0x1b, 0xcd, 0x8d, 0x4d, 0x5e, 0xa2, 0x3a,
318          0xe9, 0x36, 0x37, 0x93, 0xdb, 0x7b, 0x4d, 0x70,
319          0xb8, 0x0d, 0xc0, 0x55, 0xd0, 0x4c, 0x1d, 0x7b,
320          0x90, 0x71, 0xd8, 0xe9, 0xb6, 0x18, 0xe6, 0x30];
321 
322     /// Byte representation of a^((p-5)/8)
323     static AP58_BYTES: [u8; 32] =
324         [0x6a, 0x4f, 0x24, 0x89, 0x1f, 0x57, 0x60, 0x36,
325          0xd0, 0xbe, 0x12, 0x3c, 0x8f, 0xf5, 0xb1, 0x59,
326          0xe0, 0xf0, 0xb8, 0x1b, 0x20, 0xd2, 0xb5, 0x1f,
327          0x15, 0x21, 0xf9, 0xe3, 0xe1, 0x61, 0x21, 0x55];
328 
329     #[test]
a_mul_a_vs_a_squared_constant()330     fn a_mul_a_vs_a_squared_constant() {
331         let a = FieldElement::from_bytes(&A_BYTES);
332         let asq = FieldElement::from_bytes(&ASQ_BYTES);
333         assert_eq!(asq, &a * &a);
334     }
335 
336     #[test]
a_square_vs_a_squared_constant()337     fn a_square_vs_a_squared_constant() {
338         let a = FieldElement::from_bytes(&A_BYTES);
339         let asq = FieldElement::from_bytes(&ASQ_BYTES);
340         assert_eq!(asq, a.square());
341     }
342 
343     #[test]
a_square2_vs_a_squared_constant()344     fn a_square2_vs_a_squared_constant() {
345         let a = FieldElement::from_bytes(&A_BYTES);
346         let asq = FieldElement::from_bytes(&ASQ_BYTES);
347         assert_eq!(a.square2(), &asq+&asq);
348     }
349 
350     #[test]
a_invert_vs_inverse_of_a_constant()351     fn a_invert_vs_inverse_of_a_constant() {
352         let a    = FieldElement::from_bytes(&A_BYTES);
353         let ainv = FieldElement::from_bytes(&AINV_BYTES);
354         let should_be_inverse = a.invert();
355         assert_eq!(ainv, should_be_inverse);
356         assert_eq!(FieldElement::one(), &a * &should_be_inverse);
357     }
358 
359     #[test]
batch_invert_a_matches_nonbatched()360     fn batch_invert_a_matches_nonbatched() {
361         let a    = FieldElement::from_bytes(&A_BYTES);
362         let ap58 = FieldElement::from_bytes(&AP58_BYTES);
363         let asq  = FieldElement::from_bytes(&ASQ_BYTES);
364         let ainv = FieldElement::from_bytes(&AINV_BYTES);
365         let a2   = &a + &a;
366         let a_list = vec![a, ap58, asq, ainv, a2];
367         let mut ainv_list = a_list.clone();
368         FieldElement::batch_invert(&mut ainv_list[..]);
369         for i in 0..5 {
370             assert_eq!(a_list[i].invert(), ainv_list[i]);
371         }
372     }
373 
374     #[test]
sqrt_ratio_behavior()375     fn sqrt_ratio_behavior() {
376         let zero = FieldElement::zero();
377         let one = FieldElement::one();
378         let i = constants::SQRT_M1;
379         let two = &one + &one; // 2 is nonsquare mod p.
380         let four = &two + &two; // 4 is square mod p.
381 
382         // 0/0 should return (1, 0) since u is 0
383         let (choice, sqrt) = FieldElement::sqrt_ratio_i(&zero, &zero);
384         assert_eq!(choice.unwrap_u8(), 1);
385         assert_eq!(sqrt, zero);
386         assert_eq!(sqrt.is_negative().unwrap_u8(), 0);
387 
388         // 1/0 should return (0, 0) since v is 0, u is nonzero
389         let (choice, sqrt) = FieldElement::sqrt_ratio_i(&one, &zero);
390         assert_eq!(choice.unwrap_u8(), 0);
391         assert_eq!(sqrt, zero);
392         assert_eq!(sqrt.is_negative().unwrap_u8(), 0);
393 
394         // 2/1 is nonsquare, so we expect (0, sqrt(i*2))
395         let (choice, sqrt) = FieldElement::sqrt_ratio_i(&two, &one);
396         assert_eq!(choice.unwrap_u8(), 0);
397         assert_eq!(sqrt.square(), &two * &i);
398         assert_eq!(sqrt.is_negative().unwrap_u8(), 0);
399 
400         // 4/1 is square, so we expect (1, sqrt(4))
401         let (choice, sqrt) = FieldElement::sqrt_ratio_i(&four, &one);
402         assert_eq!(choice.unwrap_u8(), 1);
403         assert_eq!(sqrt.square(), four);
404         assert_eq!(sqrt.is_negative().unwrap_u8(), 0);
405 
406         // 1/4 is square, so we expect (1, 1/sqrt(4))
407         let (choice, sqrt) = FieldElement::sqrt_ratio_i(&one, &four);
408         assert_eq!(choice.unwrap_u8(), 1);
409         assert_eq!(&sqrt.square() * &four, one);
410         assert_eq!(sqrt.is_negative().unwrap_u8(), 0);
411     }
412 
413     #[test]
a_p58_vs_ap58_constant()414     fn a_p58_vs_ap58_constant() {
415         let a    = FieldElement::from_bytes(&A_BYTES);
416         let ap58 = FieldElement::from_bytes(&AP58_BYTES);
417         assert_eq!(ap58, a.pow_p58());
418     }
419 
420     #[test]
equality()421     fn equality() {
422         let a    = FieldElement::from_bytes(&A_BYTES);
423         let ainv = FieldElement::from_bytes(&AINV_BYTES);
424         assert!(a == a);
425         assert!(a != ainv);
426     }
427 
428     /// Notice that the last element has the high bit set, which
429     /// should be ignored
430     static B_BYTES: [u8;32] =
431         [113, 191, 169, 143,  91, 234, 121,  15,
432          241, 131, 217,  36, 230, 101,  92, 234,
433            8, 208, 170, 251,  97, 127,  70, 210,
434           58,  23, 166,  87, 240, 169, 184, 178];
435 
436     #[test]
from_bytes_highbit_is_ignored()437     fn from_bytes_highbit_is_ignored() {
438         let mut cleared_bytes = B_BYTES;
439         cleared_bytes[31] &= 127u8;
440         let with_highbit_set    = FieldElement::from_bytes(&B_BYTES);
441         let without_highbit_set = FieldElement::from_bytes(&cleared_bytes);
442         assert_eq!(without_highbit_set, with_highbit_set);
443     }
444 
445     #[test]
conditional_negate()446     fn conditional_negate() {
447         let       one = FieldElement::one();
448         let minus_one = FieldElement::minus_one();
449         let mut x = one;
450         x.conditional_negate(Choice::from(1));
451         assert_eq!(x, minus_one);
452         x.conditional_negate(Choice::from(0));
453         assert_eq!(x, minus_one);
454         x.conditional_negate(Choice::from(1));
455         assert_eq!(x, one);
456     }
457 
458     #[test]
encoding_is_canonical()459     fn encoding_is_canonical() {
460         // Encode 1 wrongly as 1 + (2^255 - 19) = 2^255 - 18
461         let one_encoded_wrongly_bytes: [u8;32] = [0xee, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f];
462         // Decode to a field element
463         let one = FieldElement::from_bytes(&one_encoded_wrongly_bytes);
464         // .. then check that the encoding is correct
465         let one_bytes = one.to_bytes();
466         assert_eq!(one_bytes[0], 1);
467         for i in 1..32 {
468             assert_eq!(one_bytes[i], 0);
469         }
470     }
471 
472     #[test]
batch_invert_empty()473     fn batch_invert_empty() {
474         FieldElement::batch_invert(&mut []);
475     }
476 }
477