forked from TrueCloudLab/restic
182 lines
4.4 KiB
Go
182 lines
4.4 KiB
Go
// Copyright 2016 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package chacha20poly1305
|
|
|
|
import (
|
|
"bytes"
|
|
cr "crypto/rand"
|
|
"encoding/hex"
|
|
mr "math/rand"
|
|
"testing"
|
|
)
|
|
|
|
func TestVectors(t *testing.T) {
|
|
for i, test := range chacha20Poly1305Tests {
|
|
key, _ := hex.DecodeString(test.key)
|
|
nonce, _ := hex.DecodeString(test.nonce)
|
|
ad, _ := hex.DecodeString(test.aad)
|
|
plaintext, _ := hex.DecodeString(test.plaintext)
|
|
|
|
aead, err := New(key)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
ct := aead.Seal(nil, nonce, plaintext, ad)
|
|
if ctHex := hex.EncodeToString(ct); ctHex != test.out {
|
|
t.Errorf("#%d: got %s, want %s", i, ctHex, test.out)
|
|
continue
|
|
}
|
|
|
|
plaintext2, err := aead.Open(nil, nonce, ct, ad)
|
|
if err != nil {
|
|
t.Errorf("#%d: Open failed", i)
|
|
continue
|
|
}
|
|
|
|
if !bytes.Equal(plaintext, plaintext2) {
|
|
t.Errorf("#%d: plaintext's don't match: got %x vs %x", i, plaintext2, plaintext)
|
|
continue
|
|
}
|
|
|
|
if len(ad) > 0 {
|
|
alterAdIdx := mr.Intn(len(ad))
|
|
ad[alterAdIdx] ^= 0x80
|
|
if _, err := aead.Open(nil, nonce, ct, ad); err == nil {
|
|
t.Errorf("#%d: Open was successful after altering additional data", i)
|
|
}
|
|
ad[alterAdIdx] ^= 0x80
|
|
}
|
|
|
|
alterNonceIdx := mr.Intn(aead.NonceSize())
|
|
nonce[alterNonceIdx] ^= 0x80
|
|
if _, err := aead.Open(nil, nonce, ct, ad); err == nil {
|
|
t.Errorf("#%d: Open was successful after altering nonce", i)
|
|
}
|
|
nonce[alterNonceIdx] ^= 0x80
|
|
|
|
alterCtIdx := mr.Intn(len(ct))
|
|
ct[alterCtIdx] ^= 0x80
|
|
if _, err := aead.Open(nil, nonce, ct, ad); err == nil {
|
|
t.Errorf("#%d: Open was successful after altering ciphertext", i)
|
|
}
|
|
ct[alterCtIdx] ^= 0x80
|
|
}
|
|
}
|
|
|
|
func TestRandom(t *testing.T) {
|
|
// Some random tests to verify Open(Seal) == Plaintext
|
|
for i := 0; i < 256; i++ {
|
|
var nonce [12]byte
|
|
var key [32]byte
|
|
|
|
al := mr.Intn(128)
|
|
pl := mr.Intn(16384)
|
|
ad := make([]byte, al)
|
|
plaintext := make([]byte, pl)
|
|
cr.Read(key[:])
|
|
cr.Read(nonce[:])
|
|
cr.Read(ad)
|
|
cr.Read(plaintext)
|
|
|
|
aead, err := New(key[:])
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
ct := aead.Seal(nil, nonce[:], plaintext, ad)
|
|
|
|
plaintext2, err := aead.Open(nil, nonce[:], ct, ad)
|
|
if err != nil {
|
|
t.Errorf("Random #%d: Open failed", i)
|
|
continue
|
|
}
|
|
|
|
if !bytes.Equal(plaintext, plaintext2) {
|
|
t.Errorf("Random #%d: plaintext's don't match: got %x vs %x", i, plaintext2, plaintext)
|
|
continue
|
|
}
|
|
|
|
if len(ad) > 0 {
|
|
alterAdIdx := mr.Intn(len(ad))
|
|
ad[alterAdIdx] ^= 0x80
|
|
if _, err := aead.Open(nil, nonce[:], ct, ad); err == nil {
|
|
t.Errorf("Random #%d: Open was successful after altering additional data", i)
|
|
}
|
|
ad[alterAdIdx] ^= 0x80
|
|
}
|
|
|
|
alterNonceIdx := mr.Intn(aead.NonceSize())
|
|
nonce[alterNonceIdx] ^= 0x80
|
|
if _, err := aead.Open(nil, nonce[:], ct, ad); err == nil {
|
|
t.Errorf("Random #%d: Open was successful after altering nonce", i)
|
|
}
|
|
nonce[alterNonceIdx] ^= 0x80
|
|
|
|
alterCtIdx := mr.Intn(len(ct))
|
|
ct[alterCtIdx] ^= 0x80
|
|
if _, err := aead.Open(nil, nonce[:], ct, ad); err == nil {
|
|
t.Errorf("Random #%d: Open was successful after altering ciphertext", i)
|
|
}
|
|
ct[alterCtIdx] ^= 0x80
|
|
}
|
|
}
|
|
|
|
func benchamarkChaCha20Poly1305Seal(b *testing.B, buf []byte) {
|
|
b.SetBytes(int64(len(buf)))
|
|
|
|
var key [32]byte
|
|
var nonce [12]byte
|
|
var ad [13]byte
|
|
var out []byte
|
|
|
|
aead, _ := New(key[:])
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
out = aead.Seal(out[:0], nonce[:], buf[:], ad[:])
|
|
}
|
|
}
|
|
|
|
func benchamarkChaCha20Poly1305Open(b *testing.B, buf []byte) {
|
|
b.SetBytes(int64(len(buf)))
|
|
|
|
var key [32]byte
|
|
var nonce [12]byte
|
|
var ad [13]byte
|
|
var ct []byte
|
|
var out []byte
|
|
|
|
aead, _ := New(key[:])
|
|
ct = aead.Seal(ct[:0], nonce[:], buf[:], ad[:])
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
out, _ = aead.Open(out[:0], nonce[:], ct[:], ad[:])
|
|
}
|
|
}
|
|
|
|
func BenchmarkChacha20Poly1305Open_64(b *testing.B) {
|
|
benchamarkChaCha20Poly1305Open(b, make([]byte, 64))
|
|
}
|
|
|
|
func BenchmarkChacha20Poly1305Seal_64(b *testing.B) {
|
|
benchamarkChaCha20Poly1305Seal(b, make([]byte, 64))
|
|
}
|
|
|
|
func BenchmarkChacha20Poly1305Open_1350(b *testing.B) {
|
|
benchamarkChaCha20Poly1305Open(b, make([]byte, 1350))
|
|
}
|
|
|
|
func BenchmarkChacha20Poly1305Seal_1350(b *testing.B) {
|
|
benchamarkChaCha20Poly1305Seal(b, make([]byte, 1350))
|
|
}
|
|
|
|
func BenchmarkChacha20Poly1305Open_8K(b *testing.B) {
|
|
benchamarkChaCha20Poly1305Open(b, make([]byte, 8*1024))
|
|
}
|
|
|
|
func BenchmarkChacha20Poly1305Seal_8K(b *testing.B) {
|
|
benchamarkChaCha20Poly1305Seal(b, make([]byte, 8*1024))
|
|
}
|