diff --git a/go.mod b/go.mod index 8876ec9..aaa6175 100644 --- a/go.mod +++ b/go.mod @@ -6,8 +6,6 @@ toolchain go1.22.1 require ( github.com/AdguardTeam/golibs v0.20.3 - github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da - github.com/aead/poly1305 v0.0.0-20180717145839-3fee0db0b635 github.com/ameshkov/dnsstamps v1.0.3 github.com/jessevdk/go-flags v1.5.0 github.com/miekg/dns v1.1.58 diff --git a/go.sum b/go.sum index 0568949..78e70d0 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,5 @@ github.com/AdguardTeam/golibs v0.20.3 h1:5RiDypxBebd4Y2eftwm6JJla18oBqRHwanR7q0rnrxw= github.com/AdguardTeam/golibs v0.20.3/go.mod h1:/votX6WK1PdcZ3T2kBOPjPCGmfhlKixhI6ljYrFRPvI= -github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da h1:KjTM2ks9d14ZYCvmHS9iAKVt9AyzRSqNU1qabPih5BY= -github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da/go.mod h1:eHEWzANqSiWQsof+nXEI9bUVUyV6F53Fp89EuCh2EAA= -github.com/aead/poly1305 v0.0.0-20180717145839-3fee0db0b635 h1:52m0LGchQBBVqJRyYYufQuIbVqRawmubW3OFGqK1ekw= -github.com/aead/poly1305 v0.0.0-20180717145839-3fee0db0b635/go.mod h1:lmLxL+FV291OopO93Bwf9fQLQeLyt33VJRUg5VJ30us= github.com/ameshkov/dnsstamps v1.0.3 h1:Srzik+J9mivH1alRACTbys2xOxs0lRH9qnTA7Y1OYVo= github.com/ameshkov/dnsstamps v1.0.3/go.mod h1:Ii3eUu73dx4Vw5O4wjzmT5+lkCwovjzaEZZ4gKyIH5A= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= diff --git a/xsecretbox/sharedkey.go b/xsecretbox/sharedkey.go index dfd398b..4e71f3a 100644 --- a/xsecretbox/sharedkey.go +++ b/xsecretbox/sharedkey.go @@ -3,14 +3,14 @@ package xsecretbox import ( "errors" - "github.com/aead/chacha20/chacha" + "golang.org/x/crypto/chacha20" "golang.org/x/crypto/curve25519" ) // SharedKey computes a shared secret compatible with the one used by // `crypto_box_xchacha20poly1305`. -func SharedKey(secretKey [32]byte, publicKey [32]byte) ([32]byte, error) { - var sharedKey [32]byte +func SharedKey(secretKey [curve25519.ScalarSize]byte, publicKey [curve25519.PointSize]byte) ([KeySize]byte, error) { + var sharedKey [curve25519.PointSize]byte sk, err := curve25519.X25519(secretKey[:], publicKey[:]) if err != nil { @@ -18,14 +18,19 @@ func SharedKey(secretKey [32]byte, publicKey [32]byte) ([32]byte, error) { } c := byte(0) - for i := 0; i < 32; i++ { + for i := 0; i < KeySize; i++ { sharedKey[i] = sk[i] c |= sk[i] } if c == 0 { return sharedKey, errors.New("weak public key") } - var nonce [16]byte - chacha.HChaCha20(&sharedKey, &nonce, &sharedKey) - return sharedKey, nil + var nonce [16]byte // HChaCha20 uses only 16 bytes long nonces + + hRes, err := chacha20.HChaCha20(sharedKey[:], nonce[:]) + if err != nil { + return [KeySize]byte{}, err + } + + return ([KeySize]byte)(hRes), nil } diff --git a/xsecretbox/xsecretbox.go b/xsecretbox/xsecretbox.go index 21b20d7..53c396b 100644 --- a/xsecretbox/xsecretbox.go +++ b/xsecretbox/xsecretbox.go @@ -4,17 +4,19 @@ import ( "crypto/subtle" "errors" - "github.com/aead/chacha20/chacha" - "github.com/aead/poly1305" + "golang.org/x/crypto/chacha20" + "golang.org/x/crypto/poly1305" ) const ( // KeySize is what the name suggests - KeySize = 32 + KeySize = chacha20.KeySize // NonceSize is what the name suggests - NonceSize = 24 + NonceSize = chacha20.NonceSizeX // TagSize is what the name suggests - TagSize = 16 + TagSize = poly1305.TagSize + // BlockSize is what the name suggests + BlockSize = 64 ) // Seal does what the name suggests @@ -26,22 +28,25 @@ func Seal(out, nonce, message, key []byte) []byte { panic("unsupported key size") } - var firstBlock [64]byte - cipher, _ := chacha.NewCipher(nonce, key, 20) + var firstBlock [BlockSize]byte + cipher, err := chacha20.NewUnauthenticatedCipher(key, nonce) + if err != nil { + panic(err) + } cipher.XORKeyStream(firstBlock[:], firstBlock[:]) - var polyKey [32]byte - copy(polyKey[:], firstBlock[:32]) + var polyKey [KeySize]byte + copy(polyKey[:], firstBlock[:KeySize]) ret, out := sliceForAppend(out, TagSize+len(message)) firstMessageBlock := message - if len(firstMessageBlock) > 32 { - firstMessageBlock = firstMessageBlock[:32] + if len(firstMessageBlock) > (BlockSize - KeySize) { + firstMessageBlock = firstMessageBlock[:(BlockSize - KeySize)] } tagOut := out out = out[poly1305.TagSize:] for i, x := range firstMessageBlock { - out[i] = firstBlock[32+i] ^ x + out[i] = firstBlock[(BlockSize - KeySize)+i] ^ x } message = message[len(firstMessageBlock):] ciphertext := out @@ -51,7 +56,7 @@ func Seal(out, nonce, message, key []byte) []byte { cipher.XORKeyStream(out, message) var tag [TagSize]byte - hash := poly1305.New(polyKey) + hash := poly1305.New(&polyKey) _, _ = hash.Write(ciphertext) hash.Sum(tag[:0]) copy(tagOut, tag[:]) @@ -71,15 +76,18 @@ func Open(out, nonce, box, key []byte) ([]byte, error) { return nil, errors.New("ciphertext is too short") } - var firstBlock [64]byte - cipher, _ := chacha.NewCipher(nonce, key, 20) + var firstBlock [BlockSize]byte + cipher, err := chacha20.NewUnauthenticatedCipher(key, nonce) + if err != nil { + panic(err) + } cipher.XORKeyStream(firstBlock[:], firstBlock[:]) - var polyKey [32]byte - copy(polyKey[:], firstBlock[:32]) + var polyKey [KeySize]byte + copy(polyKey[:], firstBlock[:KeySize]) var tag [TagSize]byte ciphertext := box[TagSize:] - hash := poly1305.New(polyKey) + hash := poly1305.New(&polyKey) _, _ = hash.Write(ciphertext) hash.Sum(tag[:0]) if subtle.ConstantTimeCompare(tag[:], box[:TagSize]) != 1 { @@ -89,11 +97,11 @@ func Open(out, nonce, box, key []byte) ([]byte, error) { ret, out := sliceForAppend(out, len(ciphertext)) firstMessageBlock := ciphertext - if len(firstMessageBlock) > 32 { - firstMessageBlock = firstMessageBlock[:32] + if len(firstMessageBlock) > (BlockSize - KeySize) { + firstMessageBlock = firstMessageBlock[:(BlockSize - KeySize)] } for i, x := range firstMessageBlock { - out[i] = firstBlock[32+i] ^ x + out[i] = firstBlock[(BlockSize - KeySize)+i] ^ x } ciphertext = ciphertext[len(firstMessageBlock):] out = out[len(firstMessageBlock):]