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