Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 0 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
@@ -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=
Expand Down
19 changes: 12 additions & 7 deletions xsecretbox/sharedkey.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,34 @@ 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 {
return sharedKey, err
}

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
}
50 changes: 29 additions & 21 deletions xsecretbox/xsecretbox.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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[:])
Expand All @@ -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 {
Expand All @@ -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):]
Expand Down
Loading