mirror of https://github.com/waku-org/noise.git
Remove 2 allocs by reusing CipherContext
This commit is contained in:
parent
6650461c89
commit
a98f07ba16
38
box/box.go
38
box/box.go
|
@ -28,6 +28,7 @@ type Ciphersuite interface {
|
||||||
}
|
}
|
||||||
|
|
||||||
type CipherContext interface {
|
type CipherContext interface {
|
||||||
|
Reset(cv []byte)
|
||||||
Encrypt(dst, authtext, plaintext []byte) []byte
|
Encrypt(dst, authtext, plaintext []byte) []byte
|
||||||
Decrypt(authtext, ciphertext []byte) ([]byte, error)
|
Decrypt(authtext, ciphertext []byte) ([]byte, error)
|
||||||
}
|
}
|
||||||
|
@ -57,6 +58,7 @@ type Crypter struct {
|
||||||
KDFNum int
|
KDFNum int
|
||||||
|
|
||||||
keyBuf [512]byte
|
keyBuf [512]byte
|
||||||
|
cc CipherContext
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Crypter) Encrypt(dst []byte, ephKey *Key, plaintext []byte, padLen int) ([]byte, error) {
|
func (c *Crypter) Encrypt(dst []byte, ephKey *Key, plaintext []byte, padLen int) ([]byte, error) {
|
||||||
|
@ -84,18 +86,24 @@ func (c *Crypter) Encrypt(dst []byte, ephKey *Key, plaintext []byte, padLen int)
|
||||||
cv1 := c.deriveKey(dh1, c.ChainVar)
|
cv1 := c.deriveKey(dh1, c.ChainVar)
|
||||||
c.ChainVar = c.deriveKey(dh2, cv1)
|
c.ChainVar = c.deriveKey(dh2, cv1)
|
||||||
|
|
||||||
cc1 := c.Cipher.NewCipher(cv1)
|
|
||||||
cc2 := c.Cipher.NewCipher(c.ChainVar)
|
|
||||||
|
|
||||||
dst = append(dst, ephKey.Public...)
|
dst = append(dst, ephKey.Public...)
|
||||||
dst = cc1.Encrypt(dst, ephKey.Public, c.SenderKey.Public)
|
dst = c.cipher(cv1).Encrypt(dst, ephKey.Public, c.SenderKey.Public)
|
||||||
return noiseBody(cc2, dst, padLen, plaintext, dst[dstPrefixLen:]), nil
|
return noiseBody(c.cipher(c.ChainVar), dst, padLen, plaintext, dst[dstPrefixLen:]), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Crypter) EncryptedLen(n int) int {
|
func (c *Crypter) EncryptedLen(n int) int {
|
||||||
return n + (2 * c.Cipher.DHLen()) + (2 * c.Cipher.MACLen()) + 4
|
return n + (2 * c.Cipher.DHLen()) + (2 * c.Cipher.MACLen()) + 4
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Crypter) cipher(cv []byte) CipherContext {
|
||||||
|
if c.cc == nil {
|
||||||
|
c.cc = c.Cipher.NewCipher(cv)
|
||||||
|
} else {
|
||||||
|
c.cc.Reset(cv)
|
||||||
|
}
|
||||||
|
return c.cc
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Crypter) Decrypt(ciphertext []byte) ([]byte, error) {
|
func (c *Crypter) Decrypt(ciphertext []byte) ([]byte, error) {
|
||||||
if len(c.ChainVar) == 0 {
|
if len(c.ChainVar) == 0 {
|
||||||
c.ChainVar = make([]byte, cvLen)
|
c.ChainVar = make([]byte, cvLen)
|
||||||
|
@ -104,19 +112,17 @@ func (c *Crypter) Decrypt(ciphertext []byte) ([]byte, error) {
|
||||||
ephPubKey := ciphertext[:c.Cipher.DHLen()]
|
ephPubKey := ciphertext[:c.Cipher.DHLen()]
|
||||||
dh1 := c.Cipher.DH(c.ReceiverKey.Private, ephPubKey)
|
dh1 := c.Cipher.DH(c.ReceiverKey.Private, ephPubKey)
|
||||||
cv1 := c.deriveKey(dh1, c.ChainVar)
|
cv1 := c.deriveKey(dh1, c.ChainVar)
|
||||||
cc1 := c.Cipher.NewCipher(cv1)
|
|
||||||
|
|
||||||
header := ciphertext[:(2*c.Cipher.DHLen())+c.Cipher.MACLen()]
|
header := ciphertext[:(2*c.Cipher.DHLen())+c.Cipher.MACLen()]
|
||||||
ciphertext = ciphertext[len(header):]
|
ciphertext = ciphertext[len(header):]
|
||||||
senderPubKey, err := cc1.Decrypt(ephPubKey, header[c.Cipher.DHLen():])
|
senderPubKey, err := c.cipher(cv1).Decrypt(ephPubKey, header[c.Cipher.DHLen():])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
dh2 := c.Cipher.DH(c.ReceiverKey.Private, senderPubKey)
|
dh2 := c.Cipher.DH(c.ReceiverKey.Private, senderPubKey)
|
||||||
c.ChainVar = c.deriveKey(dh2, cv1)
|
c.ChainVar = c.deriveKey(dh2, cv1)
|
||||||
cc2 := c.Cipher.NewCipher(c.ChainVar)
|
body, err := c.cipher(c.ChainVar).Decrypt(header, ciphertext)
|
||||||
body, err := cc2.Decrypt(header, ciphertext)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -187,17 +193,21 @@ func (noise255) DH(privkey, pubkey []byte) []byte {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (noise255) NewCipher(cv []byte) CipherContext {
|
func (noise255) NewCipher(cv []byte) CipherContext {
|
||||||
return &noise255ctx{cc: cv}
|
return &noise255ctx{cv: cv}
|
||||||
}
|
}
|
||||||
|
|
||||||
type noise255ctx struct {
|
type noise255ctx struct {
|
||||||
cc []byte
|
cv []byte
|
||||||
keystream [128]byte
|
keystream [128]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (n *noise255ctx) Reset(cv []byte) {
|
||||||
|
n.cv = cv
|
||||||
|
}
|
||||||
|
|
||||||
func (n *noise255ctx) key() (cipher.Stream, []byte) {
|
func (n *noise255ctx) key() (cipher.Stream, []byte) {
|
||||||
cipherKey := n.cc[:32]
|
cipherKey := n.cv[:32]
|
||||||
iv := n.cc[32:40]
|
iv := n.cv[32:40]
|
||||||
|
|
||||||
c, err := chacha20.NewCipher(cipherKey, iv)
|
c, err := chacha20.NewCipher(cipherKey, iv)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -210,7 +220,7 @@ func (n *noise255ctx) key() (cipher.Stream, []byte) {
|
||||||
|
|
||||||
c.XORKeyStream(n.keystream[:], n.keystream[:])
|
c.XORKeyStream(n.keystream[:], n.keystream[:])
|
||||||
|
|
||||||
n.cc = n.keystream[64:104]
|
n.cv = n.keystream[64:104]
|
||||||
return c, n.keystream[:]
|
return c, n.keystream[:]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue