1
- // Copyright 2016 The Go Authors. All rights reserved.
1
+ // Copyright 2019 The Go Authors. All rights reserved.
2
2
// Use of this source code is governed by a BSD-style
3
3
// license that can be found in the LICENSE file.
4
4
5
- // In Go 1.13, the ed25519 package was promoted to the standard library as
6
- // crypto/ed25519, and this package became a wrapper for the standard library one.
7
- //
8
- //go:build !go1.13
9
- // +build !go1.13
10
-
11
5
// Package ed25519 implements the Ed25519 signature algorithm. See
12
6
// https://ed25519.cr.yp.to/.
13
7
//
16
10
// representation includes a public key suffix to make multiple signing
17
11
// operations with the same key more efficient. This package refers to the RFC
18
12
// 8032 private key as the “seed”.
13
+ //
14
+ // Beginning with Go 1.13, the functionality of this package was moved to the
15
+ // standard library as crypto/ed25519. This package only acts as a compatibility
16
+ // wrapper.
19
17
package ed25519
20
18
21
- // This code is a port of the public domain, “ref10” implementation of ed25519
22
- // from SUPERCOP.
23
-
24
19
import (
25
- "bytes"
26
- "crypto"
27
- cryptorand "crypto/rand"
28
- "crypto/sha512"
29
- "errors"
20
+ "crypto/ed25519"
30
21
"io"
31
- "strconv"
32
-
33
- "golang.org/x/crypto/ed25519/internal/edwards25519"
34
22
)
35
23
36
24
const (
@@ -45,179 +33,39 @@ const (
45
33
)
46
34
47
35
// PublicKey is the type of Ed25519 public keys.
48
- type PublicKey []byte
36
+ //
37
+ // This type is an alias for crypto/ed25519's PublicKey type.
38
+ // See the crypto/ed25519 package for the methods on this type.
39
+ type PublicKey = ed25519.PublicKey
49
40
50
41
// PrivateKey is the type of Ed25519 private keys. It implements crypto.Signer.
51
- type PrivateKey []byte
52
-
53
- // Public returns the PublicKey corresponding to priv.
54
- func (priv PrivateKey ) Public () crypto.PublicKey {
55
- publicKey := make ([]byte , PublicKeySize )
56
- copy (publicKey , priv [32 :])
57
- return PublicKey (publicKey )
58
- }
59
-
60
- // Seed returns the private key seed corresponding to priv. It is provided for
61
- // interoperability with RFC 8032. RFC 8032's private keys correspond to seeds
62
- // in this package.
63
- func (priv PrivateKey ) Seed () []byte {
64
- seed := make ([]byte , SeedSize )
65
- copy (seed , priv [:32 ])
66
- return seed
67
- }
68
-
69
- // Sign signs the given message with priv.
70
- // Ed25519 performs two passes over messages to be signed and therefore cannot
71
- // handle pre-hashed messages. Thus opts.HashFunc() must return zero to
72
- // indicate the message hasn't been hashed. This can be achieved by passing
73
- // crypto.Hash(0) as the value for opts.
74
- func (priv PrivateKey ) Sign (rand io.Reader , message []byte , opts crypto.SignerOpts ) (signature []byte , err error ) {
75
- if opts .HashFunc () != crypto .Hash (0 ) {
76
- return nil , errors .New ("ed25519: cannot sign hashed message" )
77
- }
78
-
79
- return Sign (priv , message ), nil
80
- }
42
+ //
43
+ // This type is an alias for crypto/ed25519's PrivateKey type.
44
+ // See the crypto/ed25519 package for the methods on this type.
45
+ type PrivateKey = ed25519.PrivateKey
81
46
82
47
// GenerateKey generates a public/private key pair using entropy from rand.
83
48
// If rand is nil, crypto/rand.Reader will be used.
84
49
func GenerateKey (rand io.Reader ) (PublicKey , PrivateKey , error ) {
85
- if rand == nil {
86
- rand = cryptorand .Reader
87
- }
88
-
89
- seed := make ([]byte , SeedSize )
90
- if _ , err := io .ReadFull (rand , seed ); err != nil {
91
- return nil , nil , err
92
- }
93
-
94
- privateKey := NewKeyFromSeed (seed )
95
- publicKey := make ([]byte , PublicKeySize )
96
- copy (publicKey , privateKey [32 :])
97
-
98
- return publicKey , privateKey , nil
50
+ return ed25519 .GenerateKey (rand )
99
51
}
100
52
101
53
// NewKeyFromSeed calculates a private key from a seed. It will panic if
102
54
// len(seed) is not SeedSize. This function is provided for interoperability
103
55
// with RFC 8032. RFC 8032's private keys correspond to seeds in this
104
56
// package.
105
57
func NewKeyFromSeed (seed []byte ) PrivateKey {
106
- if l := len (seed ); l != SeedSize {
107
- panic ("ed25519: bad seed length: " + strconv .Itoa (l ))
108
- }
109
-
110
- digest := sha512 .Sum512 (seed )
111
- digest [0 ] &= 248
112
- digest [31 ] &= 127
113
- digest [31 ] |= 64
114
-
115
- var A edwards25519.ExtendedGroupElement
116
- var hBytes [32 ]byte
117
- copy (hBytes [:], digest [:])
118
- edwards25519 .GeScalarMultBase (& A , & hBytes )
119
- var publicKeyBytes [32 ]byte
120
- A .ToBytes (& publicKeyBytes )
121
-
122
- privateKey := make ([]byte , PrivateKeySize )
123
- copy (privateKey , seed )
124
- copy (privateKey [32 :], publicKeyBytes [:])
125
-
126
- return privateKey
58
+ return ed25519 .NewKeyFromSeed (seed )
127
59
}
128
60
129
61
// Sign signs the message with privateKey and returns a signature. It will
130
62
// panic if len(privateKey) is not PrivateKeySize.
131
63
func Sign (privateKey PrivateKey , message []byte ) []byte {
132
- if l := len (privateKey ); l != PrivateKeySize {
133
- panic ("ed25519: bad private key length: " + strconv .Itoa (l ))
134
- }
135
-
136
- h := sha512 .New ()
137
- h .Write (privateKey [:32 ])
138
-
139
- var digest1 , messageDigest , hramDigest [64 ]byte
140
- var expandedSecretKey [32 ]byte
141
- h .Sum (digest1 [:0 ])
142
- copy (expandedSecretKey [:], digest1 [:])
143
- expandedSecretKey [0 ] &= 248
144
- expandedSecretKey [31 ] &= 63
145
- expandedSecretKey [31 ] |= 64
146
-
147
- h .Reset ()
148
- h .Write (digest1 [32 :])
149
- h .Write (message )
150
- h .Sum (messageDigest [:0 ])
151
-
152
- var messageDigestReduced [32 ]byte
153
- edwards25519 .ScReduce (& messageDigestReduced , & messageDigest )
154
- var R edwards25519.ExtendedGroupElement
155
- edwards25519 .GeScalarMultBase (& R , & messageDigestReduced )
156
-
157
- var encodedR [32 ]byte
158
- R .ToBytes (& encodedR )
159
-
160
- h .Reset ()
161
- h .Write (encodedR [:])
162
- h .Write (privateKey [32 :])
163
- h .Write (message )
164
- h .Sum (hramDigest [:0 ])
165
- var hramDigestReduced [32 ]byte
166
- edwards25519 .ScReduce (& hramDigestReduced , & hramDigest )
167
-
168
- var s [32 ]byte
169
- edwards25519 .ScMulAdd (& s , & hramDigestReduced , & expandedSecretKey , & messageDigestReduced )
170
-
171
- signature := make ([]byte , SignatureSize )
172
- copy (signature [:], encodedR [:])
173
- copy (signature [32 :], s [:])
174
-
175
- return signature
64
+ return ed25519 .Sign (privateKey , message )
176
65
}
177
66
178
67
// Verify reports whether sig is a valid signature of message by publicKey. It
179
68
// will panic if len(publicKey) is not PublicKeySize.
180
69
func Verify (publicKey PublicKey , message , sig []byte ) bool {
181
- if l := len (publicKey ); l != PublicKeySize {
182
- panic ("ed25519: bad public key length: " + strconv .Itoa (l ))
183
- }
184
-
185
- if len (sig ) != SignatureSize || sig [63 ]& 224 != 0 {
186
- return false
187
- }
188
-
189
- var A edwards25519.ExtendedGroupElement
190
- var publicKeyBytes [32 ]byte
191
- copy (publicKeyBytes [:], publicKey )
192
- if ! A .FromBytes (& publicKeyBytes ) {
193
- return false
194
- }
195
- edwards25519 .FeNeg (& A .X , & A .X )
196
- edwards25519 .FeNeg (& A .T , & A .T )
197
-
198
- h := sha512 .New ()
199
- h .Write (sig [:32 ])
200
- h .Write (publicKey [:])
201
- h .Write (message )
202
- var digest [64 ]byte
203
- h .Sum (digest [:0 ])
204
-
205
- var hReduced [32 ]byte
206
- edwards25519 .ScReduce (& hReduced , & digest )
207
-
208
- var R edwards25519.ProjectiveGroupElement
209
- var s [32 ]byte
210
- copy (s [:], sig [32 :])
211
-
212
- // https://tools.ietf.org/html/rfc8032#section-5.1.7 requires that s be in
213
- // the range [0, order) in order to prevent signature malleability.
214
- if ! edwards25519 .ScMinimal (& s ) {
215
- return false
216
- }
217
-
218
- edwards25519 .GeDoubleScalarMultVartime (& R , & hReduced , & A , & s )
219
-
220
- var checkR [32 ]byte
221
- R .ToBytes (& checkR )
222
- return bytes .Equal (sig [:32 ], checkR [:])
70
+ return ed25519 .Verify (publicKey , message , sig )
223
71
}
0 commit comments