grumble/pkg/cryptstate/mode_secretbox.go

69 lines
1.9 KiB
Go

// Copyright (c) 2012 The Grumble Authors
// The use of this source code is goverened by a BSD-style
// license that can be found in the LICENSE-file.
package cryptstate
import (
"unsafe"
"code.google.com/p/go.crypto/nacl/secretbox"
)
// secretBoxMode implements the XSalsa20-Poly1305 CryptoMode
type secretBoxMode struct {
key [32]byte
}
// NonceSize returns the nonce size to be used with XSalsa20-Poly1305.
func (sb *secretBoxMode) NonceSize() int {
return 24
}
// KeySize returns the key size to be used with XSalsa20-Poly1305.
func (sb *secretBoxMode) KeySize() int {
return 32
}
// Overhead returns the overhead that a ciphertext has over a plaintext.
// In the case of XSalsa20-Poly1305 the overhead is the authentication tag.
func (sb *secretBoxMode) Overhead() int {
return secretbox.Overhead
}
// SetKey sets a new key. The key must have a length equal to KeySize().
func (sb *secretBoxMode) SetKey(key []byte) {
if len(key) != sb.KeySize() {
panic("cryptstate: invalid key length")
}
copy(sb.key[:], key)
}
// Encrypt encrypts a message using XSalsa20-Poly1305 and outputs it to dst.
func (sb *secretBoxMode) Encrypt(dst []byte, src []byte, nonce []byte) {
if len(dst) <= sb.Overhead() {
panic("cryptstate: bad dst")
}
if len(nonce) != 24 {
panic("cryptstate: bad nonce length")
}
noncePtr := (*[24]byte)(unsafe.Pointer(&nonce[0]))
secretbox.Seal(dst[0:0], src, noncePtr, &sb.key)
}
// Decrypt decrypts a message using XSalsa20-Poly1305 and outputs it to dst.
// Returns false if decryption failed (authentication tag mismatch).
func (sb *secretBoxMode) Decrypt(dst []byte, src []byte, nonce []byte) bool {
if len(src) <= sb.Overhead() {
panic("cryptstate: bad src")
}
if len(nonce) != 24 {
panic("cryptstate: bad nonce length")
}
noncePtr := (*[24]byte)(unsafe.Pointer(&nonce[0]))
_, ok := secretbox.Open(dst[0:0], src, noncePtr, &sb.key)
return ok
}