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}