chacha20poly1305: add example for NewX
Change-Id: I619e38a2c8629e851435299fa5204f5fd48a1d87 Reviewed-on: https://go-review.googlesource.com/128055 Reviewed-by: Adam Langley <agl@golang.org>
This commit is contained in:
@@ -2,7 +2,8 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
// Package chacha20poly1305 implements the ChaCha20-Poly1305 AEAD as specified in RFC 7539.
|
// Package chacha20poly1305 implements the ChaCha20-Poly1305 AEAD as specified in RFC 7539,
|
||||||
|
// and its extended nonce variant XChaCha20-Poly1305.
|
||||||
package chacha20poly1305 // import "golang.org/x/crypto/chacha20poly1305"
|
package chacha20poly1305 // import "golang.org/x/crypto/chacha20poly1305"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -14,12 +15,17 @@ import (
|
|||||||
const (
|
const (
|
||||||
// KeySize is the size of the key used by this AEAD, in bytes.
|
// KeySize is the size of the key used by this AEAD, in bytes.
|
||||||
KeySize = 32
|
KeySize = 32
|
||||||
|
|
||||||
// NonceSize is the size of the nonce used with the standard variant of this
|
// NonceSize is the size of the nonce used with the standard variant of this
|
||||||
// AEAD, in bytes.
|
// AEAD, in bytes.
|
||||||
//
|
//
|
||||||
// Note that this is too short to be safely generated at random if the same
|
// Note that this is too short to be safely generated at random if the same
|
||||||
// key is reused more than 2³² times.
|
// key is reused more than 2³² times.
|
||||||
NonceSize = 12
|
NonceSize = 12
|
||||||
|
|
||||||
|
// NonceSizeX is the size of the nonce used with the XChaCha20-Poly1305
|
||||||
|
// variant of this AEAD, in bytes.
|
||||||
|
NonceSizeX = 24
|
||||||
)
|
)
|
||||||
|
|
||||||
type chacha20poly1305 struct {
|
type chacha20poly1305 struct {
|
||||||
|
|||||||
@@ -7,9 +7,11 @@ package chacha20poly1305
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"crypto/cipher"
|
"crypto/cipher"
|
||||||
cr "crypto/rand"
|
cryptorand "crypto/rand"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
mr "math/rand"
|
"fmt"
|
||||||
|
"log"
|
||||||
|
mathrand "math/rand"
|
||||||
"strconv"
|
"strconv"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
@@ -55,7 +57,7 @@ func TestVectors(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(ad) > 0 {
|
if len(ad) > 0 {
|
||||||
alterAdIdx := mr.Intn(len(ad))
|
alterAdIdx := mathrand.Intn(len(ad))
|
||||||
ad[alterAdIdx] ^= 0x80
|
ad[alterAdIdx] ^= 0x80
|
||||||
if _, err := aead.Open(nil, nonce, ct, ad); err == nil {
|
if _, err := aead.Open(nil, nonce, ct, ad); err == nil {
|
||||||
t.Errorf("#%d: Open was successful after altering additional data", i)
|
t.Errorf("#%d: Open was successful after altering additional data", i)
|
||||||
@@ -63,14 +65,14 @@ func TestVectors(t *testing.T) {
|
|||||||
ad[alterAdIdx] ^= 0x80
|
ad[alterAdIdx] ^= 0x80
|
||||||
}
|
}
|
||||||
|
|
||||||
alterNonceIdx := mr.Intn(aead.NonceSize())
|
alterNonceIdx := mathrand.Intn(aead.NonceSize())
|
||||||
nonce[alterNonceIdx] ^= 0x80
|
nonce[alterNonceIdx] ^= 0x80
|
||||||
if _, err := aead.Open(nil, nonce, ct, ad); err == nil {
|
if _, err := aead.Open(nil, nonce, ct, ad); err == nil {
|
||||||
t.Errorf("#%d: Open was successful after altering nonce", i)
|
t.Errorf("#%d: Open was successful after altering nonce", i)
|
||||||
}
|
}
|
||||||
nonce[alterNonceIdx] ^= 0x80
|
nonce[alterNonceIdx] ^= 0x80
|
||||||
|
|
||||||
alterCtIdx := mr.Intn(len(ct))
|
alterCtIdx := mathrand.Intn(len(ct))
|
||||||
ct[alterCtIdx] ^= 0x80
|
ct[alterCtIdx] ^= 0x80
|
||||||
if _, err := aead.Open(nil, nonce, ct, ad); err == nil {
|
if _, err := aead.Open(nil, nonce, ct, ad); err == nil {
|
||||||
t.Errorf("#%d: Open was successful after altering ciphertext", i)
|
t.Errorf("#%d: Open was successful after altering ciphertext", i)
|
||||||
@@ -86,14 +88,14 @@ func TestRandom(t *testing.T) {
|
|||||||
var nonce = make([]byte, nonceSize)
|
var nonce = make([]byte, nonceSize)
|
||||||
var key [32]byte
|
var key [32]byte
|
||||||
|
|
||||||
al := mr.Intn(128)
|
al := mathrand.Intn(128)
|
||||||
pl := mr.Intn(16384)
|
pl := mathrand.Intn(16384)
|
||||||
ad := make([]byte, al)
|
ad := make([]byte, al)
|
||||||
plaintext := make([]byte, pl)
|
plaintext := make([]byte, pl)
|
||||||
cr.Read(key[:])
|
cryptorand.Read(key[:])
|
||||||
cr.Read(nonce[:])
|
cryptorand.Read(nonce[:])
|
||||||
cr.Read(ad)
|
cryptorand.Read(ad)
|
||||||
cr.Read(plaintext)
|
cryptorand.Read(plaintext)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
aead cipher.AEAD
|
aead cipher.AEAD
|
||||||
@@ -125,7 +127,7 @@ func TestRandom(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(ad) > 0 {
|
if len(ad) > 0 {
|
||||||
alterAdIdx := mr.Intn(len(ad))
|
alterAdIdx := mathrand.Intn(len(ad))
|
||||||
ad[alterAdIdx] ^= 0x80
|
ad[alterAdIdx] ^= 0x80
|
||||||
if _, err := aead.Open(nil, nonce[:], ct, ad); err == nil {
|
if _, err := aead.Open(nil, nonce[:], ct, ad); err == nil {
|
||||||
t.Errorf("Random #%d: Open was successful after altering additional data", i)
|
t.Errorf("Random #%d: Open was successful after altering additional data", i)
|
||||||
@@ -133,14 +135,14 @@ func TestRandom(t *testing.T) {
|
|||||||
ad[alterAdIdx] ^= 0x80
|
ad[alterAdIdx] ^= 0x80
|
||||||
}
|
}
|
||||||
|
|
||||||
alterNonceIdx := mr.Intn(aead.NonceSize())
|
alterNonceIdx := mathrand.Intn(aead.NonceSize())
|
||||||
nonce[alterNonceIdx] ^= 0x80
|
nonce[alterNonceIdx] ^= 0x80
|
||||||
if _, err := aead.Open(nil, nonce[:], ct, ad); err == nil {
|
if _, err := aead.Open(nil, nonce[:], ct, ad); err == nil {
|
||||||
t.Errorf("Random #%d: Open was successful after altering nonce", i)
|
t.Errorf("Random #%d: Open was successful after altering nonce", i)
|
||||||
}
|
}
|
||||||
nonce[alterNonceIdx] ^= 0x80
|
nonce[alterNonceIdx] ^= 0x80
|
||||||
|
|
||||||
alterCtIdx := mr.Intn(len(ct))
|
alterCtIdx := mathrand.Intn(len(ct))
|
||||||
ct[alterCtIdx] ^= 0x80
|
ct[alterCtIdx] ^= 0x80
|
||||||
if _, err := aead.Open(nil, nonce[:], ct, ad); err == nil {
|
if _, err := aead.Open(nil, nonce[:], ct, ad); err == nil {
|
||||||
t.Errorf("Random #%d: Open was successful after altering ciphertext", i)
|
t.Errorf("Random #%d: Open was successful after altering ciphertext", i)
|
||||||
@@ -217,3 +219,37 @@ func BenchmarkChacha20Poly1305(b *testing.B) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var key = make([]byte, KeySize)
|
||||||
|
|
||||||
|
func ExampleNewX() {
|
||||||
|
aead, err := NewX(key)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalln("Failed to instantiate XChaCha20-Poly1305:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, msg := range []string{
|
||||||
|
"Attack at dawn.",
|
||||||
|
"The eagle has landed.",
|
||||||
|
"Gophers, gophers, gophers everywhere!",
|
||||||
|
} {
|
||||||
|
// Encryption.
|
||||||
|
nonce := make([]byte, NonceSizeX)
|
||||||
|
if _, err := cryptorand.Read(nonce); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
ciphertext := aead.Seal(nil, nonce, []byte(msg), nil)
|
||||||
|
|
||||||
|
// Decryption.
|
||||||
|
plaintext, err := aead.Open(nil, nonce, ciphertext, nil)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalln("Failed to decrypt or authenticate message:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("%s\n", plaintext)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output: Attack at dawn.
|
||||||
|
// The eagle has landed.
|
||||||
|
// Gophers, gophers, gophers everywhere!
|
||||||
|
}
|
||||||
|
|||||||
@@ -12,12 +12,6 @@ import (
|
|||||||
"golang.org/x/crypto/internal/chacha20"
|
"golang.org/x/crypto/internal/chacha20"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
|
||||||
// NonceSizeX is the size of the nonce used with the XChaCha20-Poly1305
|
|
||||||
// variant of this AEAD, in bytes.
|
|
||||||
NonceSizeX = 24
|
|
||||||
)
|
|
||||||
|
|
||||||
type xchacha20poly1305 struct {
|
type xchacha20poly1305 struct {
|
||||||
key [8]uint32
|
key [8]uint32
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user