1
2
3
4
5 package edwards25519
6
7 import "sync"
8
9
10
11 func basepointTable() *[32]affineLookupTable {
12 basepointTablePrecomp.initOnce.Do(func() {
13 p := NewGeneratorPoint()
14 for i := 0; i < 32; i++ {
15 basepointTablePrecomp.table[i].FromP3(p)
16 for j := 0; j < 8; j++ {
17 p.Add(p, p)
18 }
19 }
20 })
21 return &basepointTablePrecomp.table
22 }
23
24 var basepointTablePrecomp struct {
25 table [32]affineLookupTable
26 initOnce sync.Once
27 }
28
29
30
31
32
33 func (v *Point) ScalarBaseMult(x *Scalar) *Point {
34 basepointTable := basepointTable()
35
36
37
38
39
40
41
42
43
44
45
46
47 digits := x.signedRadix16()
48
49 multiple := &affineCached{}
50 tmp1 := &projP1xP1{}
51 tmp2 := &projP2{}
52
53
54 v.Set(NewIdentityPoint())
55 for i := 1; i < 64; i += 2 {
56 basepointTable[i/2].SelectInto(multiple, digits[i])
57 tmp1.AddAffine(v, multiple)
58 v.fromP1xP1(tmp1)
59 }
60
61
62 tmp2.FromP3(v)
63 tmp1.Double(tmp2)
64 tmp2.FromP1xP1(tmp1)
65 tmp1.Double(tmp2)
66 tmp2.FromP1xP1(tmp1)
67 tmp1.Double(tmp2)
68 tmp2.FromP1xP1(tmp1)
69 tmp1.Double(tmp2)
70 v.fromP1xP1(tmp1)
71
72
73 for i := 0; i < 64; i += 2 {
74 basepointTable[i/2].SelectInto(multiple, digits[i])
75 tmp1.AddAffine(v, multiple)
76 v.fromP1xP1(tmp1)
77 }
78
79 return v
80 }
81
82
83
84
85 func (v *Point) ScalarMult(x *Scalar, q *Point) *Point {
86 checkInitialized(q)
87
88 var table projLookupTable
89 table.FromP3(q)
90
91
92
93
94
95
96
97
98 digits := x.signedRadix16()
99
100
101 multiple := &projCached{}
102 tmp1 := &projP1xP1{}
103 tmp2 := &projP2{}
104 table.SelectInto(multiple, digits[63])
105
106 v.Set(NewIdentityPoint())
107 tmp1.Add(v, multiple)
108 for i := 62; i >= 0; i-- {
109 tmp2.FromP1xP1(tmp1)
110 tmp1.Double(tmp2)
111 tmp2.FromP1xP1(tmp1)
112 tmp1.Double(tmp2)
113 tmp2.FromP1xP1(tmp1)
114 tmp1.Double(tmp2)
115 tmp2.FromP1xP1(tmp1)
116 tmp1.Double(tmp2)
117 v.fromP1xP1(tmp1)
118 table.SelectInto(multiple, digits[i])
119 tmp1.Add(v, multiple)
120 }
121 v.fromP1xP1(tmp1)
122 return v
123 }
124
125
126
127 func basepointNafTable() *nafLookupTable8 {
128 basepointNafTablePrecomp.initOnce.Do(func() {
129 basepointNafTablePrecomp.table.FromP3(NewGeneratorPoint())
130 })
131 return &basepointNafTablePrecomp.table
132 }
133
134 var basepointNafTablePrecomp struct {
135 table nafLookupTable8
136 initOnce sync.Once
137 }
138
139
140
141
142
143 func (v *Point) VarTimeDoubleScalarBaseMult(a *Scalar, A *Point, b *Scalar) *Point {
144 checkInitialized(A)
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160 basepointNafTable := basepointNafTable()
161 var aTable nafLookupTable5
162 aTable.FromP3(A)
163
164
165 aNaf := a.nonAdjacentForm(5)
166 bNaf := b.nonAdjacentForm(8)
167
168
169 i := 255
170 for j := i; j >= 0; j-- {
171 if aNaf[j] != 0 || bNaf[j] != 0 {
172 break
173 }
174 }
175
176 multA := &projCached{}
177 multB := &affineCached{}
178 tmp1 := &projP1xP1{}
179 tmp2 := &projP2{}
180 tmp2.Zero()
181
182
183
184
185 for ; i >= 0; i-- {
186 tmp1.Double(tmp2)
187
188
189 if aNaf[i] > 0 {
190 v.fromP1xP1(tmp1)
191 aTable.SelectInto(multA, aNaf[i])
192 tmp1.Add(v, multA)
193 } else if aNaf[i] < 0 {
194 v.fromP1xP1(tmp1)
195 aTable.SelectInto(multA, -aNaf[i])
196 tmp1.Sub(v, multA)
197 }
198
199 if bNaf[i] > 0 {
200 v.fromP1xP1(tmp1)
201 basepointNafTable.SelectInto(multB, bNaf[i])
202 tmp1.AddAffine(v, multB)
203 } else if bNaf[i] < 0 {
204 v.fromP1xP1(tmp1)
205 basepointNafTable.SelectInto(multB, -bNaf[i])
206 tmp1.SubAffine(v, multB)
207 }
208
209 tmp2.FromP1xP1(tmp1)
210 }
211
212 v.fromP2(tmp2)
213 return v
214 }
215
View as plain text