~nskaggs/+junk/xenial-test

« back to all changes in this revision

Viewing changes to src/golang.org/x/crypto/curve25519/mont25519_amd64.go

  • Committer: Nicholas Skaggs
  • Date: 2016-10-24 20:56:05 UTC
  • Revision ID: nicholas.skaggs@canonical.com-20161024205605-z8lta0uvuhtxwzwl
Initi with beta15

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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.
 
4
 
 
5
// +build amd64,!gccgo,!appengine
 
6
 
 
7
package curve25519
 
8
 
 
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.
 
12
 
 
13
//go:noescape
 
14
 
 
15
func cswap(inout *[5]uint64, v uint64)
 
16
 
 
17
//go:noescape
 
18
 
 
19
func ladderstep(inout *[5][5]uint64)
 
20
 
 
21
//go:noescape
 
22
 
 
23
func freeze(inout *[5]uint64)
 
24
 
 
25
//go:noescape
 
26
 
 
27
func mul(dest, a, b *[5]uint64)
 
28
 
 
29
//go:noescape
 
30
 
 
31
func square(out, in *[5]uint64)
 
32
 
 
33
// mladder uses a Montgomery ladder to calculate (xr/zr) *= s.
 
34
func mladder(xr, zr *[5]uint64, s *[32]byte) {
 
35
        var work [5][5]uint64
 
36
 
 
37
        work[0] = *xr
 
38
        setint(&work[1], 1)
 
39
        setint(&work[2], 0)
 
40
        work[3] = *xr
 
41
        setint(&work[4], 1)
 
42
 
 
43
        j := uint(6)
 
44
        var prevbit byte
 
45
 
 
46
        for i := 31; i >= 0; i-- {
 
47
                for j < 8 {
 
48
                        bit := ((*s)[i] >> j) & 1
 
49
                        swap := bit ^ prevbit
 
50
                        prevbit = bit
 
51
                        cswap(&work[1], uint64(swap))
 
52
                        ladderstep(&work)
 
53
                        j--
 
54
                }
 
55
                j = 7
 
56
        }
 
57
 
 
58
        *xr = work[1]
 
59
        *zr = work[2]
 
60
}
 
61
 
 
62
func scalarMult(out, in, base *[32]byte) {
 
63
        var e [32]byte
 
64
        copy(e[:], (*in)[:])
 
65
        e[0] &= 248
 
66
        e[31] &= 127
 
67
        e[31] |= 64
 
68
 
 
69
        var t, z [5]uint64
 
70
        unpack(&t, base)
 
71
        mladder(&t, &z, &e)
 
72
        invert(&z, &z)
 
73
        mul(&t, &t, &z)
 
74
        pack(out, &t)
 
75
}
 
76
 
 
77
func setint(r *[5]uint64, v uint64) {
 
78
        r[0] = v
 
79
        r[1] = 0
 
80
        r[2] = 0
 
81
        r[3] = 0
 
82
        r[4] = 0
 
83
}
 
84
 
 
85
// unpack sets r = x where r consists of 5, 51-bit limbs in little-endian
 
86
// order.
 
87
func unpack(r *[5]uint64, x *[32]byte) {
 
88
        r[0] = uint64(x[0]) |
 
89
                uint64(x[1])<<8 |
 
90
                uint64(x[2])<<16 |
 
91
                uint64(x[3])<<24 |
 
92
                uint64(x[4])<<32 |
 
93
                uint64(x[5])<<40 |
 
94
                uint64(x[6]&7)<<48
 
95
 
 
96
        r[1] = uint64(x[6])>>3 |
 
97
                uint64(x[7])<<5 |
 
98
                uint64(x[8])<<13 |
 
99
                uint64(x[9])<<21 |
 
100
                uint64(x[10])<<29 |
 
101
                uint64(x[11])<<37 |
 
102
                uint64(x[12]&63)<<45
 
103
 
 
104
        r[2] = uint64(x[12])>>6 |
 
105
                uint64(x[13])<<2 |
 
106
                uint64(x[14])<<10 |
 
107
                uint64(x[15])<<18 |
 
108
                uint64(x[16])<<26 |
 
109
                uint64(x[17])<<34 |
 
110
                uint64(x[18])<<42 |
 
111
                uint64(x[19]&1)<<50
 
112
 
 
113
        r[3] = uint64(x[19])>>1 |
 
114
                uint64(x[20])<<7 |
 
115
                uint64(x[21])<<15 |
 
116
                uint64(x[22])<<23 |
 
117
                uint64(x[23])<<31 |
 
118
                uint64(x[24])<<39 |
 
119
                uint64(x[25]&15)<<47
 
120
 
 
121
        r[4] = uint64(x[25])>>4 |
 
122
                uint64(x[26])<<4 |
 
123
                uint64(x[27])<<12 |
 
124
                uint64(x[28])<<20 |
 
125
                uint64(x[29])<<28 |
 
126
                uint64(x[30])<<36 |
 
127
                uint64(x[31]&127)<<44
 
128
}
 
129
 
 
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) {
 
133
        t := *x
 
134
        freeze(&t)
 
135
 
 
136
        out[0] = byte(t[0])
 
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)
 
143
 
 
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)
 
151
 
 
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)
 
160
 
 
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)
 
168
 
 
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)
 
176
}
 
177
 
 
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
 
181
 
 
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 */
 
189
 
 
190
        square(&t, &z2_5_0)      /* 2^6 - 2^1 */
 
191
        for i := 1; i < 5; i++ { /* 2^20 - 2^10 */
 
192
                square(&t, &t)
 
193
        }
 
194
        mul(&z2_10_0, &t, &z2_5_0) /* 2^10 - 2^0 */
 
195
 
 
196
        square(&t, &z2_10_0)      /* 2^11 - 2^1 */
 
197
        for i := 1; i < 10; i++ { /* 2^20 - 2^10 */
 
198
                square(&t, &t)
 
199
        }
 
200
        mul(&z2_20_0, &t, &z2_10_0) /* 2^20 - 2^0 */
 
201
 
 
202
        square(&t, &z2_20_0)      /* 2^21 - 2^1 */
 
203
        for i := 1; i < 20; i++ { /* 2^40 - 2^20 */
 
204
                square(&t, &t)
 
205
        }
 
206
        mul(&t, &t, &z2_20_0) /* 2^40 - 2^0 */
 
207
 
 
208
        square(&t, &t)            /* 2^41 - 2^1 */
 
209
        for i := 1; i < 10; i++ { /* 2^50 - 2^10 */
 
210
                square(&t, &t)
 
211
        }
 
212
        mul(&z2_50_0, &t, &z2_10_0) /* 2^50 - 2^0 */
 
213
 
 
214
        square(&t, &z2_50_0)      /* 2^51 - 2^1 */
 
215
        for i := 1; i < 50; i++ { /* 2^100 - 2^50 */
 
216
                square(&t, &t)
 
217
        }
 
218
        mul(&z2_100_0, &t, &z2_50_0) /* 2^100 - 2^0 */
 
219
 
 
220
        square(&t, &z2_100_0)      /* 2^101 - 2^1 */
 
221
        for i := 1; i < 100; i++ { /* 2^200 - 2^100 */
 
222
                square(&t, &t)
 
223
        }
 
224
        mul(&t, &t, &z2_100_0) /* 2^200 - 2^0 */
 
225
 
 
226
        square(&t, &t)            /* 2^201 - 2^1 */
 
227
        for i := 1; i < 50; i++ { /* 2^250 - 2^50 */
 
228
                square(&t, &t)
 
229
        }
 
230
        mul(&t, &t, &z2_50_0) /* 2^250 - 2^0 */
 
231
 
 
232
        square(&t, &t) /* 2^251 - 2^1 */
 
233
        square(&t, &t) /* 2^252 - 2^2 */
 
234
        square(&t, &t) /* 2^253 - 2^3 */
 
235
 
 
236
        square(&t, &t) /* 2^254 - 2^4 */
 
237
 
 
238
        square(&t, &t)   /* 2^255 - 2^5 */
 
239
        mul(r, &t, &z11) /* 2^255 - 21 */
 
240
}