mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
ecies: overhaul concatKDF
- Eliminate overflow error case - Simplify and inline incCounter - Preallocate k
This commit is contained in:
parent
5b70f574fd
commit
830d1382f1
1 changed files with 11 additions and 46 deletions
|
|
@ -138,54 +138,26 @@ func (prv *PrivateKey) GenerateShared(pub *PublicKey, skLen, macLen int) (sk []b
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ErrKeyDataTooLong = fmt.Errorf("ecies: can't supply requested key data")
|
|
||||||
ErrSharedTooLong = fmt.Errorf("ecies: shared secret is too long")
|
ErrSharedTooLong = fmt.Errorf("ecies: shared secret is too long")
|
||||||
ErrInvalidMessage = fmt.Errorf("ecies: invalid message")
|
ErrInvalidMessage = fmt.Errorf("ecies: invalid message")
|
||||||
)
|
)
|
||||||
|
|
||||||
func incCounter(ctr []byte) {
|
|
||||||
if ctr[3]++; ctr[3] != 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if ctr[2]++; ctr[2] != 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if ctr[1]++; ctr[1] != 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if ctr[0]++; ctr[0] != 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// NIST SP 800-56 Concatenation Key Derivation Function (see section 5.8.1).
|
// NIST SP 800-56 Concatenation Key Derivation Function (see section 5.8.1).
|
||||||
func concatKDF(hash hash.Hash, z, s1 []byte, kdLen int) (k []byte, err error) {
|
func concatKDF(hash hash.Hash, z, s1 []byte, kdLen int) []byte {
|
||||||
if s1 == nil {
|
|
||||||
s1 = make([]byte, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// reps is the maximum number of iterations of the
|
|
||||||
// counter hashing loop. This is capped to 32 bits to
|
|
||||||
// prevent overflow of the counter.
|
|
||||||
reps := (int64(kdLen) + 7) * 8 / int64(hash.Size()*8)
|
|
||||||
if reps > int64(^uint32(0)) {
|
|
||||||
return nil, ErrKeyDataTooLong
|
|
||||||
}
|
|
||||||
|
|
||||||
counter := []byte{0, 0, 0, 1}
|
counter := []byte{0, 0, 0, 1}
|
||||||
k = make([]byte, 0)
|
k := make([]byte, 0, kdLen+hash.Size())
|
||||||
|
for len(k) < kdLen {
|
||||||
for i := int64(0); i <= reps; i++ {
|
hash.Reset()
|
||||||
hash.Write(counter)
|
hash.Write(counter)
|
||||||
hash.Write(z)
|
hash.Write(z)
|
||||||
hash.Write(s1)
|
hash.Write(s1)
|
||||||
k = append(k, hash.Sum(nil)...)
|
k = k[:len(k)+hash.Size()]
|
||||||
hash.Reset()
|
hash.Sum(k[:len(k)-hash.Size()])
|
||||||
incCounter(counter)
|
// increment counter
|
||||||
|
binary.BigEndian.PutUint32(counter, binary.BigEndian.Uint32(counter)+1)
|
||||||
}
|
}
|
||||||
|
return k[:kdLen]
|
||||||
k = k[:kdLen]
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// messageTag computes the MAC of a message (called the tag) as per
|
// messageTag computes the MAC of a message (called the tag) as per
|
||||||
|
|
@ -263,10 +235,7 @@ func Encrypt(rand io.Reader, pub *PublicKey, m, s1, s2 []byte) (ct []byte, err e
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
K, err := concatKDF(hash, z, s1, params.KeyLen+params.KeyLen)
|
K := concatKDF(hash, z, s1, params.KeyLen+params.KeyLen)
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
Ke := K[:params.KeyLen]
|
Ke := K[:params.KeyLen]
|
||||||
Km := K[params.KeyLen:]
|
Km := K[params.KeyLen:]
|
||||||
hash.Write(Km)
|
hash.Write(Km)
|
||||||
|
|
@ -341,11 +310,7 @@ func (prv *PrivateKey) Decrypt(c, s1, s2 []byte) (m []byte, err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
K, err := concatKDF(hash, z, s1, params.KeyLen+params.KeyLen)
|
K := concatKDF(hash, z, s1, params.KeyLen+params.KeyLen)
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
Ke := K[:params.KeyLen]
|
Ke := K[:params.KeyLen]
|
||||||
Km := K[params.KeyLen:]
|
Km := K[params.KeyLen:]
|
||||||
hash.Write(Km)
|
hash.Write(Km)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue