124 lines
2.4 KiB
Go
124 lines
2.4 KiB
Go
package menc
|
|
|
|
// 15% AI generated code
|
|
// mostly human made; AI comments and details
|
|
|
|
import (
|
|
"crypto/aes"
|
|
"crypto/cipher"
|
|
"crypto/rand"
|
|
"encoding/binary"
|
|
"errors"
|
|
)
|
|
|
|
var (
|
|
ErrCipherTextTooShort = errors.New("ciphertext too short")
|
|
)
|
|
|
|
type AESGCM_AutoNonce struct {
|
|
gcm cipher.AEAD
|
|
nonceSeq uint32
|
|
}
|
|
|
|
func NewAESGCM_AutoNonce(key []byte) (*AESGCM_AutoNonce, error) {
|
|
block, err := aes.NewCipher(key)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
gcm, err := cipher.NewGCM(block)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &AESGCM_AutoNonce{
|
|
gcm: gcm,
|
|
}, nil
|
|
}
|
|
|
|
/*
|
|
Encrypt encrypts plaintext with optional AAD.
|
|
|
|
Nonce is sequencialy produced and auto managed.
|
|
|
|
Output format: nonce || ciphertext
|
|
*/
|
|
func (a *AESGCM_AutoNonce) Encrypt(plaintext, aad []byte) ([]byte, error) {
|
|
ns := a.gcm.NonceSize()
|
|
out := make([]byte, ns, ns+len(plaintext)+a.gcm.Overhead())
|
|
nonce := out[:ns]
|
|
|
|
binary.BigEndian.PutUint32(nonce[ns-4:], a.nonceSeq)
|
|
a.nonceSeq++
|
|
|
|
return a.gcm.Seal(out, nonce, plaintext, aad), nil
|
|
}
|
|
|
|
/*
|
|
Decrypt decrypts data produced by some AESGCM encrypt.
|
|
|
|
Expects input format: nonce || ciphertext
|
|
*/
|
|
func (a *AESGCM_AutoNonce) Decrypt(ciphertext, aad []byte) ([]byte, error) {
|
|
ns := a.gcm.NonceSize()
|
|
if len(ciphertext) < ns {
|
|
return nil, ErrCipherTextTooShort
|
|
}
|
|
|
|
nonce := ciphertext[:ns]
|
|
data := ciphertext[ns:]
|
|
|
|
return a.gcm.Open(nil, nonce, data, aad)
|
|
}
|
|
|
|
/*
|
|
Encrypt encrypts plaintext with optional AAD.
|
|
|
|
A random nonce is geneated automaticaly.
|
|
|
|
Output format: nonce || ciphertext
|
|
*/
|
|
func AESGCM_Quick_Encrypt(key, plaintext, aad []byte) ([]byte, error) {
|
|
gcm, err := helper_AESGCM_Quick(key)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
ns := gcm.NonceSize()
|
|
out := make([]byte, ns, ns+len(plaintext)+gcm.Overhead())
|
|
nonce := out[:ns]
|
|
|
|
if _, err := rand.Read(nonce); err != nil {
|
|
return nil, err
|
|
}
|
|
out = gcm.Seal(out, nonce, plaintext, aad)
|
|
|
|
return out, nil
|
|
}
|
|
|
|
/*
|
|
Decrypt decrypts data produced by some AESGCM encrypt.
|
|
|
|
Expects input format: nonce || ciphertext
|
|
*/
|
|
func AESGCM_Quick_Decrypt(key, ciphertext, aad []byte) ([]byte, error) {
|
|
gcm, err := helper_AESGCM_Quick(key)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
ns := gcm.NonceSize()
|
|
if len(ciphertext) < ns {
|
|
return nil, ErrCipherTextTooShort
|
|
}
|
|
|
|
nonce := ciphertext[:ns]
|
|
data := ciphertext[ns:]
|
|
|
|
return gcm.Open(nil, nonce, data, aad)
|
|
}
|
|
|
|
func helper_AESGCM_Quick(key []byte) (cipher.AEAD, error) {
|
|
block, err := aes.NewCipher(key)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return cipher.NewGCM(block)
|
|
}
|