@@ -35,8 +35,8 @@ import (
35
35
"crypto/elliptic"
36
36
"crypto/hmac"
37
37
"crypto/subtle"
38
+ "encoding/binary"
38
39
"errors"
39
- "fmt"
40
40
"hash"
41
41
"io"
42
42
"math/big"
@@ -45,7 +45,6 @@ import (
45
45
var (
46
46
ErrImport = errors .New ("ecies: failed to import key" )
47
47
ErrInvalidCurve = errors .New ("ecies: invalid elliptic curve" )
48
- ErrInvalidParams = errors .New ("ecies: invalid ECIES parameters" )
49
48
ErrInvalidPublicKey = errors .New ("ecies: invalid public key" )
50
49
ErrSharedKeyIsPointAtInfinity = errors .New ("ecies: shared key is point at infinity" )
51
50
ErrSharedKeyTooBig = errors .New ("ecies: shared key params are too big" )
@@ -139,57 +138,39 @@ func (prv *PrivateKey) GenerateShared(pub *PublicKey, skLen, macLen int) (sk []b
139
138
}
140
139
141
140
var (
142
- ErrKeyDataTooLong = errors .New ("ecies: can't supply requested key data" )
143
141
ErrSharedTooLong = errors .New ("ecies: shared secret is too long" )
144
142
ErrInvalidMessage = errors .New ("ecies: invalid message" )
145
143
)
146
144
147
- var (
148
- big2To32 = new (big.Int ).Exp (big .NewInt (2 ), big .NewInt (32 ), nil )
149
- big2To32M1 = new (big.Int ).Sub (big2To32 , big .NewInt (1 ))
150
- )
151
-
152
- func incCounter (ctr []byte ) {
153
- if ctr [3 ]++ ; ctr [3 ] != 0 {
154
- return
155
- }
156
- if ctr [2 ]++ ; ctr [2 ] != 0 {
157
- return
158
- }
159
- if ctr [1 ]++ ; ctr [1 ] != 0 {
160
- return
161
- }
162
- if ctr [0 ]++ ; ctr [0 ] != 0 {
163
- return
164
- }
165
- }
166
-
167
145
// NIST SP 800-56 Concatenation Key Derivation Function (see section 5.8.1).
168
- func concatKDF (hash hash.Hash , z , s1 []byte , kdLen int ) (k []byte , err error ) {
169
- if s1 == nil {
170
- s1 = make ([]byte , 0 )
171
- }
172
-
173
- reps := ((kdLen + 7 ) * 8 ) / (hash .BlockSize () * 8 )
174
- if big .NewInt (int64 (reps )).Cmp (big2To32M1 ) > 0 {
175
- fmt .Println (big2To32M1 )
176
- return nil , ErrKeyDataTooLong
177
- }
178
-
179
- counter := []byte {0 , 0 , 0 , 1 }
180
- k = make ([]byte , 0 )
181
-
182
- for i := 0 ; i <= reps ; i ++ {
183
- hash .Write (counter )
146
+ func concatKDF (hash hash.Hash , z , s1 []byte , kdLen int ) []byte {
147
+ counterBytes := make ([]byte , 4 )
148
+ k := make ([]byte , 0 , roundup (kdLen , hash .Size ()))
149
+ for counter := uint32 (1 ); len (k ) < kdLen ; counter ++ {
150
+ binary .BigEndian .PutUint32 (counterBytes , counter )
151
+ hash .Reset ()
152
+ hash .Write (counterBytes )
184
153
hash .Write (z )
185
154
hash .Write (s1 )
186
- k = append (k , hash .Sum (nil )... )
187
- hash .Reset ()
188
- incCounter (counter )
155
+ k = hash .Sum (k )
189
156
}
157
+ return k [:kdLen ]
158
+ }
190
159
191
- k = k [:kdLen ]
192
- return
160
+ // roundup rounds size up to the next multiple of blocksize.
161
+ func roundup (size , blocksize int ) int {
162
+ return size + blocksize - (size % blocksize )
163
+ }
164
+
165
+ // deriveKeys creates the encryption and MAC keys using concatKDF.
166
+ func deriveKeys (hash hash.Hash , z , s1 []byte , keyLen int ) (Ke , Km []byte ) {
167
+ K := concatKDF (hash , z , s1 , 2 * keyLen )
168
+ Ke = K [:keyLen ]
169
+ Km = K [keyLen :]
170
+ hash .Reset ()
171
+ hash .Write (Km )
172
+ Km = hash .Sum (Km [:0 ])
173
+ return Ke , Km
193
174
}
194
175
195
176
// messageTag computes the MAC of a message (called the tag) as per
@@ -210,7 +191,6 @@ func generateIV(params *ECIESParams, rand io.Reader) (iv []byte, err error) {
210
191
}
211
192
212
193
// symEncrypt carries out CTR encryption using the block cipher specified in the
213
- // parameters.
214
194
func symEncrypt (rand io.Reader , params * ECIESParams , key , m []byte ) (ct []byte , err error ) {
215
195
c , err := params .Cipher (key )
216
196
if err != nil {
@@ -250,36 +230,27 @@ func symDecrypt(params *ECIESParams, key, ct []byte) (m []byte, err error) {
250
230
// ciphertext. s1 is fed into key derivation, s2 is fed into the MAC. If the
251
231
// shared information parameters aren't being used, they should be nil.
252
232
func Encrypt (rand io.Reader , pub * PublicKey , m , s1 , s2 []byte ) (ct []byte , err error ) {
253
- params := pub .Params
254
- if params == nil {
255
- if params = ParamsFromCurve (pub .Curve ); params == nil {
256
- err = ErrUnsupportedECIESParameters
257
- return
258
- }
233
+ params , err := pubkeyParams (pub )
234
+ if err != nil {
235
+ return nil , err
259
236
}
237
+
260
238
R , err := GenerateKey (rand , pub .Curve , params )
261
239
if err != nil {
262
- return
240
+ return nil , err
263
241
}
264
242
265
- hash := params .Hash ()
266
243
z , err := R .GenerateShared (pub , params .KeyLen , params .KeyLen )
267
244
if err != nil {
268
- return
269
- }
270
- K , err := concatKDF (hash , z , s1 , params .KeyLen + params .KeyLen )
271
- if err != nil {
272
- return
245
+ return nil , err
273
246
}
274
- Ke := K [:params .KeyLen ]
275
- Km := K [params .KeyLen :]
276
- hash .Write (Km )
277
- Km = hash .Sum (nil )
278
- hash .Reset ()
247
+
248
+ hash := params .Hash ()
249
+ Ke , Km := deriveKeys (hash , z , s1 , params .KeyLen )
279
250
280
251
em , err := symEncrypt (rand , params , Ke , m )
281
252
if err != nil || len (em ) <= params .BlockSize {
282
- return
253
+ return nil , err
283
254
}
284
255
285
256
d := messageTag (params .Hash , Km , em , s2 )
@@ -289,21 +260,19 @@ func Encrypt(rand io.Reader, pub *PublicKey, m, s1, s2 []byte) (ct []byte, err e
289
260
copy (ct , Rb )
290
261
copy (ct [len (Rb ):], em )
291
262
copy (ct [len (Rb )+ len (em ):], d )
292
- return
263
+ return ct , nil
293
264
}
294
265
295
266
// Decrypt decrypts an ECIES ciphertext.
296
267
func (prv * PrivateKey ) Decrypt (c , s1 , s2 []byte ) (m []byte , err error ) {
297
268
if len (c ) == 0 {
298
269
return nil , ErrInvalidMessage
299
270
}
300
- params := prv .PublicKey .Params
301
- if params == nil {
302
- if params = ParamsFromCurve (prv .PublicKey .Curve ); params == nil {
303
- err = ErrUnsupportedECIESParameters
304
- return
305
- }
271
+ params , err := pubkeyParams (& prv .PublicKey )
272
+ if err != nil {
273
+ return nil , err
306
274
}
275
+
307
276
hash := params .Hash ()
308
277
309
278
var (
@@ -317,12 +286,10 @@ func (prv *PrivateKey) Decrypt(c, s1, s2 []byte) (m []byte, err error) {
317
286
case 2 , 3 , 4 :
318
287
rLen = (prv .PublicKey .Curve .Params ().BitSize + 7 ) / 4
319
288
if len (c ) < (rLen + hLen + 1 ) {
320
- err = ErrInvalidMessage
321
- return
289
+ return nil , ErrInvalidMessage
322
290
}
323
291
default :
324
- err = ErrInvalidPublicKey
325
- return
292
+ return nil , ErrInvalidPublicKey
326
293
}
327
294
328
295
mStart = rLen
@@ -332,36 +299,19 @@ func (prv *PrivateKey) Decrypt(c, s1, s2 []byte) (m []byte, err error) {
332
299
R .Curve = prv .PublicKey .Curve
333
300
R .X , R .Y = elliptic .Unmarshal (R .Curve , c [:rLen ])
334
301
if R .X == nil {
335
- err = ErrInvalidPublicKey
336
- return
337
- }
338
- if ! R .Curve .IsOnCurve (R .X , R .Y ) {
339
- err = ErrInvalidCurve
340
- return
302
+ return nil , ErrInvalidPublicKey
341
303
}
342
304
343
305
z , err := prv .GenerateShared (R , params .KeyLen , params .KeyLen )
344
306
if err != nil {
345
- return
307
+ return nil , err
346
308
}
347
-
348
- K , err := concatKDF (hash , z , s1 , params .KeyLen + params .KeyLen )
349
- if err != nil {
350
- return
351
- }
352
-
353
- Ke := K [:params .KeyLen ]
354
- Km := K [params .KeyLen :]
355
- hash .Write (Km )
356
- Km = hash .Sum (nil )
357
- hash .Reset ()
309
+ Ke , Km := deriveKeys (hash , z , s1 , params .KeyLen )
358
310
359
311
d := messageTag (params .Hash , Km , c [mStart :mEnd ], s2 )
360
312
if subtle .ConstantTimeCompare (c [mEnd :], d ) != 1 {
361
- err = ErrInvalidMessage
362
- return
313
+ return nil , ErrInvalidMessage
363
314
}
364
315
365
- m , err = symDecrypt (params , Ke , c [mStart :mEnd ])
366
- return
316
+ return symDecrypt (params , Ke , c [mStart :mEnd ])
367
317
}
0 commit comments