Bumping k8s dependencies to 1.13

This commit is contained in:
Cheng Xing
2018-11-16 14:08:25 -08:00
parent 305407125c
commit b4c0b68ec7
8002 changed files with 884099 additions and 276228 deletions

View File

@@ -2,32 +2,50 @@
// Use of this source code is governed by a BSD-style
// 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"
import (
"crypto/cipher"
"encoding/binary"
"errors"
)
const (
// KeySize is the size of the key used by this AEAD, in bytes.
KeySize = 32
// NonceSize is the size of the nonce used with this AEAD, in bytes.
// NonceSize is the size of the nonce used with the standard variant of this
// AEAD, in bytes.
//
// Note that this is too short to be safely generated at random if the same
// key is reused more than 2³² times.
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 {
key [32]byte
key [8]uint32
}
// New returns a ChaCha20-Poly1305 AEAD that uses the given, 256-bit key.
// New returns a ChaCha20-Poly1305 AEAD that uses the given 256-bit key.
func New(key []byte) (cipher.AEAD, error) {
if len(key) != KeySize {
return nil, errors.New("chacha20poly1305: bad key length")
}
ret := new(chacha20poly1305)
copy(ret.key[:], key)
ret.key[0] = binary.LittleEndian.Uint32(key[0:4])
ret.key[1] = binary.LittleEndian.Uint32(key[4:8])
ret.key[2] = binary.LittleEndian.Uint32(key[8:12])
ret.key[3] = binary.LittleEndian.Uint32(key[12:16])
ret.key[4] = binary.LittleEndian.Uint32(key[16:20])
ret.key[5] = binary.LittleEndian.Uint32(key[20:24])
ret.key[6] = binary.LittleEndian.Uint32(key[24:28])
ret.key[7] = binary.LittleEndian.Uint32(key[28:32])
return ret, nil
}

View File

@@ -6,7 +6,12 @@
package chacha20poly1305
import "encoding/binary"
import (
"encoding/binary"
"golang.org/x/crypto/internal/subtle"
"golang.org/x/sys/cpu"
)
//go:noescape
func chacha20Poly1305Open(dst []byte, key []uint32, src, ad []byte) bool
@@ -14,78 +19,26 @@ func chacha20Poly1305Open(dst []byte, key []uint32, src, ad []byte) bool
//go:noescape
func chacha20Poly1305Seal(dst []byte, key []uint32, src, ad []byte)
// cpuid is implemented in chacha20poly1305_amd64.s.
func cpuid(eaxArg, ecxArg uint32) (eax, ebx, ecx, edx uint32)
// xgetbv with ecx = 0 is implemented in chacha20poly1305_amd64.s.
func xgetbv() (eax, edx uint32)
var (
useASM bool
useAVX2 bool
useAVX2 = cpu.X86.HasAVX2 && cpu.X86.HasBMI2
)
func init() {
detectCPUFeatures()
}
// detectCPUFeatures is used to detect if cpu instructions
// used by the functions implemented in assembler in
// chacha20poly1305_amd64.s are supported.
func detectCPUFeatures() {
maxID, _, _, _ := cpuid(0, 0)
if maxID < 1 {
return
}
_, _, ecx1, _ := cpuid(1, 0)
haveSSSE3 := isSet(9, ecx1)
useASM = haveSSSE3
haveOSXSAVE := isSet(27, ecx1)
osSupportsAVX := false
// For XGETBV, OSXSAVE bit is required and sufficient.
if haveOSXSAVE {
eax, _ := xgetbv()
// Check if XMM and YMM registers have OS support.
osSupportsAVX = isSet(1, eax) && isSet(2, eax)
}
haveAVX := isSet(28, ecx1) && osSupportsAVX
if maxID < 7 {
return
}
_, ebx7, _, _ := cpuid(7, 0)
haveAVX2 := isSet(5, ebx7) && haveAVX
haveBMI2 := isSet(8, ebx7)
useAVX2 = haveAVX2 && haveBMI2
}
// isSet checks if bit at bitpos is set in value.
func isSet(bitpos uint, value uint32) bool {
return value&(1<<bitpos) != 0
}
// setupState writes a ChaCha20 input matrix to state. See
// https://tools.ietf.org/html/rfc7539#section-2.3.
func setupState(state *[16]uint32, key *[32]byte, nonce []byte) {
func setupState(state *[16]uint32, key *[8]uint32, nonce []byte) {
state[0] = 0x61707865
state[1] = 0x3320646e
state[2] = 0x79622d32
state[3] = 0x6b206574
state[4] = binary.LittleEndian.Uint32(key[:4])
state[5] = binary.LittleEndian.Uint32(key[4:8])
state[6] = binary.LittleEndian.Uint32(key[8:12])
state[7] = binary.LittleEndian.Uint32(key[12:16])
state[8] = binary.LittleEndian.Uint32(key[16:20])
state[9] = binary.LittleEndian.Uint32(key[20:24])
state[10] = binary.LittleEndian.Uint32(key[24:28])
state[11] = binary.LittleEndian.Uint32(key[28:32])
state[4] = key[0]
state[5] = key[1]
state[6] = key[2]
state[7] = key[3]
state[8] = key[4]
state[9] = key[5]
state[10] = key[6]
state[11] = key[7]
state[12] = 0
state[13] = binary.LittleEndian.Uint32(nonce[:4])
@@ -94,7 +47,7 @@ func setupState(state *[16]uint32, key *[32]byte, nonce []byte) {
}
func (c *chacha20poly1305) seal(dst, nonce, plaintext, additionalData []byte) []byte {
if !useASM {
if !cpu.X86.HasSSSE3 {
return c.sealGeneric(dst, nonce, plaintext, additionalData)
}
@@ -102,12 +55,15 @@ func (c *chacha20poly1305) seal(dst, nonce, plaintext, additionalData []byte) []
setupState(&state, &c.key, nonce)
ret, out := sliceForAppend(dst, len(plaintext)+16)
if subtle.InexactOverlap(out, plaintext) {
panic("chacha20poly1305: invalid buffer overlap")
}
chacha20Poly1305Seal(out[:], state[:], plaintext, additionalData)
return ret
}
func (c *chacha20poly1305) open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) {
if !useASM {
if !cpu.X86.HasSSSE3 {
return c.openGeneric(dst, nonce, ciphertext, additionalData)
}
@@ -116,6 +72,9 @@ func (c *chacha20poly1305) open(dst, nonce, ciphertext, additionalData []byte) (
ciphertext = ciphertext[:len(ciphertext)-16]
ret, out := sliceForAppend(dst, len(ciphertext))
if subtle.InexactOverlap(out, ciphertext) {
panic("chacha20poly1305: invalid buffer overlap")
}
if !chacha20Poly1305Open(out, state[:], ciphertext, additionalData) {
for i := range out {
out[i] = 0

View File

@@ -2693,22 +2693,3 @@ sealAVX2Tail512LoopB:
VPERM2I128 $0x13, tmpStoreAVX2, DD3, DD0
JMP sealAVX2SealHash
// func cpuid(eaxArg, ecxArg uint32) (eax, ebx, ecx, edx uint32)
TEXT ·cpuid(SB), NOSPLIT, $0-24
MOVL eaxArg+0(FP), AX
MOVL ecxArg+4(FP), CX
CPUID
MOVL AX, eax+8(FP)
MOVL BX, ebx+12(FP)
MOVL CX, ecx+16(FP)
MOVL DX, edx+20(FP)
RET
// func xgetbv() (eax, edx uint32)
TEXT ·xgetbv(SB),NOSPLIT,$0-8
MOVL $0, CX
XGETBV
MOVL AX, eax+0(FP)
MOVL DX, edx+4(FP)
RET

View File

@@ -8,6 +8,7 @@ import (
"encoding/binary"
"golang.org/x/crypto/internal/chacha20"
"golang.org/x/crypto/internal/subtle"
"golang.org/x/crypto/poly1305"
)
@@ -16,15 +17,20 @@ func roundTo16(n int) int {
}
func (c *chacha20poly1305) sealGeneric(dst, nonce, plaintext, additionalData []byte) []byte {
var counter [16]byte
copy(counter[4:], nonce)
ret, out := sliceForAppend(dst, len(plaintext)+poly1305.TagSize)
if subtle.InexactOverlap(out, plaintext) {
panic("chacha20poly1305: invalid buffer overlap")
}
var polyKey [32]byte
chacha20.XORKeyStream(polyKey[:], polyKey[:], &counter, &c.key)
ret, out := sliceForAppend(dst, len(plaintext)+poly1305.TagSize)
counter[0] = 1
chacha20.XORKeyStream(out, plaintext, &counter, &c.key)
s := chacha20.New(c.key, [3]uint32{
binary.LittleEndian.Uint32(nonce[0:4]),
binary.LittleEndian.Uint32(nonce[4:8]),
binary.LittleEndian.Uint32(nonce[8:12]),
})
s.XORKeyStream(polyKey[:], polyKey[:])
s.Advance() // skip the next 32 bytes
s.XORKeyStream(out, plaintext)
polyInput := make([]byte, roundTo16(len(additionalData))+roundTo16(len(plaintext))+8+8)
copy(polyInput, additionalData)
@@ -44,11 +50,14 @@ func (c *chacha20poly1305) openGeneric(dst, nonce, ciphertext, additionalData []
copy(tag[:], ciphertext[len(ciphertext)-16:])
ciphertext = ciphertext[:len(ciphertext)-16]
var counter [16]byte
copy(counter[4:], nonce)
var polyKey [32]byte
chacha20.XORKeyStream(polyKey[:], polyKey[:], &counter, &c.key)
s := chacha20.New(c.key, [3]uint32{
binary.LittleEndian.Uint32(nonce[0:4]),
binary.LittleEndian.Uint32(nonce[4:8]),
binary.LittleEndian.Uint32(nonce[8:12]),
})
s.XORKeyStream(polyKey[:], polyKey[:])
s.Advance() // skip the next 32 bytes
polyInput := make([]byte, roundTo16(len(additionalData))+roundTo16(len(ciphertext))+8+8)
copy(polyInput, additionalData)
@@ -57,6 +66,9 @@ func (c *chacha20poly1305) openGeneric(dst, nonce, ciphertext, additionalData []
binary.LittleEndian.PutUint64(polyInput[len(polyInput)-8:], uint64(len(ciphertext)))
ret, out := sliceForAppend(dst, len(ciphertext))
if subtle.InexactOverlap(out, ciphertext) {
panic("chacha20poly1305: invalid buffer overlap")
}
if !poly1305.Verify(&tag, polyInput, &polyKey) {
for i := range out {
out[i] = 0
@@ -64,7 +76,6 @@ func (c *chacha20poly1305) openGeneric(dst, nonce, ciphertext, additionalData []
return nil, errOpen
}
counter[0] = 1
chacha20.XORKeyStream(out, ciphertext, &counter, &c.key)
s.XORKeyStream(out, ciphertext)
return ret, nil
}

View File

@@ -6,9 +6,13 @@ package chacha20poly1305
import (
"bytes"
cr "crypto/rand"
"crypto/cipher"
cryptorand "crypto/rand"
"encoding/hex"
mr "math/rand"
"fmt"
"log"
mathrand "math/rand"
"strconv"
"testing"
)
@@ -19,7 +23,18 @@ func TestVectors(t *testing.T) {
ad, _ := hex.DecodeString(test.aad)
plaintext, _ := hex.DecodeString(test.plaintext)
aead, err := New(key)
var (
aead cipher.AEAD
err error
)
switch len(nonce) {
case NonceSize:
aead, err = New(key)
case NonceSizeX:
aead, err = NewX(key)
default:
t.Fatalf("#%d: wrong nonce length: %d", i, len(nonce))
}
if err != nil {
t.Fatal(err)
}
@@ -42,7 +57,7 @@ func TestVectors(t *testing.T) {
}
if len(ad) > 0 {
alterAdIdx := mr.Intn(len(ad))
alterAdIdx := mathrand.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)
@@ -50,14 +65,14 @@ func TestVectors(t *testing.T) {
ad[alterAdIdx] ^= 0x80
}
alterNonceIdx := mr.Intn(aead.NonceSize())
alterNonceIdx := mathrand.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))
alterCtIdx := mathrand.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)
@@ -68,87 +83,117 @@ func TestVectors(t *testing.T) {
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
f := func(t *testing.T, nonceSize int) {
for i := 0; i < 256; i++ {
var nonce = make([]byte, nonceSize)
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)
al := mathrand.Intn(128)
pl := mathrand.Intn(16384)
ad := make([]byte, al)
plaintext := make([]byte, pl)
cryptorand.Read(key[:])
cryptorand.Read(nonce[:])
cryptorand.Read(ad)
cryptorand.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)
var (
aead cipher.AEAD
err error
)
switch len(nonce) {
case NonceSize:
aead, err = New(key[:])
case NonceSizeX:
aead, err = NewX(key[:])
default:
t.Fatalf("#%d: wrong nonce length: %d", i, len(nonce))
}
if err != nil {
t.Fatal(err)
}
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
ct := aead.Seal(nil, nonce[:], plaintext, ad)
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)
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 := mathrand.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 := mathrand.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 := mathrand.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
}
ct[alterCtIdx] ^= 0x80
}
t.Run("Standard", func(t *testing.T) { f(t, NonceSize) })
t.Run("X", func(t *testing.T) { f(t, NonceSizeX) })
}
func benchamarkChaCha20Poly1305Seal(b *testing.B, buf []byte) {
func benchamarkChaCha20Poly1305Seal(b *testing.B, buf []byte, nonceSize int) {
b.ReportAllocs()
b.SetBytes(int64(len(buf)))
var key [32]byte
var nonce [12]byte
var nonce = make([]byte, nonceSize)
var ad [13]byte
var out []byte
aead, _ := New(key[:])
var aead cipher.AEAD
switch len(nonce) {
case NonceSize:
aead, _ = New(key[:])
case NonceSizeX:
aead, _ = NewX(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) {
func benchamarkChaCha20Poly1305Open(b *testing.B, buf []byte, nonceSize int) {
b.ReportAllocs()
b.SetBytes(int64(len(buf)))
var key [32]byte
var nonce [12]byte
var nonce = make([]byte, nonceSize)
var ad [13]byte
var ct []byte
var out []byte
aead, _ := New(key[:])
var aead cipher.AEAD
switch len(nonce) {
case NonceSize:
aead, _ = New(key[:])
case NonceSizeX:
aead, _ = NewX(key[:])
}
ct = aead.Seal(ct[:0], nonce[:], buf[:], ad[:])
b.ResetTimer()
@@ -157,26 +202,54 @@ func benchamarkChaCha20Poly1305Open(b *testing.B, buf []byte) {
}
}
func BenchmarkChacha20Poly1305Open_64(b *testing.B) {
benchamarkChaCha20Poly1305Open(b, make([]byte, 64))
func BenchmarkChacha20Poly1305(b *testing.B) {
for _, length := range []int{64, 1350, 8 * 1024} {
b.Run("Open-"+strconv.Itoa(length), func(b *testing.B) {
benchamarkChaCha20Poly1305Open(b, make([]byte, length), NonceSize)
})
b.Run("Seal-"+strconv.Itoa(length), func(b *testing.B) {
benchamarkChaCha20Poly1305Seal(b, make([]byte, length), NonceSize)
})
b.Run("Open-"+strconv.Itoa(length)+"-X", func(b *testing.B) {
benchamarkChaCha20Poly1305Open(b, make([]byte, length), NonceSizeX)
})
b.Run("Seal-"+strconv.Itoa(length)+"-X", func(b *testing.B) {
benchamarkChaCha20Poly1305Seal(b, make([]byte, length), NonceSizeX)
})
}
}
func BenchmarkChacha20Poly1305Seal_64(b *testing.B) {
benchamarkChaCha20Poly1305Seal(b, make([]byte, 64))
}
var key = make([]byte, KeySize)
func BenchmarkChacha20Poly1305Open_1350(b *testing.B) {
benchamarkChaCha20Poly1305Open(b, make([]byte, 1350))
}
func ExampleNewX() {
aead, err := NewX(key)
if err != nil {
log.Fatalln("Failed to instantiate XChaCha20-Poly1305:", err)
}
func BenchmarkChacha20Poly1305Seal_1350(b *testing.B) {
benchamarkChaCha20Poly1305Seal(b, make([]byte, 1350))
}
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)
func BenchmarkChacha20Poly1305Open_8K(b *testing.B) {
benchamarkChaCha20Poly1305Open(b, make([]byte, 8*1024))
}
// Decryption.
plaintext, err := aead.Open(nil, nonce, ciphertext, nil)
if err != nil {
log.Fatalln("Failed to decrypt or authenticate message:", err)
}
func BenchmarkChacha20Poly1305Seal_8K(b *testing.B) {
benchamarkChaCha20Poly1305Seal(b, make([]byte, 8*1024))
fmt.Printf("%s\n", plaintext)
}
// Output: Attack at dawn.
// The eagle has landed.
// Gophers, gophers, gophers everywhere!
}

View File

@@ -7,6 +7,13 @@ package chacha20poly1305
var chacha20Poly1305Tests = []struct {
plaintext, aad, key, nonce, out string
}{
{
"",
"",
"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f",
"070000004041424344454647",
"a0784d7a4716f3feb4f64e7f4b39bf04",
},
{
"4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e",
"50515253c0c1c2c3c4c5c6c7",
@@ -329,4 +336,391 @@ var chacha20Poly1305Tests = []struct {
"129039b5572e8a7a8131f76a",
"2c125232a59879aee36cacc4aca5085a4688c4f776667a8fbd86862b5cfb1d57c976688fdd652eafa2b88b1b8e358aa2110ff6ef13cdc1ceca9c9f087c35c38d89d6fbd8de89538070f17916ecb19ca3ef4a1c834f0bdaa1df62aaabef2e117106787056c909e61ecd208357dd5c363f11c5d6cf24992cc873cf69f59360a820fcf290bd90b2cab24c47286acb4e1033962b6d41e562a206a94796a8ab1c6b8bade804ff9bdf5ba6062d2c1f8fe0f4dfc05720bd9a612b92c26789f9f6a7ce43f5e8e3aee99a9cd7d6c11eaa611983c36935b0dda57d898a60a0ab7c4b54",
},
// XChaCha20-Poly1305 vectors
{
"000000000000000000000000000000",
"",
"0000000000000000000000000000000000000000000000000000000000000000",
"000000000000000000000000000000000000000000000000",
"789e9689e5208d7fd9e1f3c5b5341fb2f7033812ac9ebd3745e2c99c7bbfeb",
},
{
"02dc819b71875e49f5e1e5a768141cfd3f14307ae61a34d81decd9a3367c00c7",
"",
"b7bbfe61b8041658ddc95d5cbdc01bbe7626d24f3a043b70ddee87541234cff7",
"e293239d4c0a07840c5f83cb515be7fd59c333933027e99c",
"7a51f271bd2e547943c7be3316c05519a5d16803712289aa2369950b1504dd8267222e47b13280077ecada7b8795d535",
},
{
"7afc5f3f24155002e17dc176a8f1f3a097ff5a991b02ff4640f70b90db0c15c328b696d6998ea7988edfe3b960e47824e4ae002fbe589be57896a9b7bf5578599c6ba0153c7c",
"d499bb9758debe59a93783c61974b7",
"4ea8fab44a07f7ffc0329b2c2f8f994efdb6d505aec32113ae324def5d929ba1",
"404d5086271c58bf27b0352a205d21ce4367d7b6a7628961",
"26d2b46ad58b6988e2dcf1d09ba8ab6f532dc7e0847cdbc0ed00284225c02bbdb278ee8381ebd127a06926107d1b731cfb1521b267168926492e8f77219ad922257a5be2c5e52e6183ca4dfd0ad3912d7bd1ec968065",
},
{
"",
"",
"48d8bd02c2e9947eae58327114d35e055407b5519c8019535efcb4fc875b5e2b",
"cc0a587a475caba06f8dbc09afec1462af081fe1908c2cba",
"fc3322d0a9d6fac3eb4a9e09b00b361e",
},
{
"e0862731e5",
"",
"6579e7ee96151131a1fcd06fe0d52802c0021f214960ecceec14b2b8591f62cd",
"e2230748649bc22e2b71e46a7814ecabe3a7005e949bd491",
"e991efb85d8b1cfa3f92cb72b8d3c882e88f4529d9",
},
{
"00c7dd8f440af1530b44",
"",
"ffb733657c849d50ab4ab40c4ae18f8ee2f0acf7c907afefdc04dff3537fdff3",
"02c6fd8032a8d89edbedcd1db024c09d29f08b1e74325085",
"13dbcdb8c60c3ed28449a57688edfaea89e309ab4faa6d51e532",
},
{
"7422f311ea476cf819cb8b3c77369f",
"",
"ef0d05d028d6abdd5e99d1761d2028de75ee6eb376ff0dc8036e9a8e10743876",
"f772745200b0f92e38f1d8dae79bf8138e84b301f0be74df",
"d5f992f9834df1be86b580ac59c7eae063a68072829c51bc8a26970dd3d310",
},
{
"ba09ca69450e6c7bece31a7a3f216e3b9ed0e536",
"",
"8d93e31abfe22a63faf45cbea91877050718f13fef6e2664a1892d7f23007ccf",
"260b7b3554a7e6ff8aae7dd6234077ca539689a20c1610a8",
"c99e9a768eb2ec8569bdff8a37295069552faebcafb1a76e98bc7c5b6b778b3d1b6291f0",
},
{
"424ec5f98a0fdc5a7388532d11ab0edb26733505627b7f2d1f",
"",
"b68d5e6c46cdbb0060445522bdc5c562ae803b6aaaf1e103c146e93527a59299",
"80bb5dc1dd44a35ec4f91307f1a95b4ca31183a1a596fb7c",
"29d4eed0fff0050d4bb40de3b055d836206e7cbd62de1a63904f0cf731129ba3f9c2b9d46251a6de89",
},
{
"e7e4515cc0a6ef0491af983eaac4f862d6e726758a3c657f4ec444841e42",
"",
"e31a1d3af650e8e2848bd78432d89ecd1fdece9842dc2792e7bda080f537b17b",
"f3f09905e9a871e757348834f483ed71be9c0f437c8d74b0",
"f5c69528963e17db725a28885d30a45194f12848b8b7644c7bded47a2ee83e6d4ef34006305cfdf82effdced461d",
},
{
"0f5ca45a54875d1d19e952e53caeaa19389342f776dab11723535503338d6f77202a37",
"",
"1031bc920d4fcb4434553b1bf2d25ab375200643bf523ff037bf8914297e8dca",
"4cc77e2ef5445e07b5f44de2dc5bf62d35b8c6f69502d2bf",
"7aa8669e1bfe8b0688899cdddbb8cee31265928c66a69a5090478da7397573b1cc0f64121e7d8bff8db0ddd3c17460d7f29a12",
},
{
"c45578c04c194994e89025c7ffb015e5f138be3cd1a93640af167706aee2ad25ad38696df41ad805",
"",
"ac8648b7c94328419c668ce1c57c71893adf73abbb98892a4fc8da17400e3a5e",
"4ad637facf97af5fc03207ae56219da9972858b7430b3611",
"49e093fcd074fb67a755669119b8bd430d98d9232ca988882deeb3508bde7c00160c35cea89092db864dcb6d440aefa5aacb8aa7b9c04cf0",
},
{
"b877bfa192ea7e4c7569b9ee973f89924d45f9d8ed03c7098ad0cad6e7880906befedcaf6417bb43efabca7a2f",
"",
"125e331d5da423ecabc8adf693cdbc2fc3d3589740d40a3894f914db86c02492",
"913f8b2f08006e6260de41ec3ee01d938a3e68fb12dc44c4",
"1be334253423c90fc8ea885ee5cd3a54268c035ba8a2119e5bd4f7822cd7bf9cb4cec568d5b6d6292606d32979e044df3504e6eb8c0b2fc7e2a0e17d62",
},
{
"d946484a1df5f85ff72c92ff9e192660cde5074bd0ddd5de900c35eb10ed991113b1b19884631bc8ceb386bcd83908061ce9",
"",
"b7e83276373dcf8929b6a6ea80314c9de871f5f241c9144189ee4caf62726332",
"f59f9d6e3e6c00720dc20dc21586e8330431ebf42cf9180e",
"a38a662b18c2d15e1b7b14443cc23267a10bee23556b084b6254226389c414069b694159a4d0b5abbe34de381a0e2c88b947b4cfaaebf50c7a1ad6c656e386280ad7",
},
{
"d266927ca40b2261d5a4722f3b4da0dd5bec74e103fab431702309fd0d0f1a259c767b956aa7348ca923d64c04f0a2e898b0670988b15e",
"",
"a60e09cd0bea16f26e54b62b2908687aa89722c298e69a3a22cf6cf1c46b7f8a",
"92da9d67854c53597fc099b68d955be32df2f0d9efe93614",
"9dd6d05832f6b4d7f555a5a83930d6aed5423461d85f363efb6c474b6c4c8261b680dea393e24c2a3c8d1cc9db6df517423085833aa21f9ab5b42445b914f2313bcd205d179430",
},
{
"f7e11b4d372ed7cb0c0e157f2f9488d8efea0f9bbe089a345f51bdc77e30d1392813c5d22ca7e2c7dfc2e2d0da67efb2a559058d4de7a11bd2a2915e",
"",
"194b1190fa31d483c222ec475d2d6117710dd1ac19a6f1a1e8e894885b7fa631",
"6b07ea26bb1f2d92e04207b447f2fd1dd2086b442a7b6852",
"25ae14585790d71d39a6e88632228a70b1f6a041839dc89a74701c06bfa7c4de3288b7772cb2919818d95777ab58fe5480d6e49958f5d2481431014a8f88dab8f7e08d2a9aebbe691430011d",
},
{
"",
"1e2b11e3",
"70cd96817da85ede0efdf03a358103a84561b25453dee73735e5fb0161b0d493",
"5ddeba49f7266d11827a43931d1c300dd47a3c33f9f8bf9b",
"592fc4c19f3cddec517b2a00f9df9665",
},
{
"81b3cb7eb3",
"efcfd0cf",
"a977412f889281a6d75c24186f1bfaa00dcc5132f0929f20ef15bbf9e63c4c91",
"3f26ca997fb9166d9c615babe3e543ca43ab7cab20634ac5",
"8e4ade3e254cf52e93eace5c46667f150832725594",
},
{
"556f97f2ebdb4e949923",
"f7cee2e0",
"787b3e86546a51028501c801dadf8d5b996fd6f6f2363d5d0f900c44f6a2f4c2",
"7fa6af59a779657d1cada847439ea5b92a1337cfbebbc3b1",
"608ec22dae5f48b89d6f0d2a940d5a7661e0a8e68aaee4ad2d96",
},
{
"c06847a36ad031595b60edd44dc245",
"d4175e1f",
"16de31e534dd5af32801b1acd0ec541d1f8d82bcbc3af25ec815f3575b7aca73",
"29f6656972838f56c1684f6a278f9e4e207b51d68706fc25",
"836082cc51303e500fceade0b1a18f1d97d64ff41cc81754c07d6231b9fd1b",
},
{
"0d03c22ced7b29c6741e72166cd61792028dfc80",
"e505dad0",
"ac2b426e5c5c8e00666180a3410e8a2f6e52247a43aecea9622163e8433c93b2",
"c1123430468228625967bbc0fbd0f963e674372259ff2deb",
"bf09979bf4fed2eec6c97f6e1bcfac35eeffc6d54a55cc1d83d8767ae74db2d7cdfbc371",
},
{
"05bf00e1707cffe7ccbd06a9f846d0fd471a700ed43b4facb8",
"d863bebe",
"66c121f0f84b95ba1e6d29e7d81900bc96a642421b9b6105ae5eb5f2e7b07577",
"8ed6ae211a661e967995b71f7316ba88f44322bb62b4187b",
"b2c5c85d087e0305e9058fba52b661fb3d7f21cb4d4915ae048bc9e5d66a2f921dd4a1c1b030f442c9",
},
{
"5f2b91a9be8bfaa21451ddc6c5cf28d1cc00b046b76270b95cda3c280c83",
"a8750275",
"39592eb276877fca9dd11e2181c0b23127328407e3cc11e315e5d748f43529cc",
"1084bebd756f193d9eea608b3a0193a5028f8ced19684821",
"eaee1f49ac8468154c601a5dd8b84d597602e5a73534b5fad5664f97d0f017dd114752be969679cf610340c6a312",
},
{
"01e8e269b5376943f3b2d245483a76461dc8b7634868b559165f5dbb20839029fae9bb",
"a1e96da0",
"b8386123b87e50d9d046242cf1bf141fce7f65aff0fba76861a2bc72582d6ff0",
"0fbe2a13a89bea031de96d78f9f11358ba7b6a5e724b4392",
"705ec3f910ec85c6005baa99641de6ca43332ff52b5466df6af4ffbe4ef2a376a8f871d1eae503b5896601fee005cdc1f4c1c6",
},
{
"706daba66e2edb1f828f3c0051e3cc214b12210bde0587bba02580f741a4c83e84d4e9fe961120cd",
"87663c5a",
"d519d82ba8a3f0c3af9efe36682b62e285167be101a526c1d73000f169c2a486",
"ad651aac536978e2bc1a54816345ac5e9a9b43b3d9cc0bfc",
"07051b5e72da9c4811beb07ff9f95aece67eae18420eb3f0e8bb8a5e26d4b483fa40eb063a2354842d0c8a41d981cc2b77c530b496db01c8",
},
{
"1f6b24f2f0d9eb460d726bed953d66fcc4ecc29da6ed2fd711358eac3b2609d74ba3e21885156cde3cbe6d9b6f",
"f5efbc4e",
"86068a00544f749ad4ad15bb8e427ae78577ae22f4ca9778efff828ba10f6b20",
"c8420412c9626dcd34ece14593730f6aa2d01ec51cacd59f",
"a99f6c88eac35bb34439e34b292fe9db8192446dcdc81e2192060ec36d98b47de2bee12bf0f67cb24fb0949c07733a6781cd9455cdc61123f506886b04",
},
{
"d69389d83362be8c0ddb738659a6cc4bd65d88cb5b525232f4d59a7d4751a7203c254923ecb6873e803220aab19664789a63",
"bc35fb1c",
"835855b326a98682b3075b4d7f1b89059c3cdfc547d4296c80ce7a77ba6434e3",
"c27cb75fc319ba431cbaeb120341d0c4745d883eb47e92bc",
"db6dc3f9a0f4f1a6df2495a88910550c2c6205478bfc1e81282e34b5b36d984c72c0509c522c987c61d2e640ced69402a6d33aa10d3d0b81e680b3c19bc142e81923",
},
{
"a66a7f089115ed9e2d5bb5d33d7282a7afe401269b00f2a233a59c04b794a42901d862140b61d18d7c7f0ad5da040613e557f8abc74219",
"2c060aaf",
"99758aa7714fd707931f71803eefe04a06955041308a0b2a1104313b270ccf34",
"63f690d8926408c7a34fe8ddd505a8dc58769dc74e8d5da6",
"92b21ee85afcd8996ac28f3aed1047ad814d6e4ffbca3159af16f26eded83e4abda9e4275eb3ff0ad90dffe09f2d443b628f824f680b46527ce0128e8de1920f7c44350ebe7913",
},
{
"f955183b1f762d4536d3f6885ea7f5ac27414caf46c2e24a2fd3bd56b91c53d840fb657224565e0a6f686f8ba320e04a401057399d9a3d995ab17c13",
"c372ddc5",
"a188be3795b2ca2e69b6aa263244f0963c492d694cf6c9b705a1d7045f3f2a26",
"51bb484ea094ee140474681e1c838e4442fd148de2cc345a",
"48759a5ddfdd829d11de8e0c538ce4a9c475faab6912039b568ad92d737d172fc1eb0c00c3793de6dddbfacfdbbc7f44aeba33684e18005aa982b6fc6c556e63bb90ff7a1dde8153a63eabe0",
},
{
"",
"e013cd0bfafd486d",
"af3d3ba094d38299ecb91c17bfe3d085da5bd42e11acf8acb5bc26a4be9a7583",
"7dd63c14173831f109761b1c1abe18f6ba937d825957011b",
"8bc685a7d9d501952295cd25d8c92517",
},
{
"284b64597e",
"31d013e53aa3ea79",
"93c77409d7f805f97fe683b2dd6ee06152a5e918b3eed5b731acccffdcb2cc04",
"3d331e90c4597cf0c30d1b7cfbd07bcb6ab927eda056873c",
"3538a449d6c18d148a8c6cb76f1bc288657ac7036a",
},
{
"9fe67f5c78180ede8274",
"188608d230d75860",
"b7cca89a82640aea6f80b458c9e633d88594fb498959d39787be87030892d48f",
"ef891d50e8c08958f814590fdb7a9f16c61cc2aae1682109",
"bbb40c30f3d1391a5b38df480cbbf964b71e763e8140751f4e28",
},
{
"3a2826b6f7e3d542e4ded8f23c9aa4",
"260033e789c4676a",
"7fe2731214f2b4b42f93217d43f1776498413725e4f6cfe62b756e5a52df10ea",
"888728219ebf761547f5e2218532714403020e5a8b7a49d0",
"fe0328f883fcd88930ae017c0f54ed90f883041efc020e959125af370c1d47",
},
{
"91858bf7b969005d7164acbd5678052b651c53e0",
"f3cc53ecafcbadb3",
"d69c04e9726b22d51f97bc9da0f0fda86736e6b78e8ef9f6f0000f79890d6d43",
"6de3c45161b434e05445cf6bf69eef7bddf595fc6d8836bd",
"a8869dd578c0835e120c843bb7dedc7a1e9eae24ffd742be6bf5b74088a8a2c550976fcb",
},
{
"b3b1a4d6b2a2b9c5a1ca6c1efaec34dcfa1acbe7074d5e10cc",
"d0f72bd16cda3bae",
"2b317857b089c9305c49b83019f6e158bc4ecc3339b39ade02ee10c37c268da0",
"cb5fa6d1e14a0b4bdf350cd10c8a7bd638102911ec74be09",
"e6372f77c14343650074e07a2b7223c37b29242224b722b24d63b5956f27aa64ce7ce4e39cd14a2787",
},
{
"057d3e9f865be7dff774938cab6d080e50cf9a1593f53c0063201e0bb7ae",
"fd3881e505c8b12d",
"36e42b1ef1ee8d068f09b5fad3ee43d98d34aa3e3f994f2055aee139da71de9d",
"24124da36473d01bdca30297c9eef4fe61955525a453da17",
"a8b28139524c98c1f8776f442eac4c22766fe6aac83224641c58bf021fc9cb709ec4706f49c2d0c1828acf2bfe8d",
},
{
"bd8f13e928c34d67a6c70c3c7efdf2982ecc31d8cee68f9cbddc75912cd828ac93d28b",
"193206c8fcc5b19b",
"6e47c40c9d7b757c2efca4d73890e4c73f3c859aab4fdc64b564b8480dd84e72",
"ca31340ae20d30fe488be355cb36652c5db7c9d6265a3e95",
"a121efc5e1843deade4b8adbfef1808de4eda222f176630ad34fb476fca19e0299e4a13668e53cf13882035ba4f04f47c8b4e3",
},
{
"23067a196e977d10039c14ff358061c918d2148d31961bb3e12c27c5122383cb25c4d1d79c775720",
"62338d02fff78a00",
"2c5c79c92d91fb40ef7d0a77e8033f7b265e3bab998b8116d17b2e62bb4f8a09",
"024736adb1d5c01006dffd8158b57936d158d5b42054336d",
"46d0905473a995d38c7cdbb8ef3da96ecc82a22c5b3c6c9d1c4a61ae7a17db53cb88c5f7eccf2da1d0c417c300f989b4273470e36f03542f",
},
{
"252e966c680329eb687bff813b78fea3bfd3505333f106c6f9f45ba69896723c41bb763793d9b266e897d05557",
"1e93e0cfe6523380",
"9ec6fd1baa13ee16aec3fac16718a2baccf18a403cec467c25b7448e9b321110",
"e7120b1018ab363a36e61102eedbcbe9847a6cbacaa9c328",
"2934f034587d4144bb11182679cd2cd1c99c8088d18e233379e9bc9c41107a1f57a2723ecc7b9ba4e6ee198adf0fd766738e828827dc73136fc5b996e9",
},
{
"6744aefcb318f12bc6eeb59d4d62f7eb95f347cea14bd5158415f07f84e4e3baa3de07512d9b76095ac1312cfcb1bb77f499",
"608d2a33ce5d0b04",
"0f665cbdaaa40f4f5a00c53d951b0a98aac2342be259a52670f650a783be7aab",
"378bdb57e957b8c2e1500c9513052a3b02ff5b7edbd4a3a7",
"341c60fcb374b394f1b01a4a80aedef49ab0b67ec963675e6eec43ef106f7003be87dbf4a8976709583dccc55abc7f979c4721837e8664a69804ea31736aa2af615a",
},
{
"bcf1004f988220b7ce063ef2ec4e276ffd074f0a90aa807de1532679d2a1505568eaa4192d9a6ea52cc500322343ce9f8e68cc2c606d83",
"e64bd00126c8792c",
"58e65150d6a15dcefbc14a171998987ad0d709fb06a17d68d6a778759681c308",
"106d2bd120b06e4eb10bc674fe55c77a3742225268319303",
"a28052a6686a1e9435fee8702f7da563a7b3d7b5d3e9e27f11abf73db309cd1f39a34756258c1c5c7f2fb12cf15eb20175c2a08fc93dd19c5e482ef3fbef3d8404a3cfd54a7baf",
},
{
"acd08d4938a224b4cb2d723bf75420f3ea27b698fadd815bb7db9548a05651398644354334e69f8e4e5503bf1a6f92b38e860044a7edca6874038ce1",
"28a137808d0225b8",
"a031203b963a395b08be55844d81af39d19b23b7cc24b21afa31edc1eea6edd6",
"e8b31c52b6690f10f4ae62ba9d50ba39fb5edcfb78400e35",
"35cf39ba31da95ac9b661cdbd5e9c9655d13b8ff065c4ec10c810833a47a87d8057dd1948a7801bfe6904b49fed0aabfb3cd755a1a262d372786908ddcf64cae9f71cb9ed199c3ddacc50116",
},
{
"",
"cda7ee2857e09e9054ef6806",
"d91dffb18132d8dd3d144a2f10ba28bc5df36cb60369f3b19893ec91db3cf904",
"ee56f19c62b0438da6a0d9e01844313902be44f84a6a4ce7",
"ccd48b61a5683c195d4424009eb1d147",
},
{
"350f4c7ac2",
"7c104b539c1d2ae022434cd6",
"cbb61e369117f9250f68fa707240c554359262a4d66c757f80e3aeb6920894fb",
"fbb14c9943444eac5413c6f5c8095451eddece02c9461043",
"b5c6a35865ed8e5216ff6c77339ee1ab570de50e51",
},
{
"4f0d61d3ea03a44a8df0",
"51c20a8ae9e9794da931fe23",
"ba6ced943aa62f9261d7513b822e02054e099acafb5360f0d850064da48b5a4f",
"04c68cb50cdbb0ec03f8381cf59b886e64c40548bf8e3f82",
"ea45a73957e2a853655623f2a3bb58791f7ea36dd2957ed66ffa",
},
{
"4fbdd4d4293a8f34fdbc8f3ad44cf6",
"8212f315e3759c3253c588bb",
"5354791bc2370415811818e913e310dd12e6a0cf5dcab2b6424816eecccf4b65",
"7ee6353c2fbc73c9ebc652270bc86e4008e09583e623e679",
"50a354811a918e1801fb567621a8924baf8dd79da6d36702855d3753f1319c",
},
{
"5a6f68b5a9a9920ca9c6edf5be7c0af150a063c4",
"9a524aa62938fb7a1e50ed06",
"fd91605a6ad85d8ba7a71b08dce1032aa9992bf4f28d407a53ddda04c043cada",
"46791d99d6de33e79025bf9e97c198e7cf409614c6284b4d",
"648033c1eb615467e90b7d3ac24202d8b849549141f9bab03e9e910c29b8eab3d4fb3f2c",
},
{
"d9318c2c0d9ed89e35d242a6b1d496e7e0c5bbdf77eba14c56",
"a16053c35fbe8dc93c14a81f",
"f21406aec83134ebf7bc48c6d0f45acb5f341fbc7d3b5a9bff3ea1333c916af7",
"de6b977be450d5efa7777e006802ddbb10814a22da1c3cd9",
"8d3dad487d5161663da830b71c3e24ec5cdb74d858cbb73b084ed0902198532aad3a18416966bff223",
},
{
"68d0ee08d38cb4bcc9268fee3030666e70e41fcabf6fe06536eeec43eec5",
"11e09447d40b22dc98070eec",
"da5ee1ec02eab13220fcb94f16efec848a8dd57c0f4d67955423f5d17fde5aa3",
"8f13e61d773a250810f75d46bf163a3f9205be5751f6049a",
"92a103b03764c1ad1f88500d22eeae5c0fe1044c872987c0b97affc5e8c3d783f8cc28a11dc91990ea22dd1bad74",
},
{
"a1d960bda08efcf19e136dc1e8b05b6b381c820eda5f9a8047e1a2dd1803a1e4d11a7f",
"aa73d8d4aaa0cfd9d80a9ae8",
"08028833d617c28ba75b48f177cb5da87189189abb68dcb8974eca9230c25945",
"f7b6f34a910fd11588f567de8555932291f7df05f6e2b193",
"99cfc4cca193998bae153b744e6c94a82a2867780aa0f43acddb7c433fcb297311313ec2199f00d7ca7da0646b40113c60e935",
},
{
"3b4ae39a745b6247ce5baf675ec36c5065b1bf76c8379eab4b769961d43a753896d068938017777e",
"128c017a985052f8cdbc6b28",
"4683d5caff613187a9b16af897253848e9c54fc0ec319de62452a86961d3cbb2",
"5612a13c2da003b91188921cbac3fa093eba99d8cbbb51ff",
"91a98b93b2174257175f7c882b45cc252e0db8667612bd270c1c12fe28b6bf209760bf8f370318f92ae3f88a5d4773b05714132cc28dddb8",
},
{
"22ccf680d2995ef6563de281cff76882a036a59ad73f250e710b3040590d69bccde8a8411abe8b0d3cb728ca82",
"13a97d0a167a61aa21e531ec",
"9e140762eed274948b66de25e6e8f36ab65dc730b0cb096ef15aaba900a5588c",
"d0e9594cfd42ab72553bf34062a263f588bb8f1fc86a19f5",
"f194fc866dfba30e42c4508b7d90b3fa3f8983831ede713334563e36aa861f2f885b40be1dbe20ba2d10958a12823588d4bbbefb81a87d87315204f5e3",
},
{
"a65f5d10c482b3381af296e631eb605eba6a11ccec6ceab021460d0bd35feb676ec6dbba5d4ad6c9f4d683ea541035bc80fa",
"f15ae71ffed50a8fcc4996b0",
"f535d60e8b75ac7e526041eed86eb4d65ae7e315eff15dba6c0133acc2a6a4bf",
"01ba61691ebb3c66d2f94c1b1c597ecd7b5ff7d2a30be405",
"d79e7c3893df5a5879c2f0a3f7ca619f08e4540f3ac7db35790b4211b9d47ae735adadf35fd47252a4763e3fd2b2cd8157f6ea7986108a53437962670a97d68ee281",
},
{
"8c014655b97f6da76b0b168b565fd62de874c164fd7e227346a0ec22c908bed1e2a0b429620e6f3a68dd518f13a2c0250608a1cb08a7c3",
"10a7eff999029c5040c1b3bd",
"bf11af23e88c350a443493f6fa0eb34f234f4daa2676e26f0701bce5642d13f4",
"f14c97392afd2e32e2c625910ca029f9b6e81676c79cc42f",
"78d5226f372d5d60681dbfc749d12df74249f196b0cbf14fa65a3a59dc65ae458455ec39baa1df3397afe752bb06f6f13bf03c99abda7a95c1d0b73fd92d5f888a5f6f889a9aea",
},
{
"66234d7a5b71eef134d60eccf7d5096ee879a33983d6f7a575e3a5e3a4022edccffe7865dde20b5b0a37252e31cb9a3650c63e35b057a1bc200a5b5b",
"ccc2406f997bcae737ddd0f5",
"d009eeb5b9b029577b14d200b7687b655eedb7d74add488f092681787999d66d",
"99319712626b400f9458dbb7a9abc9f5810f25b47fc90b39",
"543a2bbf52fd999027ae7c297353f3ce986f810bc2382583d0a81fda5939e4c87b6e8d262790cd614d6f753d8035b32adf43acc7f6d4c2c44289538928564b6587c2fcb99de1d8e34ffff323",
},
}

View File

@@ -0,0 +1,104 @@
// Copyright 2018 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 (
"crypto/cipher"
"encoding/binary"
"errors"
"golang.org/x/crypto/internal/chacha20"
)
type xchacha20poly1305 struct {
key [8]uint32
}
// NewX returns a XChaCha20-Poly1305 AEAD that uses the given 256-bit key.
//
// XChaCha20-Poly1305 is a ChaCha20-Poly1305 variant that takes a longer nonce,
// suitable to be generated randomly without risk of collisions. It should be
// preferred when nonce uniqueness cannot be trivially ensured, or whenever
// nonces are randomly generated.
func NewX(key []byte) (cipher.AEAD, error) {
if len(key) != KeySize {
return nil, errors.New("chacha20poly1305: bad key length")
}
ret := new(xchacha20poly1305)
ret.key[0] = binary.LittleEndian.Uint32(key[0:4])
ret.key[1] = binary.LittleEndian.Uint32(key[4:8])
ret.key[2] = binary.LittleEndian.Uint32(key[8:12])
ret.key[3] = binary.LittleEndian.Uint32(key[12:16])
ret.key[4] = binary.LittleEndian.Uint32(key[16:20])
ret.key[5] = binary.LittleEndian.Uint32(key[20:24])
ret.key[6] = binary.LittleEndian.Uint32(key[24:28])
ret.key[7] = binary.LittleEndian.Uint32(key[28:32])
return ret, nil
}
func (*xchacha20poly1305) NonceSize() int {
return NonceSizeX
}
func (*xchacha20poly1305) Overhead() int {
return 16
}
func (x *xchacha20poly1305) Seal(dst, nonce, plaintext, additionalData []byte) []byte {
if len(nonce) != NonceSizeX {
panic("chacha20poly1305: bad nonce length passed to Seal")
}
// XChaCha20-Poly1305 technically supports a 64-bit counter, so there is no
// size limit. However, since we reuse the ChaCha20-Poly1305 implementation,
// the second half of the counter is not available. This is unlikely to be
// an issue because the cipher.AEAD API requires the entire message to be in
// memory, and the counter overflows at 256 GB.
if uint64(len(plaintext)) > (1<<38)-64 {
panic("chacha20poly1305: plaintext too large")
}
hNonce := [4]uint32{
binary.LittleEndian.Uint32(nonce[0:4]),
binary.LittleEndian.Uint32(nonce[4:8]),
binary.LittleEndian.Uint32(nonce[8:12]),
binary.LittleEndian.Uint32(nonce[12:16]),
}
c := &chacha20poly1305{
key: chacha20.HChaCha20(&x.key, &hNonce),
}
// The first 4 bytes of the final nonce are unused counter space.
cNonce := make([]byte, NonceSize)
copy(cNonce[4:12], nonce[16:24])
return c.seal(dst, cNonce[:], plaintext, additionalData)
}
func (x *xchacha20poly1305) Open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) {
if len(nonce) != NonceSizeX {
panic("chacha20poly1305: bad nonce length passed to Open")
}
if len(ciphertext) < 16 {
return nil, errOpen
}
if uint64(len(ciphertext)) > (1<<38)-48 {
panic("chacha20poly1305: ciphertext too large")
}
hNonce := [4]uint32{
binary.LittleEndian.Uint32(nonce[0:4]),
binary.LittleEndian.Uint32(nonce[4:8]),
binary.LittleEndian.Uint32(nonce[8:12]),
binary.LittleEndian.Uint32(nonce[12:16]),
}
c := &chacha20poly1305{
key: chacha20.HChaCha20(&x.key, &hNonce),
}
// The first 4 bytes of the final nonce are unused counter space.
cNonce := make([]byte, NonceSize)
copy(cNonce[4:12], nonce[16:24])
return c.open(dst, cNonce[:], ciphertext, additionalData)
}