1
2
3
4
5
6
7
8 package curve25519
9
10 import (
11 "crypto/subtle"
12 "fmt"
13
14 "golang.org/x/crypto/curve25519/internal/field"
15 )
16
17
18
19
20
21
22 func ScalarMult(dst, scalar, point *[32]byte) {
23 var e [32]byte
24
25 copy(e[:], scalar[:])
26 e[0] &= 248
27 e[31] &= 127
28 e[31] |= 64
29
30 var x1, x2, z2, x3, z3, tmp0, tmp1 field.Element
31 x1.SetBytes(point[:])
32 x2.One()
33 x3.Set(&x1)
34 z3.One()
35
36 swap := 0
37 for pos := 254; pos >= 0; pos-- {
38 b := e[pos/8] >> uint(pos&7)
39 b &= 1
40 swap ^= int(b)
41 x2.Swap(&x3, swap)
42 z2.Swap(&z3, swap)
43 swap = int(b)
44
45 tmp0.Subtract(&x3, &z3)
46 tmp1.Subtract(&x2, &z2)
47 x2.Add(&x2, &z2)
48 z2.Add(&x3, &z3)
49 z3.Multiply(&tmp0, &x2)
50 z2.Multiply(&z2, &tmp1)
51 tmp0.Square(&tmp1)
52 tmp1.Square(&x2)
53 x3.Add(&z3, &z2)
54 z2.Subtract(&z3, &z2)
55 x2.Multiply(&tmp1, &tmp0)
56 tmp1.Subtract(&tmp1, &tmp0)
57 z2.Square(&z2)
58
59 z3.Mult32(&tmp1, 121666)
60 x3.Square(&x3)
61 tmp0.Add(&tmp0, &z3)
62 z3.Multiply(&x1, &z2)
63 z2.Multiply(&tmp1, &tmp0)
64 }
65
66 x2.Swap(&x3, swap)
67 z2.Swap(&z3, swap)
68
69 z2.Invert(&z2)
70 x2.Multiply(&x2, &z2)
71 copy(dst[:], x2.Bytes())
72 }
73
74
75
76
77
78
79 func ScalarBaseMult(dst, scalar *[32]byte) {
80 ScalarMult(dst, scalar, &basePoint)
81 }
82
83 const (
84
85 ScalarSize = 32
86
87 PointSize = 32
88 )
89
90
91 var Basepoint []byte
92
93 var basePoint = [32]byte{9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
94
95 func init() { Basepoint = basePoint[:] }
96
97 func checkBasepoint() {
98 if subtle.ConstantTimeCompare(Basepoint, []byte{
99 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
100 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
101 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
102 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
103 }) != 1 {
104 panic("curve25519: global Basepoint value was modified")
105 }
106 }
107
108
109
110
111
112
113
114
115
116
117 func X25519(scalar, point []byte) ([]byte, error) {
118
119
120 var dst [32]byte
121 return x25519(&dst, scalar, point)
122 }
123
124 func x25519(dst *[32]byte, scalar, point []byte) ([]byte, error) {
125 var in [32]byte
126 if l := len(scalar); l != 32 {
127 return nil, fmt.Errorf("bad scalar length: %d, expected %d", l, 32)
128 }
129 if l := len(point); l != 32 {
130 return nil, fmt.Errorf("bad point length: %d, expected %d", l, 32)
131 }
132 copy(in[:], scalar)
133 if &point[0] == &Basepoint[0] {
134 checkBasepoint()
135 ScalarBaseMult(dst, &in)
136 } else {
137 var base, zero [32]byte
138 copy(base[:], point)
139 ScalarMult(dst, &in, &base)
140 if subtle.ConstantTimeCompare(dst[:], zero[:]) == 1 {
141 return nil, fmt.Errorf("bad input point: low order point")
142 }
143 }
144 return dst[:], nil
145 }
146
View as plain text