package romulus_go import ( "crypto/rand" "errors" ) const abytes int = 16 const keysize int = 16 const noncesize int = 16 func Encrypt(key []byte, plaintext []byte, additionalData []byte) ([]byte, error) { if len(key) < keysize { return nil, errors.New("Failed to encrypt") } cipher := make([]byte, len(plaintext)+abytes+noncesize) var cipherlen uint64 = (uint64)(len(cipher)) nonce := genNonce() ret := romulus_m_encrypt( cipher[noncesize:], &cipherlen, plaintext, (uint64)(len(plaintext)), additionalData, (uint64)(len(additionalData)), nil, nonce, key[:keysize], ) if ret != 0 { return nil, errors.New("Failed to encrypt") } copy(cipher, nonce) return cipher[:(int)(cipherlen)+noncesize], nil } func Decrypt(key []byte, ciphertext []byte, additionalData []byte) (plaintext []byte, auth bool, err error) { if len(ciphertext) <= noncesize || len(key) < keysize { return nil, false, errors.New("Failed to decrypt") } defer func() { if r := recover(); r != nil { err = errors.New("Recovered from panic in decrypt") auth = false } }() plaintext = make([]byte, len(ciphertext)) var plaintextLen uint64 = (uint64)(len(plaintext)) ret := romulus_m_decrypt( plaintext, &plaintextLen, nil, ciphertext[noncesize:], (uint64)(len(ciphertext)-noncesize), additionalData, (uint64)(len(additionalData)), ciphertext[:noncesize], key[:keysize], ) if ret == -1 { return nil, false, errors.New("Failed to authenticate") } else if ret != 0 { return nil, false, errors.New("Failed to decrypt") } return plaintext[:plaintextLen], true, nil } func genNonce() []byte { buf := make([]byte, noncesize) rand.Read(buf) return buf }