1
2
3
4
5 package nistec
6
7 import (
8 "crypto/internal/nistec/fiat"
9 "sync"
10 )
11
12 var p224GG *[96]fiat.P224Element
13 var p224GGOnce sync.Once
14
15
16 func p224SqrtCandidate(r, x *fiat.P224Element) {
17
18
19
20
21
22
23
24
25
26
27 p224GGOnce.Do(func() {
28 p224GG = new([96]fiat.P224Element)
29 for i := range p224GG {
30 if i == 0 {
31 p224GG[i].SetBytes([]byte{0x6a, 0x0f, 0xec, 0x67,
32 0x85, 0x98, 0xa7, 0x92, 0x0c, 0x55, 0xb2, 0xd4,
33 0x0b, 0x2d, 0x6f, 0xfb, 0xbe, 0xa3, 0xd8, 0xce,
34 0xf3, 0xfb, 0x36, 0x32, 0xdc, 0x69, 0x1b, 0x74})
35 } else {
36 p224GG[i].Square(&p224GG[i-1])
37 }
38 }
39 })
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65 var t0 = new(fiat.P224Element)
66 var t1 = new(fiat.P224Element)
67
68 r.Square(x)
69 r.Mul(x, r)
70 r.Square(r)
71 r.Mul(x, r)
72 t0.Square(r)
73 for s := 1; s < 3; s++ {
74 t0.Square(t0)
75 }
76 t0.Mul(r, t0)
77 t1.Square(t0)
78 r.Mul(x, t1)
79 for s := 0; s < 5; s++ {
80 t1.Square(t1)
81 }
82 t0.Mul(t0, t1)
83 t1.Square(t0)
84 for s := 1; s < 12; s++ {
85 t1.Square(t1)
86 }
87 t0.Mul(t0, t1)
88 t1.Square(t0)
89 for s := 1; s < 7; s++ {
90 t1.Square(t1)
91 }
92 r.Mul(r, t1)
93 for s := 0; s < 17; s++ {
94 t1.Square(t1)
95 }
96 t0.Mul(t0, t1)
97 t1.Square(t0)
98 for s := 1; s < 48; s++ {
99 t1.Square(t1)
100 }
101 t0.Mul(t0, t1)
102 for s := 0; s < 31; s++ {
103 t0.Square(t0)
104 }
105 r.Mul(r, t0)
106
107
108 v := new(fiat.P224Element).Square(r)
109 v.Mul(v, x)
110
111
112 r.Mul(r, x)
113
114
115
116
117
118
119
120 var p224MinusOne = new(fiat.P224Element).Sub(
121 new(fiat.P224Element), new(fiat.P224Element).One())
122
123 for i := 96 - 1; i >= 1; i-- {
124 w := new(fiat.P224Element).Set(v)
125 for j := 0; j < i-1; j++ {
126 w.Square(w)
127 }
128 cond := w.Equal(p224MinusOne)
129 v.Select(t0.Mul(v, &p224GG[96-i]), v, cond)
130 r.Select(t0.Mul(r, &p224GG[96-i-1]), r, cond)
131 }
132 }
133
View as plain text