curve25519_dalek/backend/serial/u64/field.rs
1// -*- mode: rust; -*-
2//
3// This file is part of curve25519-dalek.
4// Copyright (c) 2016-2021 isis 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\\), using \\(64\\)-bit
13//! limbs with \\(128\\)-bit products.
14
15use core::fmt::Debug;
16use core::ops::Neg;
17use core::ops::{Add, AddAssign};
18use core::ops::{Mul, MulAssign};
19use core::ops::{Sub, SubAssign};
20
21use subtle::Choice;
22use subtle::ConditionallySelectable;
23
24#[cfg(feature = "zeroize")]
25use zeroize::Zeroize;
26
27/// A `FieldElement51` represents an element of the field
28/// \\( \mathbb Z / (2\^{255} - 19)\\).
29///
30/// In the 64-bit implementation, a `FieldElement` is represented in
31/// radix \\(2\^{51}\\) as five `u64`s; the coefficients are allowed to
32/// grow up to \\(2\^{54}\\) between reductions modulo \\(p\\).
33///
34/// # Note
35///
36/// The `curve25519_dalek::field` module provides a type alias
37/// `curve25519_dalek::field::FieldElement` to either `FieldElement51`
38/// or `FieldElement2625`.
39///
40/// The backend-specific type `FieldElement51` should not be used
41/// outside of the `curve25519_dalek::field` module.
42#[derive(Copy, Clone)]
43pub struct FieldElement51(pub(crate) [u64; 5]);
44
45impl Debug for FieldElement51 {
46 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
47 write!(f, "FieldElement51({:?})", &self.0[..])
48 }
49}
50
51#[cfg(feature = "zeroize")]
52impl Zeroize for FieldElement51 {
53 fn zeroize(&mut self) {
54 self.0.zeroize();
55 }
56}
57
58impl<'b> AddAssign<&'b FieldElement51> for FieldElement51 {
59 fn add_assign(&mut self, _rhs: &'b FieldElement51) {
60 for i in 0..5 {
61 self.0[i] += _rhs.0[i];
62 }
63 }
64}
65
66impl<'a, 'b> Add<&'b FieldElement51> for &'a FieldElement51 {
67 type Output = FieldElement51;
68 fn add(self, _rhs: &'b FieldElement51) -> FieldElement51 {
69 let mut output = *self;
70 output += _rhs;
71 output
72 }
73}
74
75impl<'b> SubAssign<&'b FieldElement51> for FieldElement51 {
76 fn sub_assign(&mut self, _rhs: &'b FieldElement51) {
77 let result = (self as &FieldElement51) - _rhs;
78 self.0 = result.0;
79 }
80}
81
82impl<'a, 'b> Sub<&'b FieldElement51> for &'a FieldElement51 {
83 type Output = FieldElement51;
84 fn sub(self, _rhs: &'b FieldElement51) -> FieldElement51 {
85 // To avoid underflow, first add a multiple of p.
86 // Choose 16*p = p << 4 to be larger than 54-bit _rhs.
87 //
88 // If we could statically track the bitlengths of the limbs
89 // of every FieldElement51, we could choose a multiple of p
90 // just bigger than _rhs and avoid having to do a reduction.
91 //
92 // Since we don't yet have type-level integers to do this, we
93 // have to add an explicit reduction call here.
94 FieldElement51::reduce([
95 (self.0[0] + 36028797018963664u64) - _rhs.0[0],
96 (self.0[1] + 36028797018963952u64) - _rhs.0[1],
97 (self.0[2] + 36028797018963952u64) - _rhs.0[2],
98 (self.0[3] + 36028797018963952u64) - _rhs.0[3],
99 (self.0[4] + 36028797018963952u64) - _rhs.0[4],
100 ])
101 }
102}
103
104impl<'b> MulAssign<&'b FieldElement51> for FieldElement51 {
105 fn mul_assign(&mut self, _rhs: &'b FieldElement51) {
106 let result = (self as &FieldElement51) * _rhs;
107 self.0 = result.0;
108 }
109}
110
111impl<'a, 'b> Mul<&'b FieldElement51> for &'a FieldElement51 {
112 type Output = FieldElement51;
113
114 #[rustfmt::skip] // keep alignment of c* calculations
115 fn mul(self, _rhs: &'b FieldElement51) -> FieldElement51 {
116 /// Helper function to multiply two 64-bit integers with 128
117 /// bits of output.
118 #[inline(always)]
119 fn m(x: u64, y: u64) -> u128 { (x as u128) * (y as u128) }
120
121 // Alias self, _rhs for more readable formulas
122 let a: &[u64; 5] = &self.0;
123 let b: &[u64; 5] = &_rhs.0;
124
125 // Precondition: assume input limbs a[i], b[i] are bounded as
126 //
127 // a[i], b[i] < 2^(51 + b)
128 //
129 // where b is a real parameter measuring the "bit excess" of the limbs.
130
131 // 64-bit precomputations to avoid 128-bit multiplications.
132 //
133 // This fits into a u64 whenever 51 + b + lg(19) < 64.
134 //
135 // Since 51 + b + lg(19) < 51 + 4.25 + b
136 // = 55.25 + b,
137 // this fits if b < 8.75.
138 let b1_19 = b[1] * 19;
139 let b2_19 = b[2] * 19;
140 let b3_19 = b[3] * 19;
141 let b4_19 = b[4] * 19;
142
143 // Multiply to get 128-bit coefficients of output
144 let c0: u128 = m(a[0], b[0]) + m(a[4], b1_19) + m(a[3], b2_19) + m(a[2], b3_19) + m(a[1], b4_19);
145 let mut c1: u128 = m(a[1], b[0]) + m(a[0], b[1]) + m(a[4], b2_19) + m(a[3], b3_19) + m(a[2], b4_19);
146 let mut c2: u128 = m(a[2], b[0]) + m(a[1], b[1]) + m(a[0], b[2]) + m(a[4], b3_19) + m(a[3], b4_19);
147 let mut c3: u128 = m(a[3], b[0]) + m(a[2], b[1]) + m(a[1], b[2]) + m(a[0], b[3]) + m(a[4], b4_19);
148 let mut c4: u128 = m(a[4], b[0]) + m(a[3], b[1]) + m(a[2], b[2]) + m(a[1], b[3]) + m(a[0] , b[4]);
149
150 // How big are the c[i]? We have
151 //
152 // c[i] < 2^(102 + 2*b) * (1+i + (4-i)*19)
153 // < 2^(102 + lg(1 + 4*19) + 2*b)
154 // < 2^(108.27 + 2*b)
155 //
156 // The carry (c[i] >> 51) fits into a u64 when
157 // 108.27 + 2*b - 51 < 64
158 // 2*b < 6.73
159 // b < 3.365.
160 //
161 // So we require b < 3 to ensure this fits.
162 debug_assert!(a[0] < (1 << 54)); debug_assert!(b[0] < (1 << 54));
163 debug_assert!(a[1] < (1 << 54)); debug_assert!(b[1] < (1 << 54));
164 debug_assert!(a[2] < (1 << 54)); debug_assert!(b[2] < (1 << 54));
165 debug_assert!(a[3] < (1 << 54)); debug_assert!(b[3] < (1 << 54));
166 debug_assert!(a[4] < (1 << 54)); debug_assert!(b[4] < (1 << 54));
167
168 // Casting to u64 and back tells the compiler that the carry is
169 // bounded by 2^64, so that the addition is a u128 + u64 rather
170 // than u128 + u128.
171
172 const LOW_51_BIT_MASK: u64 = (1u64 << 51) - 1;
173 let mut out = [0u64; 5];
174
175 c1 += ((c0 >> 51) as u64) as u128;
176 out[0] = (c0 as u64) & LOW_51_BIT_MASK;
177
178 c2 += ((c1 >> 51) as u64) as u128;
179 out[1] = (c1 as u64) & LOW_51_BIT_MASK;
180
181 c3 += ((c2 >> 51) as u64) as u128;
182 out[2] = (c2 as u64) & LOW_51_BIT_MASK;
183
184 c4 += ((c3 >> 51) as u64) as u128;
185 out[3] = (c3 as u64) & LOW_51_BIT_MASK;
186
187 let carry: u64 = (c4 >> 51) as u64;
188 out[4] = (c4 as u64) & LOW_51_BIT_MASK;
189
190 // To see that this does not overflow, we need out[0] + carry * 19 < 2^64.
191 //
192 // c4 < a0*b4 + a1*b3 + a2*b2 + a3*b1 + a4*b0 + (carry from c3)
193 // < 5*(2^(51 + b) * 2^(51 + b)) + (carry from c3)
194 // < 2^(102 + 2*b + lg(5)) + 2^64.
195 //
196 // When b < 3 we get
197 //
198 // c4 < 2^110.33 so that carry < 2^59.33
199 //
200 // so that
201 //
202 // out[0] + carry * 19 < 2^51 + 19 * 2^59.33 < 2^63.58
203 //
204 // and there is no overflow.
205 out[0] += carry * 19;
206
207 // Now out[1] < 2^51 + 2^(64 -51) = 2^51 + 2^13 < 2^(51 + epsilon).
208 out[1] += out[0] >> 51;
209 out[0] &= LOW_51_BIT_MASK;
210
211 // Now out[i] < 2^(51 + epsilon) for all i.
212 FieldElement51(out)
213 }
214}
215
216impl<'a> Neg for &'a FieldElement51 {
217 type Output = FieldElement51;
218 fn neg(self) -> FieldElement51 {
219 let mut output = *self;
220 output.negate();
221 output
222 }
223}
224
225impl ConditionallySelectable for FieldElement51 {
226 fn conditional_select(
227 a: &FieldElement51,
228 b: &FieldElement51,
229 choice: Choice,
230 ) -> FieldElement51 {
231 FieldElement51([
232 u64::conditional_select(&a.0[0], &b.0[0], choice),
233 u64::conditional_select(&a.0[1], &b.0[1], choice),
234 u64::conditional_select(&a.0[2], &b.0[2], choice),
235 u64::conditional_select(&a.0[3], &b.0[3], choice),
236 u64::conditional_select(&a.0[4], &b.0[4], choice),
237 ])
238 }
239
240 fn conditional_swap(a: &mut FieldElement51, b: &mut FieldElement51, choice: Choice) {
241 u64::conditional_swap(&mut a.0[0], &mut b.0[0], choice);
242 u64::conditional_swap(&mut a.0[1], &mut b.0[1], choice);
243 u64::conditional_swap(&mut a.0[2], &mut b.0[2], choice);
244 u64::conditional_swap(&mut a.0[3], &mut b.0[3], choice);
245 u64::conditional_swap(&mut a.0[4], &mut b.0[4], choice);
246 }
247
248 fn conditional_assign(&mut self, other: &FieldElement51, choice: Choice) {
249 self.0[0].conditional_assign(&other.0[0], choice);
250 self.0[1].conditional_assign(&other.0[1], choice);
251 self.0[2].conditional_assign(&other.0[2], choice);
252 self.0[3].conditional_assign(&other.0[3], choice);
253 self.0[4].conditional_assign(&other.0[4], choice);
254 }
255}
256
257impl FieldElement51 {
258 pub(crate) const fn from_limbs(limbs: [u64; 5]) -> FieldElement51 {
259 FieldElement51(limbs)
260 }
261
262 /// The scalar \\( 0 \\).
263 pub const ZERO: FieldElement51 = FieldElement51::from_limbs([0, 0, 0, 0, 0]);
264 /// The scalar \\( 1 \\).
265 pub const ONE: FieldElement51 = FieldElement51::from_limbs([1, 0, 0, 0, 0]);
266 /// The scalar \\( -1 \\).
267 pub const MINUS_ONE: FieldElement51 = FieldElement51::from_limbs([
268 2251799813685228,
269 2251799813685247,
270 2251799813685247,
271 2251799813685247,
272 2251799813685247,
273 ]);
274
275 /// Invert the sign of this field element
276 pub fn negate(&mut self) {
277 // See commentary in the Sub impl
278 let neg = FieldElement51::reduce([
279 36028797018963664u64 - self.0[0],
280 36028797018963952u64 - self.0[1],
281 36028797018963952u64 - self.0[2],
282 36028797018963952u64 - self.0[3],
283 36028797018963952u64 - self.0[4],
284 ]);
285 self.0 = neg.0;
286 }
287
288 /// Given 64-bit input limbs, reduce to enforce the bound 2^(51 + epsilon).
289 #[inline(always)]
290 fn reduce(mut limbs: [u64; 5]) -> FieldElement51 {
291 const LOW_51_BIT_MASK: u64 = (1u64 << 51) - 1;
292
293 // Since the input limbs are bounded by 2^64, the biggest
294 // carry-out is bounded by 2^13.
295 //
296 // The biggest carry-in is c4 * 19, resulting in
297 //
298 // 2^51 + 19*2^13 < 2^51.0000000001
299 //
300 // Because we don't need to canonicalize, only to reduce the
301 // limb sizes, it's OK to do a "weak reduction", where we
302 // compute the carry-outs in parallel.
303
304 let c0 = limbs[0] >> 51;
305 let c1 = limbs[1] >> 51;
306 let c2 = limbs[2] >> 51;
307 let c3 = limbs[3] >> 51;
308 let c4 = limbs[4] >> 51;
309
310 limbs[0] &= LOW_51_BIT_MASK;
311 limbs[1] &= LOW_51_BIT_MASK;
312 limbs[2] &= LOW_51_BIT_MASK;
313 limbs[3] &= LOW_51_BIT_MASK;
314 limbs[4] &= LOW_51_BIT_MASK;
315
316 limbs[0] += c4 * 19;
317 limbs[1] += c0;
318 limbs[2] += c1;
319 limbs[3] += c2;
320 limbs[4] += c3;
321
322 FieldElement51(limbs)
323 }
324
325 /// Load a `FieldElement51` from the low 255 bits of a 256-bit
326 /// input.
327 ///
328 /// # Warning
329 ///
330 /// This function does not check that the input used the canonical
331 /// representative. It masks the high bit, but it will happily
332 /// decode 2^255 - 18 to 1. Applications that require a canonical
333 /// encoding of every field element should decode, re-encode to
334 /// the canonical encoding, and check that the input was
335 /// canonical.
336 ///
337 #[rustfmt::skip] // keep alignment of bit shifts
338 pub fn from_bytes(bytes: &[u8; 32]) -> FieldElement51 {
339 let load8 = |input: &[u8]| -> u64 {
340 (input[0] as u64)
341 | ((input[1] as u64) << 8)
342 | ((input[2] as u64) << 16)
343 | ((input[3] as u64) << 24)
344 | ((input[4] as u64) << 32)
345 | ((input[5] as u64) << 40)
346 | ((input[6] as u64) << 48)
347 | ((input[7] as u64) << 56)
348 };
349
350 let low_51_bit_mask = (1u64 << 51) - 1;
351 FieldElement51(
352 // load bits [ 0, 64), no shift
353 [ load8(&bytes[ 0..]) & low_51_bit_mask
354 // load bits [ 48,112), shift to [ 51,112)
355 , (load8(&bytes[ 6..]) >> 3) & low_51_bit_mask
356 // load bits [ 96,160), shift to [102,160)
357 , (load8(&bytes[12..]) >> 6) & low_51_bit_mask
358 // load bits [152,216), shift to [153,216)
359 , (load8(&bytes[19..]) >> 1) & low_51_bit_mask
360 // load bits [192,256), shift to [204,112)
361 , (load8(&bytes[24..]) >> 12) & low_51_bit_mask
362 ])
363 }
364
365 /// Serialize this `FieldElement51` to a 32-byte array. The
366 /// encoding is canonical.
367 #[rustfmt::skip] // keep alignment of s[*] calculations
368 pub fn as_bytes(&self) -> [u8; 32] {
369 // Let h = limbs[0] + limbs[1]*2^51 + ... + limbs[4]*2^204.
370 //
371 // Write h = pq + r with 0 <= r < p.
372 //
373 // We want to compute r = h mod p.
374 //
375 // If h < 2*p = 2^256 - 38,
376 // then q = 0 or 1,
377 //
378 // with q = 0 when h < p
379 // and q = 1 when h >= p.
380 //
381 // Notice that h >= p <==> h + 19 >= p + 19 <==> h + 19 >= 2^255.
382 // Therefore q can be computed as the carry bit of h + 19.
383
384 // First, reduce the limbs to ensure h < 2*p.
385 let mut limbs = FieldElement51::reduce(self.0).0;
386
387 let mut q = (limbs[0] + 19) >> 51;
388 q = (limbs[1] + q) >> 51;
389 q = (limbs[2] + q) >> 51;
390 q = (limbs[3] + q) >> 51;
391 q = (limbs[4] + q) >> 51;
392
393 // Now we can compute r as r = h - pq = r - (2^255-19)q = r + 19q - 2^255q
394
395 limbs[0] += 19 * q;
396
397 // Now carry the result to compute r + 19q ...
398 let low_51_bit_mask = (1u64 << 51) - 1;
399 limbs[1] += limbs[0] >> 51;
400 limbs[0] &= low_51_bit_mask;
401 limbs[2] += limbs[1] >> 51;
402 limbs[1] &= low_51_bit_mask;
403 limbs[3] += limbs[2] >> 51;
404 limbs[2] &= low_51_bit_mask;
405 limbs[4] += limbs[3] >> 51;
406 limbs[3] &= low_51_bit_mask;
407 // ... but instead of carrying (limbs[4] >> 51) = 2^255q
408 // into another limb, discard it, subtracting the value
409 limbs[4] &= low_51_bit_mask;
410
411 // Now arrange the bits of the limbs.
412 let mut s = [0u8;32];
413 s[ 0] = limbs[0] as u8;
414 s[ 1] = (limbs[0] >> 8) as u8;
415 s[ 2] = (limbs[0] >> 16) as u8;
416 s[ 3] = (limbs[0] >> 24) as u8;
417 s[ 4] = (limbs[0] >> 32) as u8;
418 s[ 5] = (limbs[0] >> 40) as u8;
419 s[ 6] = ((limbs[0] >> 48) | (limbs[1] << 3)) as u8;
420 s[ 7] = (limbs[1] >> 5) as u8;
421 s[ 8] = (limbs[1] >> 13) as u8;
422 s[ 9] = (limbs[1] >> 21) as u8;
423 s[10] = (limbs[1] >> 29) as u8;
424 s[11] = (limbs[1] >> 37) as u8;
425 s[12] = ((limbs[1] >> 45) | (limbs[2] << 6)) as u8;
426 s[13] = (limbs[2] >> 2) as u8;
427 s[14] = (limbs[2] >> 10) as u8;
428 s[15] = (limbs[2] >> 18) as u8;
429 s[16] = (limbs[2] >> 26) as u8;
430 s[17] = (limbs[2] >> 34) as u8;
431 s[18] = (limbs[2] >> 42) as u8;
432 s[19] = ((limbs[2] >> 50) | (limbs[3] << 1)) as u8;
433 s[20] = (limbs[3] >> 7) as u8;
434 s[21] = (limbs[3] >> 15) as u8;
435 s[22] = (limbs[3] >> 23) as u8;
436 s[23] = (limbs[3] >> 31) as u8;
437 s[24] = (limbs[3] >> 39) as u8;
438 s[25] = ((limbs[3] >> 47) | (limbs[4] << 4)) as u8;
439 s[26] = (limbs[4] >> 4) as u8;
440 s[27] = (limbs[4] >> 12) as u8;
441 s[28] = (limbs[4] >> 20) as u8;
442 s[29] = (limbs[4] >> 28) as u8;
443 s[30] = (limbs[4] >> 36) as u8;
444 s[31] = (limbs[4] >> 44) as u8;
445
446 // High bit should be zero.
447 debug_assert!((s[31] & 0b1000_0000u8) == 0u8);
448
449 s
450 }
451
452 /// Given `k > 0`, return `self^(2^k)`.
453 #[rustfmt::skip] // keep alignment of c* calculations
454 pub fn pow2k(&self, mut k: u32) -> FieldElement51 {
455
456 debug_assert!( k > 0 );
457
458 /// Multiply two 64-bit integers with 128 bits of output.
459 #[inline(always)]
460 fn m(x: u64, y: u64) -> u128 {
461 (x as u128) * (y as u128)
462 }
463
464 let mut a: [u64; 5] = self.0;
465
466 loop {
467 // Precondition: assume input limbs a[i] are bounded as
468 //
469 // a[i] < 2^(51 + b)
470 //
471 // where b is a real parameter measuring the "bit excess" of the limbs.
472
473 // Precomputation: 64-bit multiply by 19.
474 //
475 // This fits into a u64 whenever 51 + b + lg(19) < 64.
476 //
477 // Since 51 + b + lg(19) < 51 + 4.25 + b
478 // = 55.25 + b,
479 // this fits if b < 8.75.
480 let a3_19 = 19 * a[3];
481 let a4_19 = 19 * a[4];
482
483 // Multiply to get 128-bit coefficients of output.
484 //
485 // The 128-bit multiplications by 2 turn into 1 slr + 1 slrd each,
486 // which doesn't seem any better or worse than doing them as precomputations
487 // on the 64-bit inputs.
488 let c0: u128 = m(a[0], a[0]) + 2*( m(a[1], a4_19) + m(a[2], a3_19) );
489 let mut c1: u128 = m(a[3], a3_19) + 2*( m(a[0], a[1]) + m(a[2], a4_19) );
490 let mut c2: u128 = m(a[1], a[1]) + 2*( m(a[0], a[2]) + m(a[4], a3_19) );
491 let mut c3: u128 = m(a[4], a4_19) + 2*( m(a[0], a[3]) + m(a[1], a[2]) );
492 let mut c4: u128 = m(a[2], a[2]) + 2*( m(a[0], a[4]) + m(a[1], a[3]) );
493
494 // Same bound as in multiply:
495 // c[i] < 2^(102 + 2*b) * (1+i + (4-i)*19)
496 // < 2^(102 + lg(1 + 4*19) + 2*b)
497 // < 2^(108.27 + 2*b)
498 //
499 // The carry (c[i] >> 51) fits into a u64 when
500 // 108.27 + 2*b - 51 < 64
501 // 2*b < 6.73
502 // b < 3.365.
503 //
504 // So we require b < 3 to ensure this fits.
505 debug_assert!(a[0] < (1 << 54));
506 debug_assert!(a[1] < (1 << 54));
507 debug_assert!(a[2] < (1 << 54));
508 debug_assert!(a[3] < (1 << 54));
509 debug_assert!(a[4] < (1 << 54));
510
511 const LOW_51_BIT_MASK: u64 = (1u64 << 51) - 1;
512
513 // Casting to u64 and back tells the compiler that the carry is bounded by 2^64, so
514 // that the addition is a u128 + u64 rather than u128 + u128.
515 c1 += ((c0 >> 51) as u64) as u128;
516 a[0] = (c0 as u64) & LOW_51_BIT_MASK;
517
518 c2 += ((c1 >> 51) as u64) as u128;
519 a[1] = (c1 as u64) & LOW_51_BIT_MASK;
520
521 c3 += ((c2 >> 51) as u64) as u128;
522 a[2] = (c2 as u64) & LOW_51_BIT_MASK;
523
524 c4 += ((c3 >> 51) as u64) as u128;
525 a[3] = (c3 as u64) & LOW_51_BIT_MASK;
526
527 let carry: u64 = (c4 >> 51) as u64;
528 a[4] = (c4 as u64) & LOW_51_BIT_MASK;
529
530 // To see that this does not overflow, we need a[0] + carry * 19 < 2^64.
531 //
532 // c4 < a2^2 + 2*a0*a4 + 2*a1*a3 + (carry from c3)
533 // < 2^(102 + 2*b + lg(5)) + 2^64.
534 //
535 // When b < 3 we get
536 //
537 // c4 < 2^110.33 so that carry < 2^59.33
538 //
539 // so that
540 //
541 // a[0] + carry * 19 < 2^51 + 19 * 2^59.33 < 2^63.58
542 //
543 // and there is no overflow.
544 a[0] += carry * 19;
545
546 // Now a[1] < 2^51 + 2^(64 -51) = 2^51 + 2^13 < 2^(51 + epsilon).
547 a[1] += a[0] >> 51;
548 a[0] &= LOW_51_BIT_MASK;
549
550 // Now all a[i] < 2^(51 + epsilon) and a = self^(2^k).
551
552 k -= 1;
553 if k == 0 {
554 break;
555 }
556 }
557
558 FieldElement51(a)
559 }
560
561 /// Returns the square of this field element.
562 pub fn square(&self) -> FieldElement51 {
563 self.pow2k(1)
564 }
565
566 /// Returns 2 times the square of this field element.
567 pub fn square2(&self) -> FieldElement51 {
568 let mut square = self.pow2k(1);
569 for i in 0..5 {
570 square.0[i] *= 2;
571 }
572
573 square
574 }
575}