1
// Copyright 2012 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.
5
// +build amd64,!gccgo,!appengine
9
// These functions are implemented in the .s files. The names of the functions
10
// in the rest of the file are also taken from the SUPERCOP sources to help
11
// people following along.
15
func cswap(inout *[5]uint64, v uint64)
19
func ladderstep(inout *[5][5]uint64)
23
func freeze(inout *[5]uint64)
27
func mul(dest, a, b *[5]uint64)
31
func square(out, in *[5]uint64)
33
// mladder uses a Montgomery ladder to calculate (xr/zr) *= s.
34
func mladder(xr, zr *[5]uint64, s *[32]byte) {
46
for i := 31; i >= 0; i-- {
48
bit := ((*s)[i] >> j) & 1
51
cswap(&work[1], uint64(swap))
62
func scalarMult(out, in, base *[32]byte) {
77
func setint(r *[5]uint64, v uint64) {
85
// unpack sets r = x where r consists of 5, 51-bit limbs in little-endian
87
func unpack(r *[5]uint64, x *[32]byte) {
96
r[1] = uint64(x[6])>>3 |
104
r[2] = uint64(x[12])>>6 |
113
r[3] = uint64(x[19])>>1 |
121
r[4] = uint64(x[25])>>4 |
127
uint64(x[31]&127)<<44
130
// pack sets out = x where out is the usual, little-endian form of the 5,
131
// 51-bit limbs in x.
132
func pack(out *[32]byte, x *[5]uint64) {
137
out[1] = byte(t[0] >> 8)
138
out[2] = byte(t[0] >> 16)
139
out[3] = byte(t[0] >> 24)
140
out[4] = byte(t[0] >> 32)
141
out[5] = byte(t[0] >> 40)
142
out[6] = byte(t[0] >> 48)
144
out[6] ^= byte(t[1]<<3) & 0xf8
145
out[7] = byte(t[1] >> 5)
146
out[8] = byte(t[1] >> 13)
147
out[9] = byte(t[1] >> 21)
148
out[10] = byte(t[1] >> 29)
149
out[11] = byte(t[1] >> 37)
150
out[12] = byte(t[1] >> 45)
152
out[12] ^= byte(t[2]<<6) & 0xc0
153
out[13] = byte(t[2] >> 2)
154
out[14] = byte(t[2] >> 10)
155
out[15] = byte(t[2] >> 18)
156
out[16] = byte(t[2] >> 26)
157
out[17] = byte(t[2] >> 34)
158
out[18] = byte(t[2] >> 42)
159
out[19] = byte(t[2] >> 50)
161
out[19] ^= byte(t[3]<<1) & 0xfe
162
out[20] = byte(t[3] >> 7)
163
out[21] = byte(t[3] >> 15)
164
out[22] = byte(t[3] >> 23)
165
out[23] = byte(t[3] >> 31)
166
out[24] = byte(t[3] >> 39)
167
out[25] = byte(t[3] >> 47)
169
out[25] ^= byte(t[4]<<4) & 0xf0
170
out[26] = byte(t[4] >> 4)
171
out[27] = byte(t[4] >> 12)
172
out[28] = byte(t[4] >> 20)
173
out[29] = byte(t[4] >> 28)
174
out[30] = byte(t[4] >> 36)
175
out[31] = byte(t[4] >> 44)
178
// invert calculates r = x^-1 mod p using Fermat's little theorem.
179
func invert(r *[5]uint64, x *[5]uint64) {
180
var z2, z9, z11, z2_5_0, z2_10_0, z2_20_0, z2_50_0, z2_100_0, t [5]uint64
182
square(&z2, x) /* 2 */
183
square(&t, &z2) /* 4 */
184
square(&t, &t) /* 8 */
185
mul(&z9, &t, x) /* 9 */
186
mul(&z11, &z9, &z2) /* 11 */
187
square(&t, &z11) /* 22 */
188
mul(&z2_5_0, &t, &z9) /* 2^5 - 2^0 = 31 */
190
square(&t, &z2_5_0) /* 2^6 - 2^1 */
191
for i := 1; i < 5; i++ { /* 2^20 - 2^10 */
194
mul(&z2_10_0, &t, &z2_5_0) /* 2^10 - 2^0 */
196
square(&t, &z2_10_0) /* 2^11 - 2^1 */
197
for i := 1; i < 10; i++ { /* 2^20 - 2^10 */
200
mul(&z2_20_0, &t, &z2_10_0) /* 2^20 - 2^0 */
202
square(&t, &z2_20_0) /* 2^21 - 2^1 */
203
for i := 1; i < 20; i++ { /* 2^40 - 2^20 */
206
mul(&t, &t, &z2_20_0) /* 2^40 - 2^0 */
208
square(&t, &t) /* 2^41 - 2^1 */
209
for i := 1; i < 10; i++ { /* 2^50 - 2^10 */
212
mul(&z2_50_0, &t, &z2_10_0) /* 2^50 - 2^0 */
214
square(&t, &z2_50_0) /* 2^51 - 2^1 */
215
for i := 1; i < 50; i++ { /* 2^100 - 2^50 */
218
mul(&z2_100_0, &t, &z2_50_0) /* 2^100 - 2^0 */
220
square(&t, &z2_100_0) /* 2^101 - 2^1 */
221
for i := 1; i < 100; i++ { /* 2^200 - 2^100 */
224
mul(&t, &t, &z2_100_0) /* 2^200 - 2^0 */
226
square(&t, &t) /* 2^201 - 2^1 */
227
for i := 1; i < 50; i++ { /* 2^250 - 2^50 */
230
mul(&t, &t, &z2_50_0) /* 2^250 - 2^0 */
232
square(&t, &t) /* 2^251 - 2^1 */
233
square(&t, &t) /* 2^252 - 2^2 */
234
square(&t, &t) /* 2^253 - 2^3 */
236
square(&t, &t) /* 2^254 - 2^4 */
238
square(&t, &t) /* 2^255 - 2^5 */
239
mul(r, &t, &z11) /* 2^255 - 21 */