p256_invert.mx raw
1 // Copyright 2021 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 // Code generated by addchain. DO NOT EDIT.
6
7 package fiat
8
9 // Invert sets e = 1/x, and returns e.
10 //
11 // If x == 0, Invert returns e = 0.
12 func (e *P256Element) Invert(x *P256Element) *P256Element {
13 // Inversion is implemented as exponentiation with exponent p − 2.
14 // The sequence of 12 multiplications and 255 squarings is derived from the
15 // following addition chain generated with github.com/mmcloughlin/addchain v0.4.0.
16 //
17 // _10 = 2*1
18 // _11 = 1 + _10
19 // _110 = 2*_11
20 // _111 = 1 + _110
21 // _111000 = _111 << 3
22 // _111111 = _111 + _111000
23 // x12 = _111111 << 6 + _111111
24 // x15 = x12 << 3 + _111
25 // x16 = 2*x15 + 1
26 // x32 = x16 << 16 + x16
27 // i53 = x32 << 15
28 // x47 = x15 + i53
29 // i263 = ((i53 << 17 + 1) << 143 + x47) << 47
30 // return (x47 + i263) << 2 + 1
31 //
32
33 var z = (&P256Element{}).Set(e)
34 var t0 = &P256Element{}
35 var t1 = &P256Element{}
36
37 z.Square(x)
38 z.Mul(x, z)
39 z.Square(z)
40 z.Mul(x, z)
41 t0.Square(z)
42 for s := 1; s < 3; s++ {
43 t0.Square(t0)
44 }
45 t0.Mul(z, t0)
46 t1.Square(t0)
47 for s := 1; s < 6; s++ {
48 t1.Square(t1)
49 }
50 t0.Mul(t0, t1)
51 for s := 0; s < 3; s++ {
52 t0.Square(t0)
53 }
54 z.Mul(z, t0)
55 t0.Square(z)
56 t0.Mul(x, t0)
57 t1.Square(t0)
58 for s := 1; s < 16; s++ {
59 t1.Square(t1)
60 }
61 t0.Mul(t0, t1)
62 for s := 0; s < 15; s++ {
63 t0.Square(t0)
64 }
65 z.Mul(z, t0)
66 for s := 0; s < 17; s++ {
67 t0.Square(t0)
68 }
69 t0.Mul(x, t0)
70 for s := 0; s < 143; s++ {
71 t0.Square(t0)
72 }
73 t0.Mul(z, t0)
74 for s := 0; s < 47; s++ {
75 t0.Square(t0)
76 }
77 z.Mul(z, t0)
78 for s := 0; s < 2; s++ {
79 z.Square(z)
80 }
81 z.Mul(x, z)
82
83 return e.Set(z)
84 }
85