git.sr.ht/~pingoo/stdx@v0.0.0-20240218134121-094174641f6e/crypto/chacha20blake3/xchacha20_blake3.go (about) 1 package chacha20blake3 2 3 import ( 4 "crypto/cipher" 5 "errors" 6 7 "git.sr.ht/~pingoo/stdx/crypto/chacha" 8 ) 9 10 const ( 11 NonceSizeX = 24 12 ) 13 14 var ( 15 ErrBadNonceXLength = errors.New("chacha20blake3: bad nonce length for XChaCha20Blake3. 24 bytes required") 16 ) 17 18 type XChaCha20Blake3 struct { 19 key [KeySize]byte 20 } 21 22 // ensure that XChaCha20Blake3 implements `cipher.AEAD` interface at build time 23 var _ cipher.AEAD = (*XChaCha20Blake3)(nil) 24 25 func NewX(key []byte) (*XChaCha20Blake3, error) { 26 if len(key) != KeySize { 27 return nil, ErrBadKeyLength 28 } 29 30 ret := new(XChaCha20Blake3) 31 copy(ret.key[:], key) 32 return ret, nil 33 } 34 35 func (*XChaCha20Blake3) NonceSize() int { 36 return NonceSizeX 37 } 38 39 func (*XChaCha20Blake3) Overhead() int { 40 return TagSize 41 } 42 43 func (x *XChaCha20Blake3) Seal(dst, nonce, plaintext, additionalData []byte) []byte { 44 if len(nonce) != NonceSizeX { 45 panic(ErrBadNonceXLength) 46 } 47 48 chaChaKey, _ := chacha.HChaCha20(x.key[:], nonce[0:16]) 49 chacha20Cipher, _ := New(chaChaKey) 50 51 // chaChaNonce := make([]byte, NonceSize) 52 // copy(chaChaNonce[4:12], nonce[16:24]) 53 54 return chacha20Cipher.Seal(dst, nonce[16:24], plaintext, additionalData) 55 } 56 57 func (x *XChaCha20Blake3) Open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) { 58 if len(nonce) != NonceSizeX { 59 panic(ErrBadNonceXLength) 60 } 61 62 chaChaKey, _ := chacha.HChaCha20(x.key[:], nonce[0:16]) 63 chacha20Cipher, _ := New(chaChaKey) 64 65 return chacha20Cipher.Open(dst, nonce[16:24], ciphertext, additionalData) 66 }