romulus_go/romulus_m.go

81 lines
1.7 KiB
Go

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
}