mirror of
https://github.com/taigrr/arc
synced 2025-01-18 04:33:13 -08:00
initial import
This commit is contained in:
106
vendor/github.com/wg/ecies/aead.go
generated
vendored
Normal file
106
vendor/github.com/wg/ecies/aead.go
generated
vendored
Normal file
@@ -0,0 +1,106 @@
|
||||
// Copyright (C) 2016 - Will Glozer. All rights reserved.
|
||||
|
||||
package ecies
|
||||
|
||||
import (
|
||||
"crypto/cipher"
|
||||
"crypto/subtle"
|
||||
"errors"
|
||||
|
||||
"github.com/wg/ecies/chacha20poly1305"
|
||||
"github.com/wg/ecies/xchacha20poly1305"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrInvalidKeySize = errors.New("cipher: invalid key length")
|
||||
ErrAuthFailed = errors.New("cipher: message auth failed")
|
||||
)
|
||||
|
||||
type AEAD struct {
|
||||
key []byte
|
||||
nonceSize int
|
||||
tagSize int
|
||||
Cipher
|
||||
}
|
||||
|
||||
func NewXChaCha20Poly1305(key []byte) (cipher.AEAD, error) {
|
||||
if len(key) != xchacha20poly1305.KeySize {
|
||||
return nil, ErrInvalidKeySize
|
||||
}
|
||||
|
||||
core := &xchacha20poly1305.XChaCha20Poly1305{}
|
||||
|
||||
return &AEAD{
|
||||
key: key,
|
||||
nonceSize: xchacha20poly1305.NonceSize,
|
||||
tagSize: xchacha20poly1305.TagSize,
|
||||
Cipher: core,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func NewChaCha20Poly1305(key []byte) (cipher.AEAD, error) {
|
||||
if len(key) != chacha20poly1305.KeySize {
|
||||
return nil, ErrInvalidKeySize
|
||||
}
|
||||
|
||||
core := &chacha20poly1305.ChaCha20Poly1305{}
|
||||
|
||||
return &AEAD{
|
||||
key: key,
|
||||
nonceSize: chacha20poly1305.NonceSize,
|
||||
tagSize: chacha20poly1305.TagSize,
|
||||
Cipher: core,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (a *AEAD) NonceSize() int {
|
||||
return a.nonceSize
|
||||
}
|
||||
|
||||
func (a *AEAD) Overhead() int {
|
||||
return a.tagSize
|
||||
}
|
||||
|
||||
func (a *AEAD) Open(dst, nonce, src, aad []byte) ([]byte, error) {
|
||||
err := a.Init(a.key, nonce)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
n := len(src) - a.tagSize
|
||||
dst, ret := extend(dst, n)
|
||||
src, tag := src[:n], src[n:]
|
||||
|
||||
a.Auth(aad)
|
||||
a.Decrypt(dst, src)
|
||||
|
||||
if subtle.ConstantTimeCompare(tag, a.Tag(nil)) != 1 {
|
||||
return nil, ErrAuthFailed
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (a *AEAD) Seal(dst, nonce, src, aad []byte) []byte {
|
||||
err := a.Init(a.key, nonce)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
n := len(src) + a.tagSize
|
||||
dst, ret := extend(dst, n)
|
||||
tag := dst[len(src):]
|
||||
|
||||
a.Auth(aad)
|
||||
a.Encrypt(dst, src)
|
||||
a.Tag(tag[:0])
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func extend(dst []byte, n int) ([]byte, []byte) {
|
||||
if len(dst) < n {
|
||||
dst = append(dst, make([]byte, n)...)
|
||||
}
|
||||
return dst, dst[:n]
|
||||
}
|
||||
69
vendor/github.com/wg/ecies/aead_test.go
generated
vendored
Normal file
69
vendor/github.com/wg/ecies/aead_test.go
generated
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
// Copyright (C) 2016 - Will Glozer. All rights reserved.
|
||||
|
||||
package ecies
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestRFC7539(t *testing.T) {
|
||||
plaintext := []byte{
|
||||
0x4c, 0x61, 0x64, 0x69, 0x65, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x47, 0x65, 0x6e, 0x74, 0x6c,
|
||||
0x65, 0x6d, 0x65, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x61, 0x73,
|
||||
0x73, 0x20, 0x6f, 0x66, 0x20, 0x27, 0x39, 0x39, 0x3a, 0x20, 0x49, 0x66, 0x20, 0x49, 0x20, 0x63,
|
||||
0x6f, 0x75, 0x6c, 0x64, 0x20, 0x6f, 0x66, 0x66, 0x65, 0x72, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x6f,
|
||||
0x6e, 0x6c, 0x79, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x74, 0x69, 0x70, 0x20, 0x66, 0x6f, 0x72, 0x20,
|
||||
0x74, 0x68, 0x65, 0x20, 0x66, 0x75, 0x74, 0x75, 0x72, 0x65, 0x2c, 0x20, 0x73, 0x75, 0x6e, 0x73,
|
||||
0x63, 0x72, 0x65, 0x65, 0x6e, 0x20, 0x77, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x62, 0x65, 0x20, 0x69,
|
||||
0x74, 0x2e,
|
||||
}
|
||||
|
||||
aad := []byte{
|
||||
0x50, 0x51, 0x52, 0x53, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
|
||||
}
|
||||
|
||||
key := []byte{
|
||||
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
|
||||
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
|
||||
}
|
||||
|
||||
nonce := []byte{
|
||||
0x07, 0x00, 0x00, 0x00,
|
||||
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
|
||||
}
|
||||
|
||||
ciphertext := []byte{
|
||||
0xd3, 0x1a, 0x8d, 0x34, 0x64, 0x8e, 0x60, 0xdb, 0x7b, 0x86, 0xaf, 0xbc, 0x53, 0xef, 0x7e, 0xc2,
|
||||
0xa4, 0xad, 0xed, 0x51, 0x29, 0x6e, 0x08, 0xfe, 0xa9, 0xe2, 0xb5, 0xa7, 0x36, 0xee, 0x62, 0xd6,
|
||||
0x3d, 0xbe, 0xa4, 0x5e, 0x8c, 0xa9, 0x67, 0x12, 0x82, 0xfa, 0xfb, 0x69, 0xda, 0x92, 0x72, 0x8b,
|
||||
0x1a, 0x71, 0xde, 0x0a, 0x9e, 0x06, 0x0b, 0x29, 0x05, 0xd6, 0xa5, 0xb6, 0x7e, 0xcd, 0x3b, 0x36,
|
||||
0x92, 0xdd, 0xbd, 0x7f, 0x2d, 0x77, 0x8b, 0x8c, 0x98, 0x03, 0xae, 0xe3, 0x28, 0x09, 0x1b, 0x58,
|
||||
0xfa, 0xb3, 0x24, 0xe4, 0xfa, 0xd6, 0x75, 0x94, 0x55, 0x85, 0x80, 0x8b, 0x48, 0x31, 0xd7, 0xbc,
|
||||
0x3f, 0xf4, 0xde, 0xf0, 0x8e, 0x4b, 0x7a, 0x9d, 0xe5, 0x76, 0xd2, 0x65, 0x86, 0xce, 0xc6, 0x4b,
|
||||
0x61, 0x16,
|
||||
}
|
||||
|
||||
tag := []byte{
|
||||
0x1a, 0xe1, 0x0b, 0x59, 0x4f, 0x09, 0xe2, 0x6a, 0x7e, 0x90, 0x2e, 0xcb, 0xd0, 0x60, 0x06, 0x91,
|
||||
}
|
||||
|
||||
aead, err := NewChaCha20Poly1305(key)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
sealed := aead.Seal(nil, nonce, plaintext, aad)
|
||||
if !bytes.Equal(sealed, append(ciphertext, tag...)) {
|
||||
t.Fatal("Seal: ciphertext|tag incorrect")
|
||||
}
|
||||
|
||||
opened, err := aead.Open(nil, nonce, append(ciphertext, tag...), aad)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !bytes.Equal(opened, plaintext) {
|
||||
t.Fatal("Open: plaintext incorrect")
|
||||
}
|
||||
}
|
||||
90
vendor/github.com/wg/ecies/box.go
generated
vendored
Normal file
90
vendor/github.com/wg/ecies/box.go
generated
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
// Copyright (C) 2016 - Will Glozer. All rights reserved.
|
||||
|
||||
package ecies
|
||||
|
||||
import (
|
||||
"crypto/subtle"
|
||||
"errors"
|
||||
|
||||
"github.com/dchest/blake2b"
|
||||
"github.com/wg/ecies/xchacha20poly1305"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrBoxAuthFailed = errors.New("box: message auth failed")
|
||||
ErrBoxTooSmall = errors.New("box: destination too small")
|
||||
ErrBoxInvariant = errors.New("box: invariant violation")
|
||||
)
|
||||
|
||||
type Box struct {
|
||||
key [xchacha20poly1305.KeySize]byte
|
||||
xchacha20poly1305.XChaCha20Poly1305
|
||||
}
|
||||
|
||||
func NewX25519XChaCha20Poly1305(publicKey, privateKey *[32]byte) (*Box, error) {
|
||||
var secret [32]byte
|
||||
if err := X25519(&secret, publicKey, privateKey); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return newXChaCha20Poly1305Box(secret[:])
|
||||
}
|
||||
|
||||
func NewX448XChaCha20Poly1305(publicKey, privateKey *[56]byte) (*Box, error) {
|
||||
var secret [56]byte
|
||||
if err := X448(&secret, publicKey, privateKey); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return newXChaCha20Poly1305Box(secret[:])
|
||||
}
|
||||
|
||||
func (b *Box) Seal(dst, msg, nonce []byte) error {
|
||||
if cap(dst) < len(msg)+xchacha20poly1305.TagSize {
|
||||
return ErrBoxTooSmall
|
||||
}
|
||||
|
||||
if err := b.Init(b.key[:], nonce); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
n := len(msg)
|
||||
b.Encrypt(dst, msg)
|
||||
b.Tag(dst[n:n])
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *Box) Open(dst, msg, nonce []byte) error {
|
||||
if cap(dst) < len(msg)-xchacha20poly1305.TagSize {
|
||||
return ErrBoxTooSmall
|
||||
}
|
||||
|
||||
if err := b.Init(b.key[:], nonce); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
n := len(msg) - xchacha20poly1305.TagSize
|
||||
msg, tag := msg[:n], msg[n:]
|
||||
b.Decrypt(dst, msg)
|
||||
|
||||
if subtle.ConstantTimeCompare(tag, b.Tag(nil)) != 1 {
|
||||
return ErrBoxAuthFailed
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func newXChaCha20Poly1305Box(secret []byte) (*Box, error) {
|
||||
h, err := blake2b.New(&blake2b.Config{
|
||||
Size: xchacha20poly1305.KeySize,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, ErrBoxInvariant
|
||||
}
|
||||
|
||||
box := &Box{}
|
||||
h.Write(secret)
|
||||
h.Sum(box.key[:0])
|
||||
|
||||
return box, nil
|
||||
}
|
||||
124
vendor/github.com/wg/ecies/box_test.go
generated
vendored
Normal file
124
vendor/github.com/wg/ecies/box_test.go
generated
vendored
Normal file
@@ -0,0 +1,124 @@
|
||||
// Copyright (C) 2016 - Will Glozer. All rights reserved.
|
||||
|
||||
package ecies
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
"testing"
|
||||
|
||||
"github.com/dchest/blake2b"
|
||||
"github.com/wg/ecies/xchacha20poly1305"
|
||||
)
|
||||
|
||||
func TestXChaCha20Poly1305KeySetup(t *testing.T) {
|
||||
secret := []byte("secret")
|
||||
|
||||
cfg := blake2b.Config{Size: xchacha20poly1305.KeySize}
|
||||
hash, err := blake2b.New(&cfg)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
hash.Write(secret)
|
||||
key := hash.Sum(nil)
|
||||
|
||||
box, err := newXChaCha20Poly1305Box(secret)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !bytes.Equal(box.key[:], key) {
|
||||
t.Fatal("box key initialization incorrect")
|
||||
}
|
||||
}
|
||||
|
||||
func TestXChaCha20Poly1305Box(t *testing.T) {
|
||||
const tagSize = xchacha20poly1305.TagSize
|
||||
|
||||
var (
|
||||
key [xchacha20poly1305.KeySize]byte
|
||||
nonce [xchacha20poly1305.NonceSize]byte
|
||||
msg [64]byte
|
||||
raw [len(msg) + tagSize]byte
|
||||
sealed [len(msg) + tagSize]byte
|
||||
opened [len(msg) + tagSize]byte
|
||||
box Box
|
||||
)
|
||||
|
||||
rand.Read(key[:])
|
||||
rand.Read(nonce[:])
|
||||
rand.Read(msg[:])
|
||||
copy(box.key[:], key[:])
|
||||
|
||||
c := xchacha20poly1305.New(&key, &nonce)
|
||||
c.Encrypt(raw[:], msg[:])
|
||||
c.Tag(raw[len(msg):len(msg)])
|
||||
|
||||
err := box.Seal(sealed[:], msg[:], nonce[:])
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !bytes.Equal(sealed[:len(msg)], raw[:len(msg)]) {
|
||||
t.Fatal("sealed ciphertext != raw ciphertext")
|
||||
}
|
||||
|
||||
if !bytes.Equal(sealed[len(msg):], raw[len(msg):]) {
|
||||
t.Fatal("sealed auth tag != raw auth tag")
|
||||
}
|
||||
|
||||
err = box.Open(opened[:], sealed[:], nonce[:])
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !bytes.Equal(opened[:len(msg)], msg[:]) {
|
||||
t.Fatal("opened plaintext != original plaintext")
|
||||
}
|
||||
}
|
||||
|
||||
func TestXChaCha20Poly1305BoxInPlace(t *testing.T) {
|
||||
const tagSize = xchacha20poly1305.TagSize
|
||||
|
||||
var (
|
||||
key [xchacha20poly1305.KeySize]byte
|
||||
nonce [xchacha20poly1305.NonceSize]byte
|
||||
msg [64]byte
|
||||
raw [len(msg) + tagSize]byte
|
||||
dst [len(msg) + tagSize]byte
|
||||
box Box
|
||||
)
|
||||
|
||||
rand.Read(key[:])
|
||||
rand.Read(nonce[:])
|
||||
rand.Read(msg[:])
|
||||
copy(dst[:], msg[:])
|
||||
copy(box.key[:], key[:])
|
||||
|
||||
c := xchacha20poly1305.New(&key, &nonce)
|
||||
c.Encrypt(raw[:], msg[:])
|
||||
c.Tag(raw[len(msg):len(msg)])
|
||||
|
||||
err := box.Seal(dst[:], dst[:len(msg)], nonce[:])
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !bytes.Equal(dst[:len(msg)], raw[:len(msg)]) {
|
||||
t.Fatal("sealed ciphertext != raw ciphertext")
|
||||
}
|
||||
|
||||
if !bytes.Equal(dst[len(msg):], raw[len(msg):]) {
|
||||
t.Fatal("sealed auth tag != raw auth tag")
|
||||
}
|
||||
|
||||
err = box.Open(dst[:], dst[:], nonce[:])
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !bytes.Equal(dst[:len(msg)], msg[:]) {
|
||||
t.Fatal("opened plaintext != original plaintext")
|
||||
}
|
||||
}
|
||||
90
vendor/github.com/wg/ecies/chacha20poly1305/chacha20poly1305.go
generated
vendored
Normal file
90
vendor/github.com/wg/ecies/chacha20poly1305/chacha20poly1305.go
generated
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
// Copyright (C) 2016 - Will Glozer. All rights reserved.
|
||||
|
||||
// Package chacha20poly1305 implements the AEAD_CHACHA20_POLY1305
|
||||
// construction as specified in RFC 7539.
|
||||
package chacha20poly1305
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
|
||||
"schwanenlied.me/yawning/chacha20"
|
||||
"schwanenlied.me/yawning/poly1305"
|
||||
)
|
||||
|
||||
const (
|
||||
KeySize = chacha20.KeySize
|
||||
NonceSize = chacha20.INonceSize
|
||||
TagSize = poly1305.Size
|
||||
)
|
||||
|
||||
var padding [16]byte
|
||||
|
||||
type ChaCha20Poly1305 struct {
|
||||
a, n uint64
|
||||
chacha20.Cipher
|
||||
poly1305.Poly1305
|
||||
}
|
||||
|
||||
func New(key *[KeySize]byte, nonce *[NonceSize]byte) *ChaCha20Poly1305 {
|
||||
x := &ChaCha20Poly1305{}
|
||||
x.Init(key[:], nonce[:])
|
||||
return x
|
||||
}
|
||||
|
||||
func (x *ChaCha20Poly1305) Init(key, nonce []byte) error {
|
||||
err := x.ReKey(key, nonce)
|
||||
if err == nil {
|
||||
x.initPoly1305()
|
||||
x.Seek(1)
|
||||
x.a = 0
|
||||
x.n = 0
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (x *ChaCha20Poly1305) Auth(src []byte) {
|
||||
if n := len(src); n > 0 {
|
||||
x.Poly1305.Write(src)
|
||||
x.a = uint64(n)
|
||||
x.Poly1305.Write(padding[:16-n%16])
|
||||
}
|
||||
}
|
||||
|
||||
func (x *ChaCha20Poly1305) Decrypt(dst, src []byte) {
|
||||
x.Poly1305.Write(src)
|
||||
x.XORKeyStream(dst, src)
|
||||
x.n += uint64(len(src))
|
||||
}
|
||||
|
||||
func (x *ChaCha20Poly1305) Encrypt(dst, src []byte) {
|
||||
n := len(src)
|
||||
x.XORKeyStream(dst, src)
|
||||
x.Poly1305.Write(dst[:n])
|
||||
x.n += uint64(n)
|
||||
}
|
||||
|
||||
func (x *ChaCha20Poly1305) Tag(b []byte) []byte {
|
||||
var lengths [16]byte
|
||||
binary.LittleEndian.PutUint64(lengths[0:], uint64(x.a))
|
||||
binary.LittleEndian.PutUint64(lengths[8:], uint64(x.n))
|
||||
x.Poly1305.Write(padding[:16-x.n%16])
|
||||
x.Poly1305.Write(lengths[:])
|
||||
return x.Poly1305.Sum(b)
|
||||
}
|
||||
|
||||
func (x *ChaCha20Poly1305) Reset() {
|
||||
x.Cipher.Reset()
|
||||
}
|
||||
|
||||
func (x *ChaCha20Poly1305) TagSize() int {
|
||||
return TagSize
|
||||
}
|
||||
|
||||
func (x *ChaCha20Poly1305) initPoly1305() {
|
||||
var key [poly1305.KeySize]byte
|
||||
x.KeyStream(key[:])
|
||||
x.Poly1305.Init(key[:])
|
||||
for i := range key {
|
||||
key[i] = 0
|
||||
}
|
||||
}
|
||||
114
vendor/github.com/wg/ecies/chacha20poly1305/chacha20poly1305_test.go
generated
vendored
Normal file
114
vendor/github.com/wg/ecies/chacha20poly1305/chacha20poly1305_test.go
generated
vendored
Normal file
@@ -0,0 +1,114 @@
|
||||
// Copyright (C) 2016 - Will Glozer. All rights reserved.
|
||||
|
||||
package chacha20poly1305
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestRFC7539(t *testing.T) {
|
||||
plaintext := []byte{
|
||||
0x4c, 0x61, 0x64, 0x69, 0x65, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x47, 0x65, 0x6e, 0x74, 0x6c,
|
||||
0x65, 0x6d, 0x65, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x61, 0x73,
|
||||
0x73, 0x20, 0x6f, 0x66, 0x20, 0x27, 0x39, 0x39, 0x3a, 0x20, 0x49, 0x66, 0x20, 0x49, 0x20, 0x63,
|
||||
0x6f, 0x75, 0x6c, 0x64, 0x20, 0x6f, 0x66, 0x66, 0x65, 0x72, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x6f,
|
||||
0x6e, 0x6c, 0x79, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x74, 0x69, 0x70, 0x20, 0x66, 0x6f, 0x72, 0x20,
|
||||
0x74, 0x68, 0x65, 0x20, 0x66, 0x75, 0x74, 0x75, 0x72, 0x65, 0x2c, 0x20, 0x73, 0x75, 0x6e, 0x73,
|
||||
0x63, 0x72, 0x65, 0x65, 0x6e, 0x20, 0x77, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x62, 0x65, 0x20, 0x69,
|
||||
0x74, 0x2e,
|
||||
}
|
||||
|
||||
aad := []byte{
|
||||
0x50, 0x51, 0x52, 0x53, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
|
||||
}
|
||||
|
||||
key := []byte{
|
||||
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
|
||||
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
|
||||
}
|
||||
|
||||
nonce := []byte{
|
||||
0x07, 0x00, 0x00, 0x00,
|
||||
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
|
||||
}
|
||||
|
||||
ciphertext := []byte{
|
||||
0xd3, 0x1a, 0x8d, 0x34, 0x64, 0x8e, 0x60, 0xdb, 0x7b, 0x86, 0xaf, 0xbc, 0x53, 0xef, 0x7e, 0xc2,
|
||||
0xa4, 0xad, 0xed, 0x51, 0x29, 0x6e, 0x08, 0xfe, 0xa9, 0xe2, 0xb5, 0xa7, 0x36, 0xee, 0x62, 0xd6,
|
||||
0x3d, 0xbe, 0xa4, 0x5e, 0x8c, 0xa9, 0x67, 0x12, 0x82, 0xfa, 0xfb, 0x69, 0xda, 0x92, 0x72, 0x8b,
|
||||
0x1a, 0x71, 0xde, 0x0a, 0x9e, 0x06, 0x0b, 0x29, 0x05, 0xd6, 0xa5, 0xb6, 0x7e, 0xcd, 0x3b, 0x36,
|
||||
0x92, 0xdd, 0xbd, 0x7f, 0x2d, 0x77, 0x8b, 0x8c, 0x98, 0x03, 0xae, 0xe3, 0x28, 0x09, 0x1b, 0x58,
|
||||
0xfa, 0xb3, 0x24, 0xe4, 0xfa, 0xd6, 0x75, 0x94, 0x55, 0x85, 0x80, 0x8b, 0x48, 0x31, 0xd7, 0xbc,
|
||||
0x3f, 0xf4, 0xde, 0xf0, 0x8e, 0x4b, 0x7a, 0x9d, 0xe5, 0x76, 0xd2, 0x65, 0x86, 0xce, 0xc6, 0x4b,
|
||||
0x61, 0x16,
|
||||
}
|
||||
|
||||
tag := []byte{
|
||||
0x1a, 0xe1, 0x0b, 0x59, 0x4f, 0x09, 0xe2, 0x6a, 0x7e, 0x90, 0x2e, 0xcb, 0xd0, 0x60, 0x06, 0x91,
|
||||
}
|
||||
|
||||
c := ChaCha20Poly1305{}
|
||||
|
||||
err := c.Init(key, nonce)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
c.Auth(aad)
|
||||
c.Encrypt(plaintext, plaintext)
|
||||
|
||||
if !bytes.Equal(plaintext, ciphertext) {
|
||||
t.Fatal("encrypted plaintext != ciphertext")
|
||||
}
|
||||
|
||||
if !bytes.Equal(c.Tag(nil), tag) {
|
||||
t.Fatal("actual tag != expected tag")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRFC7539_ChaCha20(t *testing.T) {
|
||||
plaintext := []byte{
|
||||
0x4c, 0x61, 0x64, 0x69, 0x65, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x47, 0x65, 0x6e, 0x74, 0x6c,
|
||||
0x65, 0x6d, 0x65, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x61, 0x73,
|
||||
0x73, 0x20, 0x6f, 0x66, 0x20, 0x27, 0x39, 0x39, 0x3a, 0x20, 0x49, 0x66, 0x20, 0x49, 0x20, 0x63,
|
||||
0x6f, 0x75, 0x6c, 0x64, 0x20, 0x6f, 0x66, 0x66, 0x65, 0x72, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x6f,
|
||||
0x6e, 0x6c, 0x79, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x74, 0x69, 0x70, 0x20, 0x66, 0x6f, 0x72, 0x20,
|
||||
0x74, 0x68, 0x65, 0x20, 0x66, 0x75, 0x74, 0x75, 0x72, 0x65, 0x2c, 0x20, 0x73, 0x75, 0x6e, 0x73,
|
||||
0x63, 0x72, 0x65, 0x65, 0x6e, 0x20, 0x77, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x62, 0x65, 0x20, 0x69,
|
||||
0x74, 0x2e,
|
||||
}
|
||||
|
||||
key := []byte{
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
|
||||
}
|
||||
|
||||
nonce := []byte{
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x00,
|
||||
}
|
||||
|
||||
ciphertext := []byte{
|
||||
0x6e, 0x2e, 0x35, 0x9a, 0x25, 0x68, 0xf9, 0x80, 0x41, 0xba, 0x07, 0x28, 0xdd, 0x0d, 0x69, 0x81,
|
||||
0xe9, 0x7e, 0x7a, 0xec, 0x1d, 0x43, 0x60, 0xc2, 0x0a, 0x27, 0xaf, 0xcc, 0xfd, 0x9f, 0xae, 0x0b,
|
||||
0xf9, 0x1b, 0x65, 0xc5, 0x52, 0x47, 0x33, 0xab, 0x8f, 0x59, 0x3d, 0xab, 0xcd, 0x62, 0xb3, 0x57,
|
||||
0x16, 0x39, 0xd6, 0x24, 0xe6, 0x51, 0x52, 0xab, 0x8f, 0x53, 0x0c, 0x35, 0x9f, 0x08, 0x61, 0xd8,
|
||||
0x07, 0xca, 0x0d, 0xbf, 0x50, 0x0d, 0x6a, 0x61, 0x56, 0xa3, 0x8e, 0x08, 0x8a, 0x22, 0xb6, 0x5e,
|
||||
0x52, 0xbc, 0x51, 0x4d, 0x16, 0xcc, 0xf8, 0x06, 0x81, 0x8c, 0xe9, 0x1a, 0xb7, 0x79, 0x37, 0x36,
|
||||
0x5a, 0xf9, 0x0b, 0xbf, 0x74, 0xa3, 0x5b, 0xe6, 0xb4, 0x0b, 0x8e, 0xed, 0xf2, 0x78, 0x5e, 0x42,
|
||||
0x87, 0x4d,
|
||||
}
|
||||
|
||||
c := ChaCha20Poly1305{}
|
||||
|
||||
err := c.Init(key, nonce)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
c.Encrypt(plaintext, plaintext)
|
||||
|
||||
if !bytes.Equal(plaintext, ciphertext) {
|
||||
t.Fatal("encrypted plaintext != expected ciphertext")
|
||||
}
|
||||
}
|
||||
13
vendor/github.com/wg/ecies/cipher.go
generated
vendored
Normal file
13
vendor/github.com/wg/ecies/cipher.go
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
// Copyright (C) 2016 - Will Glozer. All rights reserved.
|
||||
|
||||
package ecies
|
||||
|
||||
type Cipher interface {
|
||||
Init(key, nonce []byte) error
|
||||
Auth(src []byte)
|
||||
Decrypt(dst, src []byte)
|
||||
Encrypt(dst, src []byte)
|
||||
Tag(tag []byte) []byte
|
||||
Reset()
|
||||
TagSize() int
|
||||
}
|
||||
14
vendor/github.com/wg/ecies/doc.go
generated
vendored
Normal file
14
vendor/github.com/wg/ecies/doc.go
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
// Copyright (C) 2016 - Will Glozer. All rights reserved.
|
||||
|
||||
/*
|
||||
Package ecies provides a convenient interface to a number of Elliptic Curve
|
||||
Integrated Encryption Schemes and their corresponding primitives: Curve25519,
|
||||
Curve448 AKA Ed448-Goldilocks, XChaCha20, Poly1305, and BLAKE2b.
|
||||
|
||||
This package has not been subject to peer review and the specific algorithm
|
||||
combinations have not been standardized.
|
||||
|
||||
The cryptographic core is provided by Yawning Angel's excellent open-source x448,
|
||||
ChaCha20, and Poly1305 libraries, but any mistakes are the fault of Will Glozer.
|
||||
*/
|
||||
package ecies
|
||||
43
vendor/github.com/wg/ecies/ecdh.go
generated
vendored
Normal file
43
vendor/github.com/wg/ecies/ecdh.go
generated
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
// Copyright (C) 2016 - Will Glozer. All rights reserved.
|
||||
|
||||
package ecies
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io"
|
||||
|
||||
"golang.org/x/crypto/curve25519"
|
||||
"schwanenlied.me/yawning/x448"
|
||||
)
|
||||
|
||||
var ErrX448 = errors.New("curve448: key exchange failed")
|
||||
|
||||
func GenerateCurve25519Key(rand io.Reader, public, private *[32]byte) error {
|
||||
_, err := io.ReadFull(rand, private[:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
curve25519.ScalarBaseMult(public, private)
|
||||
return nil
|
||||
}
|
||||
|
||||
func GenerateCurve448Key(rand io.Reader, public, private *[56]byte) error {
|
||||
_, err := io.ReadFull(rand, private[:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
x448.ScalarBaseMult(public, private)
|
||||
return nil
|
||||
}
|
||||
|
||||
func X25519(secret, public, private *[32]byte) error {
|
||||
curve25519.ScalarMult(secret, private, public)
|
||||
return nil
|
||||
}
|
||||
|
||||
func X448(secret, public, private *[56]byte) error {
|
||||
if x448.ScalarMult(secret, private, public) != 0 {
|
||||
return ErrX448
|
||||
}
|
||||
return nil
|
||||
}
|
||||
157
vendor/github.com/wg/ecies/ecdh_test.go
generated
vendored
Normal file
157
vendor/github.com/wg/ecies/ecdh_test.go
generated
vendored
Normal file
@@ -0,0 +1,157 @@
|
||||
// Copyright (C) 2016 - Will Glozer. All rights reserved.
|
||||
|
||||
package ecies
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func Test_X25519_RFC7748(t *testing.T) {
|
||||
const keySize = 32
|
||||
|
||||
unhex := func(s string) *[keySize]byte {
|
||||
var out [keySize]byte
|
||||
switch n, err := hex.Decode(out[:], []byte(s)); {
|
||||
case err != nil:
|
||||
t.Fatal(err)
|
||||
case n != keySize:
|
||||
t.Fatalf("%d != %d", n, keySize)
|
||||
}
|
||||
return &out
|
||||
}
|
||||
|
||||
var (
|
||||
alicePrivateKey = unhex("77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a")
|
||||
alicePublicKey = unhex("8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a")
|
||||
bobPrivateKey = unhex("5dab087e624a8a4b79e17f8b83800ee66f3bb1292618b6fd1c2f8b27ff88e0eb")
|
||||
bobPublicKey = unhex("de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f")
|
||||
expectedSecret = unhex("4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742")
|
||||
sharedSecret [keySize]byte
|
||||
)
|
||||
|
||||
_ = alicePublicKey
|
||||
_ = bobPrivateKey
|
||||
|
||||
err := X25519(&sharedSecret, bobPublicKey, alicePrivateKey)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal("key exchange failed", err)
|
||||
}
|
||||
|
||||
if !bytes.Equal(sharedSecret[:], expectedSecret[:]) {
|
||||
t.Fatal("shared secret incorrect")
|
||||
}
|
||||
}
|
||||
|
||||
func Test_X448_RFC7748(t *testing.T) {
|
||||
const keySize = 56
|
||||
|
||||
unhex := func(s ...string) *[keySize]byte {
|
||||
var out [keySize]byte
|
||||
var in []byte
|
||||
|
||||
for i := range s {
|
||||
in = append(in, []byte(s[i])...)
|
||||
}
|
||||
|
||||
switch n, err := hex.Decode(out[:], in); {
|
||||
case err != nil:
|
||||
t.Fatal(err)
|
||||
case n != keySize:
|
||||
t.Fatalf("%d != %d", n, keySize)
|
||||
}
|
||||
return &out
|
||||
}
|
||||
|
||||
var (
|
||||
alicePrivateKey = unhex(
|
||||
"9a8f4925d1519f5775cf46b04b5800d4ee9ee8bae8bc5565d498c28d",
|
||||
"d9c9baf574a9419744897391006382a6f127ab1d9ac2d8c0a598726b",
|
||||
)
|
||||
alicePublicKey = unhex(
|
||||
"9b08f7cc31b7e3e67d22d5aea121074a273bd2b83de09c63faa73d2c",
|
||||
"22c5d9bbc836647241d953d40c5b12da88120d53177f80e532c41fa0",
|
||||
)
|
||||
bobPrivateKey = unhex(
|
||||
"1c306a7ac2a0e2e0990b294470cba339e6453772b075811d8fad0d1d",
|
||||
"6927c120bb5ee8972b0d3e21374c9c921b09d1b0366f10b65173992d",
|
||||
)
|
||||
bobPublicKey = unhex(
|
||||
"3eb7a829b0cd20f5bcfc0b599b6feccf6da4627107bdb0d4f345b430",
|
||||
"27d8b972fc3e34fb4232a13ca706dcb57aec3dae07bdc1c67bf33609",
|
||||
)
|
||||
expectedSecret = unhex(
|
||||
"07fff4181ac6cc95ec1c16a94a0f74d12da232ce40a77552281d282b",
|
||||
"b60c0b56fd2464c335543936521c24403085d59a449a5037514a879d",
|
||||
)
|
||||
sharedSecret [keySize]byte
|
||||
)
|
||||
|
||||
_ = alicePublicKey
|
||||
_ = bobPrivateKey
|
||||
|
||||
err := X448(&sharedSecret, bobPublicKey, alicePrivateKey)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal("key exchange failed", err)
|
||||
}
|
||||
|
||||
if !bytes.Equal(sharedSecret[:], expectedSecret[:]) {
|
||||
t.Fatal("shared secret incorrect")
|
||||
}
|
||||
}
|
||||
|
||||
func Test_X25519_EphemeralStatic(t *testing.T) {
|
||||
const keySize = 32
|
||||
|
||||
var (
|
||||
aliceStaticPublic [keySize]byte
|
||||
aliceStaticPrivate [keySize]byte
|
||||
aliceEphemeralPublic [keySize]byte
|
||||
aliceEphemeralPrivate [keySize]byte
|
||||
bobStaticPublic [keySize]byte
|
||||
bobStaticPrivate [keySize]byte
|
||||
aliceSecret [keySize]byte
|
||||
bobSecret [keySize]byte
|
||||
)
|
||||
|
||||
GenerateCurve25519Key(rand.Reader, &aliceStaticPublic, &aliceStaticPrivate)
|
||||
GenerateCurve25519Key(rand.Reader, &aliceEphemeralPublic, &aliceEphemeralPrivate)
|
||||
GenerateCurve25519Key(rand.Reader, &bobStaticPublic, &bobStaticPrivate)
|
||||
|
||||
X25519(&aliceSecret, &bobStaticPublic, &aliceEphemeralPrivate)
|
||||
X25519(&bobSecret, &aliceEphemeralPublic, &bobStaticPrivate)
|
||||
|
||||
if !bytes.Equal(aliceSecret[:], bobSecret[:]) {
|
||||
t.Fatal("alice's shared secret != bob's shared secret")
|
||||
}
|
||||
}
|
||||
|
||||
func Test_X448_EphemeralStatic(t *testing.T) {
|
||||
const keySize = 56
|
||||
|
||||
var (
|
||||
aliceStaticPublic [keySize]byte
|
||||
aliceStaticPrivate [keySize]byte
|
||||
aliceEphemeralPublic [keySize]byte
|
||||
aliceEphemeralPrivate [keySize]byte
|
||||
bobStaticPublic [keySize]byte
|
||||
bobStaticPrivate [keySize]byte
|
||||
aliceSecret [keySize]byte
|
||||
bobSecret [keySize]byte
|
||||
)
|
||||
|
||||
GenerateCurve448Key(rand.Reader, &aliceStaticPublic, &aliceStaticPrivate)
|
||||
GenerateCurve448Key(rand.Reader, &aliceEphemeralPublic, &aliceEphemeralPrivate)
|
||||
GenerateCurve448Key(rand.Reader, &bobStaticPublic, &bobStaticPrivate)
|
||||
|
||||
X448(&aliceSecret, &bobStaticPublic, &aliceEphemeralPrivate)
|
||||
X448(&bobSecret, &aliceEphemeralPublic, &bobStaticPrivate)
|
||||
|
||||
if !bytes.Equal(aliceSecret[:], bobSecret[:]) {
|
||||
t.Fatal("alice's shared secret != bob's shared secret")
|
||||
}
|
||||
}
|
||||
23
vendor/github.com/wg/ecies/vendor/github.com/dchest/blake2b/README
generated
vendored
Normal file
23
vendor/github.com/wg/ecies/vendor/github.com/dchest/blake2b/README
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
Go implementation of BLAKE2b collision-resistant cryptographic hash function
|
||||
created by Jean-Philippe Aumasson, Samuel Neves, Zooko Wilcox-O'Hearn, and
|
||||
Christian Winnerlein (https://blake2.net).
|
||||
|
||||
INSTALLATION
|
||||
|
||||
$ go get github.com/dchest/blake2b
|
||||
|
||||
|
||||
DOCUMENTATION
|
||||
|
||||
See http://godoc.org/github.com/dchest/blake2b
|
||||
|
||||
|
||||
PUBLIC DOMAIN DEDICATION
|
||||
|
||||
Written in 2012 by Dmitry Chestnykh.
|
||||
|
||||
To the extent possible under law, the author have dedicated all copyright
|
||||
and related and neighboring rights to this software to the public domain
|
||||
worldwide. This software is distributed without any warranty.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
|
||||
299
vendor/github.com/wg/ecies/vendor/github.com/dchest/blake2b/blake2b.go
generated
vendored
Normal file
299
vendor/github.com/wg/ecies/vendor/github.com/dchest/blake2b/blake2b.go
generated
vendored
Normal file
@@ -0,0 +1,299 @@
|
||||
// Written in 2012 by Dmitry Chestnykh.
|
||||
//
|
||||
// To the extent possible under law, the author have dedicated all copyright
|
||||
// and related and neighboring rights to this software to the public domain
|
||||
// worldwide. This software is distributed without any warranty.
|
||||
// http://creativecommons.org/publicdomain/zero/1.0/
|
||||
|
||||
// Package blake2b implements BLAKE2b cryptographic hash function.
|
||||
package blake2b
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"hash"
|
||||
)
|
||||
|
||||
const (
|
||||
BlockSize = 128 // block size of algorithm
|
||||
Size = 64 // maximum digest size
|
||||
SaltSize = 16 // maximum salt size
|
||||
PersonSize = 16 // maximum personalization string size
|
||||
KeySize = 64 // maximum size of key
|
||||
)
|
||||
|
||||
type digest struct {
|
||||
h [8]uint64 // current chain value
|
||||
t [2]uint64 // message bytes counter
|
||||
f [2]uint64 // finalization flags
|
||||
x [BlockSize]byte // buffer for data not yet compressed
|
||||
nx int // number of bytes in buffer
|
||||
|
||||
ih [8]uint64 // initial chain value (after config)
|
||||
paddedKey [BlockSize]byte // copy of key, padded with zeros
|
||||
isKeyed bool // indicates whether hash was keyed
|
||||
size uint8 // digest size in bytes
|
||||
isLastNode bool // indicates processing of the last node in tree hashing
|
||||
}
|
||||
|
||||
// Initialization values.
|
||||
var iv = [8]uint64{
|
||||
0x6a09e667f3bcc908, 0xbb67ae8584caa73b,
|
||||
0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1,
|
||||
0x510e527fade682d1, 0x9b05688c2b3e6c1f,
|
||||
0x1f83d9abfb41bd6b, 0x5be0cd19137e2179,
|
||||
}
|
||||
|
||||
// Config is used to configure hash function parameters and keying.
|
||||
// All parameters are optional.
|
||||
type Config struct {
|
||||
Size uint8 // digest size (if zero, default size of 64 bytes is used)
|
||||
Key []byte // key for prefix-MAC
|
||||
Salt []byte // salt (if < 16 bytes, padded with zeros)
|
||||
Person []byte // personalization (if < 16 bytes, padded with zeros)
|
||||
Tree *Tree // parameters for tree hashing
|
||||
}
|
||||
|
||||
// Tree represents parameters for tree hashing.
|
||||
type Tree struct {
|
||||
Fanout uint8 // fanout
|
||||
MaxDepth uint8 // maximal depth
|
||||
LeafSize uint32 // leaf maximal byte length (0 for unlimited)
|
||||
NodeOffset uint64 // node offset (0 for first, leftmost or leaf)
|
||||
NodeDepth uint8 // node depth (0 for leaves)
|
||||
InnerHashSize uint8 // inner hash byte length
|
||||
IsLastNode bool // indicates processing of the last node of layer
|
||||
}
|
||||
|
||||
var (
|
||||
defaultConfig = &Config{Size: Size}
|
||||
config256 = &Config{Size: 32}
|
||||
)
|
||||
|
||||
func verifyConfig(c *Config) error {
|
||||
if c.Size > Size {
|
||||
return errors.New("digest size is too large")
|
||||
}
|
||||
if len(c.Key) > KeySize {
|
||||
return errors.New("key is too large")
|
||||
}
|
||||
if len(c.Salt) > SaltSize {
|
||||
// Smaller salt is okay: it will be padded with zeros.
|
||||
return errors.New("salt is too large")
|
||||
}
|
||||
if len(c.Person) > PersonSize {
|
||||
// Smaller personalization is okay: it will be padded with zeros.
|
||||
return errors.New("personalization is too large")
|
||||
}
|
||||
if c.Tree != nil {
|
||||
if c.Tree.Fanout == 1 {
|
||||
return errors.New("fanout of 1 is not allowed in tree mode")
|
||||
}
|
||||
if c.Tree.MaxDepth < 2 {
|
||||
return errors.New("incorrect tree depth")
|
||||
}
|
||||
if c.Tree.InnerHashSize < 1 || c.Tree.InnerHashSize > Size {
|
||||
return errors.New("incorrect tree inner hash size")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// New returns a new hash.Hash configured with the given Config.
|
||||
// Config can be nil, in which case the default one is used, calculating 64-byte digest.
|
||||
// Returns non-nil error if Config contains invalid parameters.
|
||||
func New(c *Config) (hash.Hash, error) {
|
||||
if c == nil {
|
||||
c = defaultConfig
|
||||
} else {
|
||||
if c.Size == 0 {
|
||||
// Set default size if it's zero.
|
||||
c.Size = Size
|
||||
}
|
||||
if err := verifyConfig(c); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
d := new(digest)
|
||||
d.initialize(c)
|
||||
return d, nil
|
||||
}
|
||||
|
||||
// initialize initializes digest with the given
|
||||
// config, which must be non-nil and verified.
|
||||
func (d *digest) initialize(c *Config) {
|
||||
// Create parameter block.
|
||||
var p [BlockSize]byte
|
||||
p[0] = c.Size
|
||||
p[1] = uint8(len(c.Key))
|
||||
if c.Salt != nil {
|
||||
copy(p[32:], c.Salt)
|
||||
}
|
||||
if c.Person != nil {
|
||||
copy(p[48:], c.Person)
|
||||
}
|
||||
if c.Tree != nil {
|
||||
p[2] = c.Tree.Fanout
|
||||
p[3] = c.Tree.MaxDepth
|
||||
binary.LittleEndian.PutUint32(p[4:], c.Tree.LeafSize)
|
||||
binary.LittleEndian.PutUint64(p[8:], c.Tree.NodeOffset)
|
||||
p[16] = c.Tree.NodeDepth
|
||||
p[17] = c.Tree.InnerHashSize
|
||||
} else {
|
||||
p[2] = 1
|
||||
p[3] = 1
|
||||
}
|
||||
// Initialize.
|
||||
d.size = c.Size
|
||||
for i := 0; i < 8; i++ {
|
||||
d.h[i] = iv[i] ^ binary.LittleEndian.Uint64(p[i*8:])
|
||||
}
|
||||
if c.Tree != nil && c.Tree.IsLastNode {
|
||||
d.isLastNode = true
|
||||
}
|
||||
// Process key.
|
||||
if c.Key != nil {
|
||||
copy(d.paddedKey[:], c.Key)
|
||||
d.Write(d.paddedKey[:])
|
||||
d.isKeyed = true
|
||||
}
|
||||
// Save a copy of initialized state.
|
||||
copy(d.ih[:], d.h[:])
|
||||
}
|
||||
|
||||
// New512 returns a new hash.Hash computing the BLAKE2b 64-byte checksum.
|
||||
func New512() hash.Hash {
|
||||
d := new(digest)
|
||||
d.initialize(defaultConfig)
|
||||
return d
|
||||
}
|
||||
|
||||
// New256 returns a new hash.Hash computing the BLAKE2b 32-byte checksum.
|
||||
func New256() hash.Hash {
|
||||
d := new(digest)
|
||||
d.initialize(config256)
|
||||
return d
|
||||
}
|
||||
|
||||
// NewMAC returns a new hash.Hash computing BLAKE2b prefix-
|
||||
// Message Authentication Code of the given size in bytes
|
||||
// (up to 64) with the given key (up to 64 bytes in length).
|
||||
func NewMAC(outBytes uint8, key []byte) hash.Hash {
|
||||
d, err := New(&Config{Size: outBytes, Key: key})
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
return d
|
||||
}
|
||||
|
||||
// Reset resets the state of digest to the initial state
|
||||
// after configuration and keying.
|
||||
func (d *digest) Reset() {
|
||||
copy(d.h[:], d.ih[:])
|
||||
d.t[0] = 0
|
||||
d.t[1] = 0
|
||||
d.f[0] = 0
|
||||
d.f[1] = 0
|
||||
d.nx = 0
|
||||
if d.isKeyed {
|
||||
d.Write(d.paddedKey[:])
|
||||
}
|
||||
}
|
||||
|
||||
// Size returns the digest size in bytes.
|
||||
func (d *digest) Size() int { return int(d.size) }
|
||||
|
||||
// BlockSize returns the algorithm block size in bytes.
|
||||
func (d *digest) BlockSize() int { return BlockSize }
|
||||
|
||||
func (d *digest) Write(p []byte) (nn int, err error) {
|
||||
nn = len(p)
|
||||
left := BlockSize - d.nx
|
||||
if len(p) > left {
|
||||
// Process buffer.
|
||||
copy(d.x[d.nx:], p[:left])
|
||||
p = p[left:]
|
||||
blocks(d, d.x[:])
|
||||
d.nx = 0
|
||||
}
|
||||
// Process full blocks except for the last one.
|
||||
if len(p) > BlockSize {
|
||||
n := len(p) &^ (BlockSize - 1)
|
||||
if n == len(p) {
|
||||
n -= BlockSize
|
||||
}
|
||||
blocks(d, p[:n])
|
||||
p = p[n:]
|
||||
}
|
||||
// Fill buffer.
|
||||
d.nx += copy(d.x[d.nx:], p)
|
||||
return
|
||||
}
|
||||
|
||||
// Sum returns the calculated checksum.
|
||||
func (d0 *digest) Sum(in []byte) []byte {
|
||||
// Make a copy of d0 so that caller can keep writing and summing.
|
||||
d := *d0
|
||||
hash := d.checkSum()
|
||||
return append(in, hash[:d.size]...)
|
||||
}
|
||||
|
||||
func (d *digest) checkSum() [Size]byte {
|
||||
// Do not create unnecessary copies of the key.
|
||||
if d.isKeyed {
|
||||
for i := 0; i < len(d.paddedKey); i++ {
|
||||
d.paddedKey[i] = 0
|
||||
}
|
||||
}
|
||||
|
||||
dec := BlockSize - uint64(d.nx)
|
||||
if d.t[0] < dec {
|
||||
d.t[1]--
|
||||
}
|
||||
d.t[0] -= dec
|
||||
|
||||
// Pad buffer with zeros.
|
||||
for i := d.nx; i < len(d.x); i++ {
|
||||
d.x[i] = 0
|
||||
}
|
||||
// Set last block flag.
|
||||
d.f[0] = 0xffffffffffffffff
|
||||
if d.isLastNode {
|
||||
d.f[1] = 0xffffffffffffffff
|
||||
}
|
||||
// Compress last block.
|
||||
blocks(d, d.x[:])
|
||||
|
||||
var out [Size]byte
|
||||
j := 0
|
||||
for _, s := range d.h[:(d.size-1)/8+1] {
|
||||
out[j+0] = byte(s >> 0)
|
||||
out[j+1] = byte(s >> 8)
|
||||
out[j+2] = byte(s >> 16)
|
||||
out[j+3] = byte(s >> 24)
|
||||
out[j+4] = byte(s >> 32)
|
||||
out[j+5] = byte(s >> 40)
|
||||
out[j+6] = byte(s >> 48)
|
||||
out[j+7] = byte(s >> 56)
|
||||
j += 8
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// Sum512 returns a 64-byte BLAKE2b hash of data.
|
||||
func Sum512(data []byte) [64]byte {
|
||||
var d digest
|
||||
d.initialize(defaultConfig)
|
||||
d.Write(data)
|
||||
return d.checkSum()
|
||||
}
|
||||
|
||||
// Sum256 returns a 32-byte BLAKE2b hash of data.
|
||||
func Sum256(data []byte) (out [32]byte) {
|
||||
var d digest
|
||||
d.initialize(config256)
|
||||
d.Write(data)
|
||||
sum := d.checkSum()
|
||||
copy(out[:], sum[:32])
|
||||
return
|
||||
}
|
||||
625
vendor/github.com/wg/ecies/vendor/github.com/dchest/blake2b/blake2b_test.go
generated
vendored
Normal file
625
vendor/github.com/wg/ecies/vendor/github.com/dchest/blake2b/blake2b_test.go
generated
vendored
Normal file
@@ -0,0 +1,625 @@
|
||||
// Written in 2012 by Dmitry Chestnykh.
|
||||
//
|
||||
// To the extent possible under law, the author have dedicated all copyright
|
||||
// and related and neighboring rights to this software to the public domain
|
||||
// worldwide. This software is distributed without any warranty.
|
||||
// http://creativecommons.org/publicdomain/zero/1.0/
|
||||
|
||||
package blake2b
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestSum(t *testing.T) {
|
||||
buf := make([]byte, len(golden))
|
||||
for i := range buf {
|
||||
buf[i] = byte(i)
|
||||
}
|
||||
h := New512()
|
||||
for i, v := range golden {
|
||||
if v != fmt.Sprintf("%x", Sum512(buf[:i])) {
|
||||
t.Errorf("%d: Sum512(): \nexpected %s\ngot %x", i, v, Sum512(buf[:i]))
|
||||
}
|
||||
h.Reset()
|
||||
h.Write(buf[:i])
|
||||
sum := h.Sum(nil)
|
||||
if fmt.Sprintf("%x", sum) != v {
|
||||
t.Errorf("%d:\nexpected %s\ngot %x", i, v, sum)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func TestSum256(t *testing.T) {
|
||||
// Simple one-hash test.
|
||||
in := "The cryptographic hash function BLAKE2 is an improved version of the SHA-3 finalist BLAKE"
|
||||
good := "e5866d0c42b4e27e89a316fa5c3ba8cacae754e53d8267da37ba1893c2fcd92c"
|
||||
if good != fmt.Sprintf("%x", Sum256([]byte(in))) {
|
||||
t.Errorf("Sum256(): \nexpected %s\ngot %x", good, Sum256([]byte(in)))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestSumLength(t *testing.T) {
|
||||
h, _ := New(&Config{Size: 19})
|
||||
sum := h.Sum(nil)
|
||||
if len(sum) != 19 {
|
||||
t.Fatalf("Sum() returned a slice larger than the given hash size")
|
||||
}
|
||||
}
|
||||
|
||||
func TestKeyedSum(t *testing.T) {
|
||||
buf := make([]byte, len(goldenKeyed))
|
||||
for i := range buf {
|
||||
buf[i] = byte(i)
|
||||
}
|
||||
h := NewMAC(64, buf[:64])
|
||||
for i, v := range goldenKeyed {
|
||||
h.Reset()
|
||||
h.Write(buf[:i])
|
||||
sum := h.Sum(nil)
|
||||
if fmt.Sprintf("%x", sum) != v {
|
||||
t.Errorf("%d:\nexpected %s\ngot %x", i, v, sum)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
var bench = New512()
|
||||
var buf = make([]byte, 8<<10)
|
||||
|
||||
func BenchmarkWrite1K(b *testing.B) {
|
||||
b.SetBytes(1024)
|
||||
for i := 0; i < b.N; i++ {
|
||||
bench.Write(buf[:1024])
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkWrite8K(b *testing.B) {
|
||||
b.SetBytes(int64(len(buf)))
|
||||
for i := 0; i < b.N; i++ {
|
||||
bench.Write(buf)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkHash64(b *testing.B) {
|
||||
b.SetBytes(64)
|
||||
for i := 0; i < b.N; i++ {
|
||||
Sum512(buf[:64])
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkHash128(b *testing.B) {
|
||||
b.SetBytes(128)
|
||||
for i := 0; i < b.N; i++ {
|
||||
Sum512(buf[:128])
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkHash1K(b *testing.B) {
|
||||
b.SetBytes(1024)
|
||||
for i := 0; i < b.N; i++ {
|
||||
Sum512(buf[:1024])
|
||||
}
|
||||
}
|
||||
|
||||
// Test vectors taken from reference implementation in C#.
|
||||
var golden = []string{
|
||||
"786a02f742015903c6c6fd852552d272912f4740e15847618a86e217f71f5419d25e1031afee585313896444934eb04b903a685b1448b755d56f701afe9be2ce",
|
||||
"2fa3f686df876995167e7c2e5d74c4c7b6e48f8068fe0e44208344d480f7904c36963e44115fe3eb2a3ac8694c28bcb4f5a0f3276f2e79487d8219057a506e4b",
|
||||
"1c08798dc641aba9dee435e22519a4729a09b2bfe0ff00ef2dcd8ed6f8a07d15eaf4aee52bbf18ab5608a6190f70b90486c8a7d4873710b1115d3debbb4327b5",
|
||||
"40a374727302d9a4769c17b5f409ff32f58aa24ff122d7603e4fda1509e919d4107a52c57570a6d94e50967aea573b11f86f473f537565c66f7039830a85d186",
|
||||
"77ddf4b14425eb3d053c1e84e3469d92c4cd910ed20f92035e0c99d8a7a86cecaf69f9663c20a7aa230bc82f60d22fb4a00b09d3eb8fc65ef547fe63c8d3ddce",
|
||||
"cbaa0ba7d482b1f301109ae41051991a3289bc1198005af226c5e4f103b66579f461361044c8ba3439ff12c515fb29c52161b7eb9c2837b76a5dc33f7cb2e2e8",
|
||||
"f95d45cf69af5c2023bdb505821e62e85d7caedf7beda12c0248775b0c88205eeb35af3a90816f6608ce7dd44ec28db1140614e1ddebf3aa9cd1843e0fad2c36",
|
||||
"8f945ba700f2530e5c2a7df7d5dce0f83f9efc78c073fe71ae1f88204a4fd1cf70a073f5d1f942ed623aa16e90a871246c90c45b621b3401a5ddbd9df6264165",
|
||||
"e998e0dc03ec30eb99bb6bfaaf6618acc620320d7220b3af2b23d112d8e9cb1262f3c0d60d183b1ee7f096d12dae42c958418600214d04f5ed6f5e718be35566",
|
||||
"6a9a090c61b3410aede7ec9138146ceb2c69662f460c3da53c6515c1eb31f41ca3d280e567882f95cf664a94147d78f42cfc714a40d22ef19470e053493508a2",
|
||||
"29102511d749db3cc9b4e335fa1f5e8faca8421d558f6a3f3321d50d044a248ba595cfc3efd3d2adc97334da732413f5cbf4751c362ba1d53862ac1e8dabeee8",
|
||||
"c97a4779d47e6f77729b5917d0138abb35980ab641bd73a8859eb1ac98c05362ed7d608f2e9587d6ba9e271d343125d40d933a8ed04ec1fe75ec407c7a53c34e",
|
||||
"10f0dc91b9f845fb95fad6860e6ce1adfa002c7fc327116d44d047cd7d5870d772bb12b5fac00e02b08ac2a0174d0446c36ab35f14ca31894cd61c78c849b48a",
|
||||
"dea9101cac62b8f6a3c650f90eea5bfae2653a4eafd63a6d1f0f132db9e4f2b1b662432ec85b17bcac41e775637881f6aab38dd66dcbd080f0990a7a6e9854fe",
|
||||
"441ffaa08cd79dff4afc9b9e5b5620eec086730c25f661b1d6fbfbd1cec3148dd72258c65641f2fca5eb155fadbcabb13c6e21dc11faf72c2a281b7d56145f19",
|
||||
"444b240fe3ed86d0e2ef4ce7d851edde22155582aa0914797b726cd058b6f45932e0e129516876527b1dd88fc66d7119f4ab3bed93a61a0e2d2d2aeac336d958",
|
||||
"bfbabbef45554ccfa0dc83752a19cc35d5920956b301d558d772282bc867009168e9e98606bb5ba73a385de5749228c925a85019b71f72fe29b3cd37ca52efe6",
|
||||
"9c4d0c3e1cdbbf485bec86f41cec7c98373f0e09f392849aaa229ebfbf397b22085529cb7ef39f9c7c2222a514182b1effaa178cc3687b1b2b6cbcb6fdeb96f8",
|
||||
"477176b3bfcbadd7657c23c24625e4d0d674d1868f006006398af97aa41877c8e70d3d14c3bbc9bbcdcea801bd0e1599af1f3eec67405170f4e26c964a57a8b7",
|
||||
"a78c490eda3173bb3f10dee52f110fb1c08e0302230b85ddd7c11257d92de148785ef00c039c0bb8eb9808a35b2d8c080f572859714c9d4069c5bcaf090e898e",
|
||||
"58d023397beb5b4145cb2255b07d74290b36d9fd1e594afbd8eea47c205b2efbfe6f46190faf95af504ab072e36f6c85d767a321bfd7f22687a4abbf494a689c",
|
||||
"4001ec74d5a46fd29c2c3cdbe5d1b9f20e51a941be98d2a4e1e2fbf866a672121db6f81a514cfd10e7358d571bdba48e4ce708b9d124894bc0b5ed554935f73a",
|
||||
"ccd1b22dab6511225d2401ea2d8625d206a12473cc732b615e5640cefff0a4adf971b0e827a619e0a80f5db9ccd0962329010d07e34a2064e731c520817b2183",
|
||||
"b4a0a9e3574edb9e1e72aa31e39cc5f30dbf943f8cabc408449654a39131e66d718a18819143e3ea96b4a1895988a1c0056cf2b6e04f9ac19d657383c2910c44",
|
||||
"447becab16630608d39f4f058b16f7af95b85a76aa0fa7cea2b80755fb76e9c804f2ca78f02643c915fbf2fce5e19de86000de03b18861815a83126071f8a37b",
|
||||
"54e6dab9977380a5665822db93374eda528d9beb626f9b94027071cb26675e112b4a7fec941ee60a81e4d2ea3ff7bc52cfc45dfbfe735a1c646b2cf6d6a49b62",
|
||||
"3ea62625949e3646704d7e3c906f82f6c028f540f5f72a794b0c57bf97b7649bfeb90b01d3ca3e829de21b3826e6f87014d3c77350cb5a15ff5d468a81bec160",
|
||||
"213cfe145c54a33691569980e5938c8883a46d84d149c8ff1a67cd287b4d49c6da69d3a035443db085983d0efe63706bd5b6f15a7da459e8d50a19093db55e80",
|
||||
"5716c4a38f38db104e494a0a27cbe89a26a6bb6f499ec01c8c01aa7cb88497e75148cd6eee12a7168b6f78ab74e4be749251a1a74c38c86d6129177e2889e0b6",
|
||||
"030460a98bdf9ff17cd96404f28fc304f2b7c04eaade53677fd28f788ca22186b8bc80dd21d17f8549c711aff0e514e19d4e15f5990252a03e082f28dc2052f6",
|
||||
"19e7f1ccee88a10672333e390cf22013a8c734c6cb9eab41f17c3c8032a2e4aca0569ea36f0860c7a1af28fa476840d66011168859334a9e4ef9cc2e61a0e29e",
|
||||
"29f8b8c78c80f2fcb4bdf7825ed90a70d625ff785d262677e250c04f3720c888d03f8045e4edf3f5285bd39d928a10a7d0a5df00b8484ac2868142a1e8bea351",
|
||||
"5c52920a7263e39d57920ca0cb752ac6d79a04fef8a7a216a1ecb7115ce06d89fd7d735bd6f4272555dba22c2d1c96e6352322c62c5630fde0f4777a76c3de2c",
|
||||
"83b098f262251bf660064a9d3511ce7687a09e6dfbb878299c30e93dfb43a9314db9a600337db26ebeedaf2256a96dabe9b29e7573ad11c3523d874dde5be7ed",
|
||||
"9447d98aa5c9331352f43d3e56d0a9a9f9581865998e2885cc56dd0a0bd5a7b50595bd10f7529bcd31f37dc16a1465d594079667da2a3fcb70401498837cedeb",
|
||||
"867732f2feeb23893097561ac710a4bff453be9cfbedba8ba324f9d312a82d732e1b83b829fdcd177b882ca0c1bf544b223be529924a246a63cf059bfdc50a1b",
|
||||
"f15ab26d4cdfcf56e196bb6ba170a8fccc414de9285afd98a3d3cf2fb88fcbc0f19832ac433a5b2cc2392a4ce34332987d8d2c2bef6c3466138db0c6e42fa47b",
|
||||
"2813516d68ed4a08b39d648aa6aacd81e9d655ecd5f0c13556c60fdf0d333ea38464b36c02baccd746e9575e96c63014f074ae34a0a25b320f0fbedd6acf7665",
|
||||
"d3259afca8a48962fa892e145acf547f26923ae8d4924c8a531581526b04b44c7af83c643ef5a0bc282d36f3fb04c84e28b351f40c74b69dc7840bc717b6f15f",
|
||||
"f14b061ae359fa31b989e30332bfe8de8cc8cdb568e14be214a2223b84caab7419549ecfcc96ce2acec119485d87d157d3a8734fc426597d64f36570ceaf224d",
|
||||
"55e70b01d1fbf8b23b57fb62e26c2ce54f13f8fa2464e6eb98d16a6117026d8b90819012496d4071ebe2e59557ece3519a7aa45802f9615374877332b73490b3",
|
||||
"25261eb296971d6e4a71b2928e64839c67d422872bf9f3c31993615222de9f8f0b2c4be8548559b4b354e736416e3218d4e8a1e219a4a6d43e1a9a521d0e75fc",
|
||||
"08307f347c41294e34bb54cb42b1522d22f824f7b6e5db50fda096798e181a8f026fa27b4ae45d52a62caf9d5198e24a4913c6671775b2d723c1239bfbf016d7",
|
||||
"1e5c62e7e9bfa1b118747a2de08b3ca10112af96a46e4b22c3fc06f9bfee4eb5c49e057a4a4886234324572576bb9b5ecfde0d99b0de4f98ec16e4d1b85fa947",
|
||||
"c74a77395fb8bc126447454838e561e962853dc7eb49a1e3cb67c3d0851f3e39517be8c350ac910903d49cd2bfdf545c99316d0346170b739f0add5d533c2cfc",
|
||||
"0dd57b423cc01eb2861391eb886a0d17079b933fc76eb3fc08a19f8a74952cb68f6bcdc644f77370966e4d13e80560bcf082ef0479d48fbbab4df03b53a4e178",
|
||||
"4d8dc3923edccdfce70072398b8a3da5c31fcb3ee3b645c85f717cbaeb4b673a19394425a585bfb464d92f1597d0b754d163f97ced343b25db5a70ef48ebb34f",
|
||||
"f0a50553e4dfb0c4e3e3d3ba82034857e3b1e50918f5b8a7d698e10d242b0fb544af6c92d0c3aaf9932220416117b4e78ecb8a8f430e13b82a5915290a5819c5",
|
||||
"b15543f3f736086627cc5365e7e8988c2ef155c0fd4f428961b00d1526f04d6d6a658b4b8ed32c5d8621e7f4f8e8a933d9ecc9dd1b8333cbe28cfc37d9719e1c",
|
||||
"7b4fa158e415fef023247264cbbe15d16d91a44424a8db707eb1e2033c30e9e1e7c8c0864595d2cb8c580eb47e9d16abbd7e44e824f7cedb7def57130e52cfe9",
|
||||
"60424ff23234c34dc9687ad502869372cc31a59380186bc2361c835d972f49666eb1ac69629de646f03f9b4db9e2ace093fbfdf8f20ab5f98541978be8ef549f",
|
||||
"7406018ce704d84f5eb9c79fea97da345699468a350ee0b2d0f3a4bf2070304ea862d72a51c57d3064947286f531e0eaf7563702262e6c724abf5ed8c8398d17",
|
||||
"14ef5c6d647b3bd1e6e32006c231199810de5c4dc88e70240273b0ea18e651a3eb4f5ca3114b8a56716969c7cda27e0c8db832ad5e89a2dc6cb0adbe7d93abd1",
|
||||
"38cf6c24e3e08bcf1f6cf3d1b1f65b905239a3118033249e448113ec632ea6dc346feeb2571c38bd9a7398b2221280328002b23e1a45adaffe66d93f6564eaa2",
|
||||
"6cd7208a4bc7e7e56201bbba02a0f489cd384abe40afd4222f158b3d986ee72a54c50fb64fd4ed2530eda2c8af2928a0da6d4f830ae1c9db469dfd970f12a56f",
|
||||
"659858f0b5c9edab5b94fd732f6e6b17c51cc096104f09beb3afc3aa467c2ecf885c4c6541effa9023d3b5738ae5a14d867e15db06fe1f9d1127b77e1aabb516",
|
||||
"26cca0126f5d1a813c62e5c71001c046f9c92095704550be5873a495a999ad010a4f79491f24f286500adce1a137bc2084e4949f5b7294cefe51ecaff8e95cba",
|
||||
"4147c1f55172788c5567c561feef876f621fff1ce87786b8467637e70dfbcd0dbdb6415cb600954ab9c04c0e457e625b407222c0fe1ae21b2143688ada94dc58",
|
||||
"5b1bf154c62a8af6e93d35f18f7f90abb16a6ef0e8d1aecd118bf70167bab2af08935c6fdc0663ce74482d17a8e54b546d1c296631c65f3b522a515839d43d71",
|
||||
"9f600419a4e8f4fb834c24b0f7fc13bf4e279d98e8a3c765ee934917403e3a66097182ea21453cb63ebbe8b73a9c2167596446438c57627f330badd4f569f7d6",
|
||||
"457ef6466a8924fd8011a34471a5a1ac8ccd9bd0d07a97414ac943021ce4b9e4b9c8db0a28f016ed43b1542481990022147b313e194671131e708dd43a3ed7dc",
|
||||
"9997b2194d9af6dfcb9143f41c0ed83d3a3f4388361103d38c2a49b280a581212715fd908d41c651f5c715ca38c0ce2830a37e00e508ced1bcdc320e5e4d1e2e",
|
||||
"5c6bbf16baa180f986bd40a1287ed4c549770e7284858fc47bc21ab95ebbf3374b4ee3fd9f2af60f3395221b2acc76f2d34c132954049f8a3a996f1e32ec84e5",
|
||||
"d10bf9a15b1c9fc8d41f89bb140bf0be08d2f3666176d13baac4d381358ad074c9d4748c300520eb026daeaea7c5b158892fde4e8ec17dc998dcd507df26eb63",
|
||||
"2fc6e69fa26a89a5ed269092cb9b2a449a4409a7a44011eecad13d7c4b0456602d402fa5844f1a7a758136ce3d5d8d0e8b86921ffff4f692dd95bdc8e5ff0052",
|
||||
"fcbe8be7dcb49a32dbdf239459e26308b84dff1ea480df8d104eeff34b46fae98627b450c2267d48c0946a697c5b59531452ac0484f1c84e3a33d0c339bb2e28",
|
||||
"a19093a6e3bcf5952f850f2030f69b9606f147f90b8baee3362da71d9f35b44ef9d8f0a7712ba1877fddcd2d8ea8f1e5a773d0b745d4725605983a2de901f803",
|
||||
"3c2006423f73e268fa59d2920377eb29a4f9a8b462be15983ee3b85ae8a78e992633581a9099893b63db30241c34f643027dc878279af5850d7e2d4a2653073a",
|
||||
"d0f2f2e3787653f77cce2fa24835785bbd0c433fc779465a115149905a9dd1cb827a628506d457fcf124a0c2aef9ce2d2a0a0f63545570d8667ff9e2eba07334",
|
||||
"78a9fc048e25c6dcb5de45667de8ffdd3a93711141d594e9fa62a959475da6075ea8f0916e84e45ad911b75467077ee52d2c9aebf4d58f20ce4a3a00458b05d4",
|
||||
"45813f441769ab6ed37d349ff6e72267d76ae6bb3e3c612ec05c6e02a12af5a37c918b52bf74267c3f6a3f183a8064ff84c07b193d08066789a01accdb6f9340",
|
||||
"956da1c68d83a7b881e01b9a966c3c0bf27f68606a8b71d457bd016d4c41dd8a380c709a296cb4c6544792920fd788835771a07d4a16fb52ed48050331dc4c8b",
|
||||
"df186c2dc09caa48e14e942f75de5ac1b7a21e4f9f072a5b371e09e07345b0740c76177b01278808fec025eded9822c122afd1c63e6f0ce2e32631041063145c",
|
||||
"87475640966a9fdcd6d3a3b5a2cca5c08f0d882b10243c0ec1bf3c6b1c37f2cd3212f19a057864477d5eaf8faed73f2937c768a0af415e84bbce6bd7de23b660",
|
||||
"c3b573bbe10949a0fbd4ff884c446f2229b76902f9dfdbb8a0353da5c83ca14e8151bbaac82fd1576a009adc6f1935cf26edd4f1fb8da483e6c5cd9d8923adc3",
|
||||
"b09d8d0bba8a7286e43568f7907550e42036d674e3c8fc34d8ca46f771d6466b70fb605875f6a863c877d12f07063fdc2e90ccd459b1910dcd52d8f10b2b0a15",
|
||||
"af3a22bf75b21abfb0acd54422ba1b7300a952eff02ebeb65b5c234471a98df32f4f9643ce1904108a168767924280bd76c83f8c82d9a79d9259b195362a2a04",
|
||||
"bf4ff2221b7e6957a724cd964aa3d5d0d9941f540413752f4699d8101b3e537508bf09f8508b317736ffd265f2847aa7d84bd2d97569c49d632aed9945e5fa5e",
|
||||
"9c6b6b78199b1bdacb4300e31479fa622a6b5bc80d4678a6078f88a8268cd7206a2799e8d4621a464ef6b43dd8adffe97caf221b22b6b8778b149a822aefbb09",
|
||||
"890656f09c99d280b5ecb381f56427b813751bc652c7828078b23a4af83b4e3a61fdbac61f89bee84ea6bee760c047f25c6b0a201c69a38fd6fd971af18588bb",
|
||||
"31a046f7882ffe6f83ce472e9a0701832ec7b3f76fbcfd1df60fe3ea48fde1651254247c3fd95e100f9172731e17fd5297c11f4bb328363ca361624a81af797c",
|
||||
"27a60b2d00e7a671d47d0aec2a686a0ac04b52f40ab6629028eb7d13f4baa99ac0fe46ee6c814944f2f4b4d20e9378e4847ea44c13178091e277b87ea7a55711",
|
||||
"8b5ccef194162c1f19d68f91e0b0928f289ec5283720840c2f73d253111238dcfe94af2b59c2c1ca2591901a7bc060e7459b6c47df0f71701a35cc0aa831b5b6",
|
||||
"57ab6c4b2229aeb3b70476d803cd63812f107ce6da17fed9b17875e8f86c724f49e024cbf3a1b8b119c50357652b81879d2ade2d588b9e4f7cedba0e4644c9ee",
|
||||
"0190a8dac320a739f322e15731aa140ddaf5bed294d5c82e54fef29f214e18aafaa84f8be99af62950266b8f901f15dd4c5d35516fc35b4cab2e96e4695bbe1c",
|
||||
"d14d7c4c415eeb0e10b159224bea127ebd84f9591c702a330f5bb7bb7aa44ea39de6ed01f18da7adf40cfb97c5d152c27528824b21e239526af8f36b214e0cfb",
|
||||
"be28c4be706970488fac7d29c3bd5c4e986085c4c3332f1f3fd30973db614164ba2f31a78875ffdc150325c88327a9443ed04fdfe5be93876d1628560c764a80",
|
||||
"031da1069e3a2e9c3382e436ffd79df74b1ca6a8adb2deabe676ab45994cbc054f037d2f0eace858d32c14e2d1c8b46077308e3bdc2c1b53172ecf7a8c14e349",
|
||||
"4665cef8ba4db4d0acb118f2987f0bb09f8f86aa445aa3d5fc9a8b346864787489e8fcecc125d17e9b56e12988eac5ecc7286883db0661b8ff05da2afff30fe4",
|
||||
"63b7032e5f930cc9939517f9e986816cfbec2be59b9568b13f2ead05bae7777cab620c6659404f7409e4199a3be5f7865aa7cbdf8c4253f7e8219b1bd5f46fea",
|
||||
"9f09bf093a2b0ff8c2634b49e37f1b2135b447aa9144c9787dbfd92129316c99e88aab8a21fdef2372d1189aec500f95775f1f92bfb45545e4259fb9b7b02d14",
|
||||
"f9f8493c68088807df7f6a2693d64ea59f03e9e05a223e68524ca32195a4734b654fcea4d2734c866cf95c889fb10c49159be2f5043dc98bb55e02ef7bdcb082",
|
||||
"3c9a7359ab4febce07b20ac447b06a240b7fe1dae5439c49b60b5819f7812e4c172406c1aac316713cf0dded1038077258e2eff5b33913d9d95caeb4e6c6b970",
|
||||
"ad6aab8084510e822cfce8625d62cf4de655f4763884c71e80bab9ac9d5318dba4a6033ed29084e65216c031606ca17615dcfe3ba11d26851ae0999ca6e232cf",
|
||||
"156e9e6261374c9dc884f36e70f0fe1ab9297997b836fa7d170a9c9ebf575b881e7bcea44d6c0248d35597907154828955be19135852f9228815eca024a8adfb",
|
||||
"4215407633f4cca9b6788be93e6aa3d963c7d6ce4b147247099f46a3acb500a30038cb3e788c3d29f132ad844e80e9e99251f6db96acd8a091cfc770af53847b",
|
||||
"1c077e279de6548523502b6df800ffdab5e2c3e9442eb838f58c295f3b147cef9d701c41c321283f00c71affa0619310399126295b78dd4d1a74572ef9ed5135",
|
||||
"f07a555f49fe481cf4cd0a87b71b82e4a95064d06677fdd90a0eb598877ba1c83d4677b393c3a3b6661c421f5b12cb99d20376ba7275c2f3a8f5a9b7821720da",
|
||||
"b5911b380d20c7b04323e4026b38e200f534259233b581e02c1e3e2d8438d6c66d5a4eb201d5a8b75072c4ec29106334da70bc79521b0ced2cfd533f5ff84f95",
|
||||
"01f070a09bae911296361f91aa0e8e0d09a7725478536d9d48c5fe1e5e7c3c5b9b9d6eb07796f6da57ae562a7d70e882e37adfde83f0c433c2cd363536bb22c8",
|
||||
"6f793eb4374a48b0775acaf9adcf8e45e54270c9475f004ad8d5973e2aca52747ff4ed04ae967275b9f9eb0e1ff75fb4f794fa8be9add7a41304868d103fab10",
|
||||
"965f20f139765fcc4ce4ba3794675863cac24db472cd2b799d035bce3dbea502da7b524865f6b811d8c5828d3a889646fe64a380da1aa7c7044e9f245dced128",
|
||||
"ec295b5783601244c30e4641e3b45be222c4dce77a58700f53bc8ec52a941690b4d0b087fb6fcb3f39832b9de8f75ec20bd43079811749cdc907edb94157d180",
|
||||
"61c72f8ccc91dbb54ca6750bc489672de09faedb8fdd4f94ff2320909a303f5d5a98481c0bc1a625419fb4debfbf7f8a53bb07ec3d985e8ea11e72d559940780",
|
||||
"afd8145b259eefc8d12620c3c5b03e1ed8fd2ccefe0365078c80fd42c1770e28b44948f27e65a1886690110db814397b68e43d80d1ba16dfa358e739c898cfa3",
|
||||
"552fc7893cf1ce933ada35c0da98844e41545e244c3157a1428d7b4c21f9cd7e4071aed77b7ca9f1c38fba32237412ef21a342742ec8324378f21e507fafdd88",
|
||||
"467a33fbadf5ebc52596ef86aaaefc6faba8ee651b1ce04de368a03a5a9040ef2835e00adb09abb3fbd2bce818a2413d0b0253b5bda4fc5b2f6f85f3fd5b55f2",
|
||||
"22eff8e6dd5236f5f57d94ede874d6c9428e8f5d566f17cd6d1848cd752fe13c655cb10fbaaff76872f2bf2da99e15dc624075e1ec2f58a3f64072121838569e",
|
||||
"9cec6bbf62c4bce4138abae1cbec8dad31950444e90321b1347196834c114b864af3f3cc3508f83751ffb4eda7c84d140734bb4263c3625c00f04f4c8068981b",
|
||||
"a8b60fa4fc2442f6f1514ad7402626920cc7c2c9f72124b8cba8ee2cb7c4586f658a4410cffcc0ab88343955e094c6af0d20d0c714fb0a988f543f300f58d389",
|
||||
"8271cc45dfa5e4170e847e8630b952cf9c2aa777d06f26a7585b8381f188dacc7337391cfcc94b053dc4ec29cc17f077870428f1ac23fddda165ef5a3f155f39",
|
||||
"bf23c0c25c8060e4f6995f1623a3bebecaa96e308680000a8aa3cd56bb1a6da099e10d9231b37f4519b2efd2c24de72f31a5f19535241b4a59fa3c03ceb790e7",
|
||||
"877fd652c05281009c0a5250e7a3a671f8b18c108817fe4a874de22da8e45db11958a600c5f62e67d36cbf84474cf244a9c2b03a9fb9dc711cd1a2cab6f3fae0",
|
||||
"29df4d87ea444baf5bcdf5f4e41579e28a67de84149f06c03f110ea84f572a9f676addd04c4878f49c5c00accda441b1a387caceb2e993bb7a10cd8c2d6717e1",
|
||||
"710dacb166844639cd7b637c274209424e2449dc35d790bbfa4f76177054a36b3b76fac0ca6e61df1e687000678ac0746df75d0a3954897681fd393a155a1bb4",
|
||||
"c1d5f93b8dea1f2571babccbc01764541a0cda87e444d673c50966ca559c33354b3acb26e5d5781ffb28847a4b4754d77008c62a835835f500dea7c3b58bdae2",
|
||||
"a41e41271cdab8af4d72b104bfb2ad041ac4df14677da671d85640c4b187f50c2b66513c4619fbd5d5dc4fe65dd37b9042e9848dda556a504caa2b1c6afe4730",
|
||||
"e7bcbacdc379c43d81ebadcb37781552fc1d753e8cf310d968392d06c91f1d64cc9e90ce1d22c32d277fc6cda433a4d442c762e9eacf2c259f32d64cf9da3a22",
|
||||
"51755b4ac5456b13218a19c5b9242f57c4a981e4d4ecdce09a3193362b808a579345d4881c2607a56534dd7f21956aff72c2f4173a6e7b6cc2212ba0e3daee1f",
|
||||
"dcc2c4beb9c1f2607b786c20c631972347034c1cc02fcc7d02ff01099cfe1c6989840ac213923629113aa8bad713ccf0fe4ce13264fb32b8b0fe372da382544a",
|
||||
"3d55176acea4a7e3a65ffa9fb10a7a1767199cf077cee9f71532d67cd7c73c9f93cfc37ccdcc1fdef50aad46a504a650d298d597a3a9fa95c6c40cb71fa5e725",
|
||||
"d07713c005de96dd21d2eb8bbeca66746ea51a31ae922a3e74864889540a48db27d7e4c90311638b224bf0201b501891754848113c266108d0adb13db71909c7",
|
||||
"58983c21433d950caa23e4bc18543b8e601c204318532152daf5e159a0cd1480183d29285c05f129cb0cc3164687928086ffe380158df1d394c6ac0d4288bca8",
|
||||
"8100a8dc528d2b682ab4250801ba33f02a3e94c54dac0ae1482aa21f51ef3a82f3807e6facb0aeb05947bf7aa2adcb034356f90fa4560ede02201a37e411ec1a",
|
||||
"07025f1bb6c784f3fe49de5c14b936a5acacacaab33f6ac4d0e00ab6a12483d6bec00b4fe67c7ca5cc508c2a53efb5bfa5398769d843ff0d9e8b14d36a01a77f",
|
||||
"ba6aefd972b6186e027a76273a4a723321a3f580cfa894da5a9ce8e721c828552c64dacee3a7fd2d743b5c35ad0c8efa71f8ce99bf96334710e2c2346e8f3c52",
|
||||
"e0721e02517aedfa4e7e9ba503e025fd46e714566dc889a84cbfe56a55dfbe2fc4938ac4120588335deac8ef3fa229adc9647f54ad2e3472234f9b34efc46543",
|
||||
"b6292669ccd38d5f01caae96ba272c76a879a45743afa0725d83b9ebb26665b731f1848c52f11972b6644f554c064fa90780dbbbf3a89d4fc31f67df3e5857ef",
|
||||
"2319e3789c47e2daa5fe807f61bec2a1a6537fa03f19ff32e87eecbfd64b7e0e8ccff439ac333b040f19b0c4ddd11a61e24ac1fe0f10a039806c5dcc0da3d115",
|
||||
"f59711d44a031d5f97a9413c065d1e614c417ede998590325f49bad2fd444d3e4418be19aec4e11449ac1a57207898bc57d76a1bcf3566292c20c683a5c4648f",
|
||||
"df0a9d0c212843a6a934e3902b2dd30d17fba5f969d2030b12a546d8a6a45e80cf5635f071f0452e9c919275da99bed51eb1173c1af0518726b75b0ec3bae2b5",
|
||||
"a3eb6e6c7bf2fb8b28bfe8b15e15bb500f781ecc86f778c3a4e655fc5869bf2846a245d4e33b7b14436a17e63be79b36655c226a50ffbc7124207b0202342db5",
|
||||
"56d4cbcd070563426a017069425c2cd2ae540668287a5fb9dac432eb8ab1a353a30f2fe1f40d83333afe696a267795408a92fe7da07a0c1814cf77f36e105ee8",
|
||||
"e59b9987d428b3eda37d80abdb16cd2b0aef674c2b1dda4432ea91ee6c935c684b48b4428a8cc740e579a30deff35a803013820dd23f14ae1d8413b5c8672aec",
|
||||
"cd9fcc99f99d4cc16d031900b2a736e1508db4b586814e6345857f354a70ccecb1df3b50a19adaf43c278efa423ff4bb6c523ec7fd7859b97b168a7ebff8467c",
|
||||
"0602185d8c3a78738b99164b8bc6ffb21c7debebbf806372e0da44d121545597b9c662a255dc31542cf995ecbe6a50fb5e6e0ee4ef240fe557eded1188087e86",
|
||||
"c08afa5b927bf08097afc5fff9ca4e7800125c1f52f2af3553fa2b89e1e3015c4f87d5e0a48956ad31450b083dad147ffb5ec03434a26830cf37d103ab50c5da",
|
||||
"36f1e1c11d6ef6bc3b536d505d544a871522c5c2a253067ec9933b6ec25464daf985525f5b9560a16d890259ac1bb5cc67c0c469cde133def000ea1d686f4f5d",
|
||||
"bf2ab2e2470f5438c3b689e66e7686fffa0cb1e1798ad3a86ff99075bf6138e33d9c0ce59afb24ac67a02af34428191a9a0a6041c07471b7c3b1a752d6fc0b8b",
|
||||
"d400601f9728ccc4c92342d9787d8d28ab323af375ca5624b4bb91d17271fbae862e413be73f1f68e615b8c5c391be0dbd9144746eb339ad541547ba9c468a17",
|
||||
"79fe2fe157eb85a038abb8ebbc647731d2c83f51b0ac6ee14aa284cb6a3549a4dcceb300740a825f52f5fb30b03b8c4d8b0f4aa67a63f4a94e3303c4eda4c02b",
|
||||
"75351313b52a8529298d8c186b1768666dcca8595317d7a4816eb88c062020c0c8efc554bb341b64688db5ccafc35f3c3cd09d6564b36d7b04a248e146980d4b",
|
||||
"e3128b1d311d02179d7f25f97a5a8bee2cc8c86303644fcd664e157d1fef00f23e46f9a5e8e5c890ce565bb6abd4302ce06469d52a5bd53e1c5a54d04649dc03",
|
||||
"c2382a72d2d3ace9d5933d00b60827ed380cda08d0ba5f6dd41e29ee6dbe8ecb9235f06be95d83b6816a2fb7a5ad47035e8a4b69a4884b99e4bece58cab25d44",
|
||||
"6b1c69460bbd50ac2ed6f32e6e887cfed407d47dcf0aaa60387fe320d780bd03eab6d7baeb2a07d10cd552a300341354ea9a5f03183a623f92a2d4d9f00926af",
|
||||
"6cda206c80cdc9c44ba990e0328c314f819b142d00630404c48c05dc76d1b00ce4d72fc6a48e1469ddef609412c364820854214b4869af090f00d3c1ba443e1b",
|
||||
"7ffc8c26fbd6a0f7a609e6e1939f6a9edf1b0b066641fb76c4f9602ed748d11602496b35355b1aa255850a509d2f8ee18c8f3e1d7dcbc37a136598f56a59ed17",
|
||||
"70de1f08dd4e09d5fc151f17fc991a23abfc05104290d50468882efaf582b6ec2f14f577c0d68c3ad06626916e3c86e6daab6c53e5163e82b6bd0ce49fc0d8df",
|
||||
"4f81935756ed35ee2058ee0c6a6110d6fac5cb6a4f46aa9411603f99965823b6da4838276c5c06bc7880e376d92758369ee7305bcec8d3cfd28ccabb7b4f0579",
|
||||
"abcb61cb3683d18f27ad527908ed2d32a0426cb7bb4bf18061903a7dc42e7e76f982382304d18af8c80d91dd58dd47af76f8e2c36e28af2476b4bccf82e89fdf",
|
||||
"02d261ad56a526331b643dd2186de9a82e72a58223cd1e723686c53d869b83b94632b7b647ab2afc0d522e29da3a5615b741d82852e0df41b66007dbcba90543",
|
||||
"c5832741fa30c5436823015383d297ff4c4a5d7276c3f902122066e04be5431b1a85faf73b918434f9300963d1dea9e8ac3924ef490226edeea5f743e410669f",
|
||||
"cfaeab268cd075a5a6aed515023a032d54f2f2ff733ce0cbc78db51db4504d675923f82746d6594606ad5d67734b11a67cc6a468c2032e43ca1a94c6273a985e",
|
||||
"860850f92eb268272b67d133609bd64e34f61bf03f4c1738645c17fec818465d7ecd2be2907641130025fda79470ab731646e7f69440e8367ea76ac4cee8a1df",
|
||||
"84b154ed29bbedefa648286839046f4b5aa34430e2d67f7496e4c39f2c7ea78995f69e1292200016f16ac3b37700e6c7e7861afc396b64a59a1dbf47a55c4bbc",
|
||||
"aeeec260a5d8eff5ccab8b95da435a63ed7a21ea7fc7559413fd617e33609f8c290e64bbacc528f6c080262288b0f0a3219be223c991bee92e72349593e67638",
|
||||
"8ad78a9f26601d127e8d2f2f976e63d19a054a17dcf59e0f013ab54a6887bbdffde7aaae117e0fbf3271016595b9d9c712c01b2c53e9655a382bc4522e616645",
|
||||
"8934159dade1ac74147dfa282c75954fcef443ef25f80dfe9fb6ea633b8545111d08b34ef43fff17026c7964f5deac6d2b3c29dacf2747f022df5967dfdc1a0a",
|
||||
"cd36dd0b240614cf2fa2b9e959679dcdd72ec0cd58a43da3790a92f6cdeb9e1e795e478a0a47d371100d340c5cedcdbbc9e68b3f460818e5bdff7b4cda4c2744",
|
||||
"00df4e099b807137a85990f49d3a94315e5a5f7f7a6076b303e96b056fb93800111f479628e2f8db59aeb6ac70c3b61f51f9b46e80ffdeae25ebddb4af6cb4ee",
|
||||
"2b9c955e6caed4b7c9e246b86f9a1726e810c59d126cee66ed71bf015b83558a4b6d84d18dc3ff4620c2ffb722359fdef85ba0d4e2d22ecbe0ed784f99afe587",
|
||||
"181df0a261a2f7d29ea5a15772715105d450a4b6c236f699f462d60ca76487feedfc9f5eb92df838e8fb5dc3694e84c5e0f4a10b761f506762be052c745a6ee8",
|
||||
"21fb203458bf3a7e9a80439f9a902899cd5de0139dfd56f7110c9dec8437b26bda63de2f565926d85edb1d6c6825669743dd9992653d13979544d5dc8228bfaa",
|
||||
"ef021f29c5ffb830e64b9aa9058dd660fd2fcb81c497a7e698bcfbf59de5ad4a86ff93c10a4b9d1ae5774725f9072dcde9e1f199bab91f8bff921864aa502eee",
|
||||
"b3cfda40526b7f1d37569bdfcdf911e5a6efe6b2ec90a0454c47b2c046bf130fc3b352b34df4813d48d33ab8e269b69b075676cb6d00a8dcf9e1f967ec191b2c",
|
||||
"b4c6c3b267071eefb9c8c72e0e2b941293641f8673cb70c1cc26ad1e73cf141755860ad19b34c2f34ed35bb52ec4507cc1fe59047743a5f0c6febde625e26091",
|
||||
"57a34f2bcca60d4b85103b830c9d7952a416be5263ae429c9e5e53fe8590a8f78ec65a51109ea85dcdf7b6223f9f2b340539fad81923dbf8edabf95129e4dff6",
|
||||
"9cf46662fcd61a232277b685663b8b5da832dfd9a3b8ccfeec993ec6ac415ad07e048adfe414df272770dba867da5c1224c6fd0aa0c2187d426ac647e9887361",
|
||||
"5ce1042ab4d542c2f9ee9d17262af8164098935bef173d0e18489b04841746cd2f2df866bd7da6e5ef9024c648023ec723ab9c62fd80285739d84f15d2ab515a",
|
||||
"8488396bd4a8729b7a473178f232dadf3f0f8e22678ba5a43e041e72da1e2cf82194c307207a54cb8156293339eaec693ff66bfcd5efc65e95e4ecaf54530abd",
|
||||
"f598da901c3835bca560779037dfde9f0c51dc61c0b760fc1522d7b470ee63f5bdc6498476e86049ad86e4e21af2854a984cc905427d2f17f66b1f41c3da6f61",
|
||||
"5f93269798cf02132107337660a8d7a177354c0212eb93e555e7c37a08aef3d8dce01217011cd965c04dd2c105f2e2b6cae5e4e6bcaf09dfbee3e0a6a6357c37",
|
||||
"0ecf581d47bac9230986faabd70c2f5b80e91066f0ec55a842937882286d2ca007bb4e973b0b091d52167ff7c4009c7ab4ad38fff1dceacdb7be81ef4a452952",
|
||||
"5aeca8abe1528582b2a307b4009585498a3d467ca6101cb0c5126f9976056e9ffc123cc20c302b2a737f492c75d21f01512c90ca0541dfa56e950a321dcb28d8",
|
||||
"732fbf8f1cb2b8329263ede27858fe46f8d3354d376bcda0548e7ce1fa9dd11f85eb661fe950b543aa635ca4d3f04ede5b32d6b656e5ce1c44d35c4a6c56cff8",
|
||||
"d5e938735d63788c80100aefd18648d18cf272f69f20ff24cfe2895c088ad08b0104da1672a4eb26fc52545cc7d7a01b266cf546c403c45bd129eb41bdd9200b",
|
||||
"65a245b49352ee297d91af8c8be00528ac6e046dd83ac7bd465a98816dd68f3e00e1ae8f895327a7e9a8c9326598379a29c9fc91ec0c6eef08f3e2b216c11008",
|
||||
"c95654b63019130ab45dd0fb4941b98aeb3af2a123913eca2ce99b3e97410a7bf8661cc7fbaa2bc1cf2b13113b1ed40a0118b88e5fffc3542759ea007ed4c58d",
|
||||
"1eb262f38fa494431f017dad44c0dfb69324ac032f04b657fc91a88647bb74760f24e7c956514f0cf002990b182c1642b9b2426e96a61187e4e012f00e217d84",
|
||||
"3b955aeebfa5151ac1ab8e3f5cc1e3767084c842a575d36269836e97353d41622b731dddcd5f269550a3a5b87be1e90326340b6e0e62555815d9600597ac6ef9",
|
||||
"68289f6605473ba0e4f241baf7477a9885426a858f19ef2a18b0d40ef8e41282ed5526b519799e270f13881327918278755711071d8511fe963e3b5606aa3716",
|
||||
"80a33787542612c38f6bcd7cd86cab460227509b1cbad5ec408a91413d51155a0476dadbf3a2518e4a6e77cc346622e347a469bf8baa5f04eb2d98705355d063",
|
||||
"34629bc6d831391c4cdf8af1b4b7b6b8e8ee17cf98c70e5dd586cd99f14b11df945166236a9571e6d591bb83ee4d164d46f6b9d8ef86ff865a81bfb91b00424b",
|
||||
"8b7cc339163863bb4383e542b0ef0e7cf36b84ad932cdf5a80419ec9ad692e7a7e784d2c7cb3796a18b8f800035f3aa06c824100611120a7bdeb35618ccb81b7",
|
||||
"4f084e4939dd5a7f5a658fad58a18a15c25c32ec1c7fd5c5c6c3e892b3971aeaac308304ef17b1c47239ea4bb398b3fd6d4528d8de8e768ae0f1a5a5c6b5c297",
|
||||
"48f407a1af5b8009b2051742e8cf5cd5656669e7d722ee8e7bd202060849442168d8facc117c012bfb7bf449d99befff6a34aea203f1d8d352722be5014ec818",
|
||||
"a6aa82cd1e426f9a73bfa39a29037876114655b8c22d6d3ff8b638ae7dea6b17843e09e52eb66fa1e475e4a8a3de429b7d0f4a776fcb8bdc9b9fede7d52e815f",
|
||||
"5817027d6bdd00c5dd10ac593cd560372270775a18526d7e6f13872a2e20eab664625be7168ac4bd7c9e0ce7fc4099e0f48442e2c767191c6e1284e9b2ccea8c",
|
||||
"08e41028340a45c74e4052b3a8d6389e22e043a1adab5e28d97619450d723469b620caa519b81c14523854f619fd3027e3847bd03276e60604a80ddb4de876d6",
|
||||
"130b8420537eb07d72abda07c85acbd8b9a44f16321dd0422145f809673d30f2b5321326e2bff317ef3fef983c51c4f8ab24a325d298e34afce569a82555774c",
|
||||
"ac49b844afaa012e31c474ca263648844fd2f6307992c2f752aca02c3828965175794deee2d2ee95c61cd284f6b5a2d75e2ef2b29ee8149e77fb81447b2fd04b",
|
||||
"b9d7ca81cc60bb9578e44024e5a0a0be80f27336a6a9f4e53df3999cb191280b090e2ac2d29c5baad9d71415bdc129e69aa2667af6a7fd5e189fccdcee817340",
|
||||
"a755e113386572c75ced61d719706070b9146048e42a9f8cd35667a088b42f08808abdf77e618abd959afc757379ca2c00bcc1a48390fa2bff618b1e0078a613",
|
||||
"a73c7debed326f1c0db0795ee7d6e3946894b826b1f8101c56c823ba17168312e7f53fc7dbe52c3e11e69852c40485e2ef182477862ea6a34ec136e2dfeea6f4",
|
||||
"6cb8f9d52c56d82cac28f39ea1593e8bb2506293ac0d68376a1709b62a46df14a4ae64b2d8fab76733a1ced2d548e3f3c6fcb49d40c3d5808e449cd83d1c2aa2",
|
||||
"683fa2b2369a10162c1c1c7b24bc970ee67da220564f32203f625696c0352a0b9ad96624362d952d84463c1106a2dba7a092599884b35a0b89c8f1b6a9b5a61e",
|
||||
"aad9ad44610118b77d508aeb1bbcd1c1b7d0171397fb510a401bbc0ec34623670d86a2dc3c8f3ab5a2044df730256727545f0860ce21a1eac717dfc48f5d228e",
|
||||
"c42578de23b4c987d5e1ac4d689ed5de4b0417f9704bc6bce969fa13471585d62c2cb1212a944f397fc9ca2c3747c3beb694ec4c5be68828dda53ef43faec6c0",
|
||||
"470f00841ee8244e63ed2c7ea30e2e419897c197462ecccecf713b42a5065fff5914bc9b79affe8f6b657875e789ae213bd914cd35bd174d46e9d18bd843773d",
|
||||
"34fc4213730f47a5e9a3580f643e12945cfcb31bf206f6ad450ce528da3fa432e005d6b0ecce10dca7c5995f6aacc5150e1b009e19751e8309f8859531844374",
|
||||
"fb3c1f0f56a56f8e316fdf5d853c8c872c39635d083634c3904fc3ac07d1b578e85ff0e480e92d44ade33b62e893ee32343e79ddf6ef292e89b582d312502314",
|
||||
"c7c97fc65dd2b9e3d3d607d31598d3f84261e9919251e9c8e57bb5f829377d5f73eabbed55c6c381180f29ad02e5be797ffec7e57bdecbc50ad3d062f0993ab0",
|
||||
"a57a49cdbe67ae7d9f797bb5cc7efc2df07f4e1b15955f85dae74b76e2ecb85afb6cd9eeed8888d5ca3ec5ab65d27a7b19e578475760a045ac3c92e13a938e77",
|
||||
"c7143fce9614a17fd653aeb140726dc9c3dbb1de6cc581b2726897ec24b7a50359ad492243be66d9edd8c933b5b80e0b91bb61ea98056006516976fae8d99a35",
|
||||
"65bb58d07f937e2d3c7e65385f9c54730b704105ccdb691f6e146d4ee8f6c086f49511035110a9ad6031fdceb943e0f9613bcb276dd40f0624ef0f924f809783",
|
||||
"e540277f683b1186dd3b5b3f61433396581a35feb12002be8c6a6231fc40ffa70f08081bc58b2d94f7649543614a435faa2d62110e13dabc7b86629b63af9c24",
|
||||
"418500878c5fbcb584c432f4285e05e49f2e3e075399a0dbfcf874ebf8c03d02bf16bc6989d161c77ca0786b05053c6c709433712319192128835cf0b660595b",
|
||||
"889090dbb1944bdc9433ee5ef1010c7a4a24a8e71ecea8e12a31318ce49dcab0aca5c3802334aab2cc84b14c6b9321fe586bf3f876f19cd406eb1127fb944801",
|
||||
"53b6a28910aa92e27e536fb549cf9b9918791060898e0b9fe183577ff43b5e9c7689c745b32e412269837c31b89e6cc12bf76e13cad366b74ece48bb85fd09e9",
|
||||
"7c092080c6a80d672409d081d3d177106bcd63567785140719490950ae07ae8fcaabbaaab330cfbcf7374482c220af2eadeeb73dcbb35ed823344e144e7d4899",
|
||||
"9ccde566d2400509181111f32dde4cd63209fe59a30c114546ad2776d889a41bad8fa1bb468cb2f9d42ca9928a7770fef8e8ba4d0c812d9a1e75c3d8d2ccd75a",
|
||||
"6e293bf5d03fe43977cfe3f57ccdb3ae282a85455dca33f37f4b74f8398cc612433d755cbec412f8f82a3bd3bc4a278f7ecd0dfa9bbdc40be7a787c8f159b2df",
|
||||
"c56546fb2178456f336164c18b90deffc83ae2b5a3aca77b6884d36d2c1db39501b3e65e36c758c66e3188451fdb3515ee162c001f06c3e8cb573adf30f7a101",
|
||||
"6f82f89f299ebca2fe014b59bffe1aa84e88b1915fe256afb646fd8448af2b8891a7fab37a4ea6f9a50e6c317039d8cf878f4c8e1a0dd464f0b4d6ff1c7ea853",
|
||||
"2b8599ff9c3d6198637ad51e57d1998b0d75313fe2dd61a533c964a6dd9607c6f723e9452ce46e014b1c1d6de77ba5b88c914d1c597bf1eae13474b4290e89b2",
|
||||
"08bf346d38e1df06c8260edb1da75579275948d5c0a0aa9ed2886f8856de5417a156998758f5b17e52f101ca957a71137473dfd18d7d209c4c10d9233c93691d",
|
||||
"6df2156d773114d310b63db9ee5350d77e6bcf25b05fcd910f9b31bc42bb13fe8225ebcb2a23a62280777b6bf74e2cd0917c7640b43defe468cd1e18c943c66a",
|
||||
"7c7038bc13a91151828a5ba82b4a96040f258a4dfb1b1373f0d359168afb0517a20b28a12d3644046be66b8d08d8ae7f6a923ea1c00187c6d11dc502bac71305",
|
||||
"bcd1b30d808fb739b987cbf154bea00da9d40380b861d4c1d6377122dadd61c0e59018b71941cfb62e00dcd70aeb9abf0473e80f0a7eca6b6dea246ab229dd2b",
|
||||
"7ed4468d968530fe7ab2c33540b26d8c3bd3ed44b34fbe8c2a9d7f805b5ada0ea252eeade4fce97f89728ad85bc8bb2430b1bef2cddd32c8446e59b8e8ba3c67",
|
||||
"6d30b7c6ce8a3236c0ca2f8d728b1088ca06983a8043e621d5dcf0c537d13b08791edeb01a3cf0943ec1c890ab6e29b146a236cd46bcb9d93bf516fb67c63fe5",
|
||||
"97fe03cef31438508911bded975980a66029305dc5e3fa8ad1b4fb22fcdf5a19a733320327d8f71ccf496cb3a44a77af56e3dde73d3a5f176896cc57c9a5ad99",
|
||||
"785a9d0fbd21136dbce8fa7eafd63c9dad220052978416b31d9753eaa149097847ed9b30a65c70507eff01879149ed5cf0471d37798edc05abd56ad4a2cccb1d",
|
||||
"ad408d2abddfd37b3bf34794c1a3371d928ed7fc8d966225333584c5665817832a37c07f0dc7cb5aa874cd7d20fe8fab8eabcb9b33d2e0841f6e200960899d95",
|
||||
"97668f745b6032fc815d9579322769dccd9501a5080029b8ae826befb6742331bd9f76efeb3e2b8e81a9786b282f5068a3a2424697a77c41876b7e753f4c7767",
|
||||
"26bb985f47e7fee0cfd252d4ef96bed42b9c370c1c6a3e8c9eb04ef7f7818b833a0d1f043ebafb911dc779e02740a02a44d3a1ea45ed4ad55e686c927cafe97e",
|
||||
"5bfe2b1dcf7fe9b95088acedb575c19016c743b2e763bf5851ac407c9eda43715edfa48b4825492c5179593fff21351b76e8b7e034e4c53c79f61f29c479bd08",
|
||||
"c76509ef72f4a6f9c9c40618ed52b2084f83502232e0ac8bdaf3264368e4d0180f6854c4abf4f6509c79caafc44cf3194afc57bd077bd7b3c9bda3d4b8775816",
|
||||
"d66f2beab990e354ccb910e4e9c7ac618c7b63ef292a96b552341de78dc46d3ec8cfabc699b50af41fda39cf1b0173660923510ad67faedef5207cffe8641d20",
|
||||
"7d8f0672992b79be3a364d8e5904f4ab713bbc8ab01b4f309ad8ccf223ce1034a860dcb0b00550612cc2fa17f2969e18f22e1427d254b4a82b3a03a3eb394adf",
|
||||
"a56d6725bfb3de47c1414adf25fc8f0fc9846f6987722bc06366d5ca4e89722925ebbc881418844075397a0ca89842c7b9e9e07e1d9d183ebeb39e120b483bf7",
|
||||
"af5e03d7fe60c67e10313344434e79485a03a758d6dce985574745763c1c5c77d4fb3e6fb12230368370993bf90feed0c5d1607524562d7c09c0c210ed393d7c",
|
||||
"7a20540cc07bf72b582421fc342e82f52134b69841ec28ed189e2ea6a29dd2f82a640352d222b52f2911dc72a7dab31caadd80c6118f13c56b2a1e4373be0ea3",
|
||||
"486f02c63e5467ea1fdde7e82bfacc2c1ba5d636d9f3d08b210da3f372f706ec218cc17ff60aef703bbe0c15c38ae55d286a684f864c78211ccab4178c92adba",
|
||||
"1c7a5c1dedcd04a921788f7eb23361ca1953b04b9c7aec35d65ea3e4996db26f281278ea4ae666ad81027d98af57262cdbfa4c085f4210568c7e15eec7805114",
|
||||
"9ce3fa9a860bdbd5378fd6d7b8b671c6cb7692910ce8f9b6cb4122cbcbe6ac06ca0422cef1225935053b7d193a81b9e972eb85a1d3074f14cbb5ec9f0573892d",
|
||||
"a91187be5c371c4265c174fd4653b8ab708551f83d1fee1cc1479581bc006d6fb78fcc9a5dee1db3666f508f9780a37593ebcccf5fbed39667dc6361e921f779",
|
||||
"4625767d7b1d3d3ed2fbc674af14e0244152f2a4021fcf3311505d89bd81e2f9f9a500c3b199914db49500b3c98d03ea93286751a686a3b875daab0ccd63b44f",
|
||||
"43dfdfe1b014fed3a2acabb7f3e9a182f2aa18019d27e3e6cdcf31a15b428e91e7b08cf5e5c376fce2d8a28ff85ab0a0a1656edb4a0a91532620096d9a5a652d",
|
||||
"279e3202be3989ba3112772585177487e4fe3ee3eab49c2f7fa7fe87cfe7b80d3e0355edff6d031e6c96c795db1c6f041880ec3824defacf9263820a8e7327de",
|
||||
"ea2d066ac229d4d4b616a8bedec734325224e4b4e58f1ae6dad7e40c2da29196c3b1ea9571dacc81e87328caa0211e09027b0524aa3f4a849917b3586747ebbb",
|
||||
"49f014f5c61822c899ab5cae51be4044a4495e777deb7da9b6d8490efbb87530adf293daf079f94c33b7044ef62e2e5bb3eb11e17304f8453ee6ce24f033ddb0",
|
||||
"9233490344e5b0dc5912671b7ae54cee7730dbe1f4c7d92a4d3e3aab50571708db51dcf9c2944591db651db32d22935b86944969be77d5b5feae6c3840a8db26",
|
||||
"b6e75e6f4c7f453b7465d25b5ac8c7196902eaa953875228c8634e16e2ae1f38bc3275304335f5989eccc1e34167d4e68d7719968fba8e2fe67947c35c48e806",
|
||||
"cc14ca665af1483efbc3af80080e650d5046a3932f4f51f3fe90a0705ec25104adf07839265dc51d43401411246e474f0d5e5637af94767283d53e0617e981f4",
|
||||
"230a1c857cb2e7852e41b647e90e4585d2d881e1734dc38955356e8dd7bff39053092c6b38e236e1899525647073dddf6895d64206325e7647f275567b255909",
|
||||
"cbb65321ac436e2ffdab2936359ce49023f7dee7614ef28d173c3d27c5d1bffa51553d433f8ee3c9e49c05a2b883cce954c9a8093b80612a0cdd4732e041f995",
|
||||
"3e7e570074337275efb51315588034c3cf0dddca20b4612e0bd5b881e7e5476d319ce4fe9f19186e4c0826f44f131eb048e65be242b1172c63badb123ab0cbe8",
|
||||
"d32e9ec02d38d4e1b8249df8dcb00c5b9c68eb8922672e3505393b6a210ba56f9496e5ee0490ef387c3cdec061f06bc0382d9304cafbb8e0cd33d57029e62df2",
|
||||
"8c1512466089f05b3775c262b62d22b83854a83218130b4ec91b3ccbd293d2a54302cecaab9b100c68d1e6ddc8f07cddbdfe6fdaaaf099cc09d6b725879c6369",
|
||||
"91a7f61c97c2911e4c812ef71d780ad8fa788794561d08303fd1c1cb608a46a12563086ec5b39d471aed94fb0f6c678a43b8792932f9028d772a22768ea23a9b",
|
||||
"4f6bb222a395e8b18f6ba155477aed3f0729ac9e83e16d31a2a8bc655422b837c891c6199e6f0d75799e3b691525c581953517f252c4b9e3a27a28fbaf49644c",
|
||||
"5d06c07e7a646c413a501c3f4bb2fc38127de7509b7077c4d9b5613201c1aa02fd5f79d2745915dd57fbcb4ce08695f6efc0cb3d2d330e19b4b0e6004ea6471e",
|
||||
"b96756e57909968f14b796a5d30f4c9d671472cf82c8cfb2caca7ac7a44ca0a14c9842d00c82e337502c94d5960aca4c492ea7b0df919ddf1aada2a275bb10d4",
|
||||
"ff0a015e98db9c99f03977710aac3e658c0d896f6d71d618ba79dc6cf72ac75b7c038eb6862dede4543e145413a6368d69f5722c827ba3ef25b6ae6440d39276",
|
||||
"5b21c5fd8868367612474fa2e70e9cfa2201ffeee8fafab5797ad58fefa17c9b5b107da4a3db6320baaf2c8617d5a51df914ae88da3867c2d41f0cc14fa67928",
|
||||
}
|
||||
|
||||
var goldenKeyed = []string{
|
||||
"10ebb67700b1868efb4417987acf4690ae9d972fb7a590c2f02871799aaa4786b5e996e8f0f4eb981fc214b005f42d2ff4233499391653df7aefcbc13fc51568",
|
||||
"961f6dd1e4dd30f63901690c512e78e4b45e4742ed197c3c5e45c549fd25f2e4187b0bc9fe30492b16b0d0bc4ef9b0f34c7003fac09a5ef1532e69430234cebd",
|
||||
"da2cfbe2d8409a0f38026113884f84b50156371ae304c4430173d08a99d9fb1b983164a3770706d537f49e0c916d9f32b95cc37a95b99d857436f0232c88a965",
|
||||
"33d0825dddf7ada99b0e7e307104ad07ca9cfd9692214f1561356315e784f3e5a17e364ae9dbb14cb2036df932b77f4b292761365fb328de7afdc6d8998f5fc1",
|
||||
"beaa5a3d08f3807143cf621d95cd690514d0b49efff9c91d24b59241ec0eefa5f60196d407048bba8d2146828ebcb0488d8842fd56bb4f6df8e19c4b4daab8ac",
|
||||
"098084b51fd13deae5f4320de94a688ee07baea2800486689a8636117b46c1f4c1f6af7f74ae7c857600456a58a3af251dc4723a64cc7c0a5ab6d9cac91c20bb",
|
||||
"6044540d560853eb1c57df0077dd381094781cdb9073e5b1b3d3f6c7829e12066bbaca96d989a690de72ca3133a83652ba284a6d62942b271ffa2620c9e75b1f",
|
||||
"7a8cfe9b90f75f7ecb3acc053aaed6193112b6f6a4aeeb3f65d3de541942deb9e2228152a3c4bbbe72fc3b12629528cfbb09fe630f0474339f54abf453e2ed52",
|
||||
"380beaf6ea7cc9365e270ef0e6f3a64fb902acae51dd5512f84259ad2c91f4bc4108db73192a5bbfb0cbcf71e46c3e21aee1c5e860dc96e8eb0b7b8426e6abe9",
|
||||
"60fe3c4535e1b59d9a61ea8500bfac41a69dffb1ceadd9aca323e9a625b64da5763bad7226da02b9c8c4f1a5de140ac5a6c1124e4f718ce0b28ea47393aa6637",
|
||||
"4fe181f54ad63a2983feaaf77d1e7235c2beb17fa328b6d9505bda327df19fc37f02c4b6f0368ce23147313a8e5738b5fa2a95b29de1c7f8264eb77b69f585cd",
|
||||
"f228773ce3f3a42b5f144d63237a72d99693adb8837d0e112a8a0f8ffff2c362857ac49c11ec740d1500749dac9b1f4548108bf3155794dcc9e4082849e2b85b",
|
||||
"962452a8455cc56c8511317e3b1f3b2c37df75f588e94325fdd77070359cf63a9ae6e930936fdf8e1e08ffca440cfb72c28f06d89a2151d1c46cd5b268ef8563",
|
||||
"43d44bfa18768c59896bf7ed1765cb2d14af8c260266039099b25a603e4ddc5039d6ef3a91847d1088d401c0c7e847781a8a590d33a3c6cb4df0fab1c2f22355",
|
||||
"dcffa9d58c2a4ca2cdbb0c7aa4c4c1d45165190089f4e983bb1c2cab4aaeff1fa2b5ee516fecd780540240bf37e56c8bcca7fab980e1e61c9400d8a9a5b14ac6",
|
||||
"6fbf31b45ab0c0b8dad1c0f5f4061379912dde5aa922099a030b725c73346c524291adef89d2f6fd8dfcda6d07dad811a9314536c2915ed45da34947e83de34e",
|
||||
"a0c65bddde8adef57282b04b11e7bc8aab105b99231b750c021f4a735cb1bcfab87553bba3abb0c3e64a0b6955285185a0bd35fb8cfde557329bebb1f629ee93",
|
||||
"f99d815550558e81eca2f96718aed10d86f3f1cfb675cce06b0eff02f617c5a42c5aa760270f2679da2677c5aeb94f1142277f21c7f79f3c4f0cce4ed8ee62b1",
|
||||
"95391da8fc7b917a2044b3d6f5374e1ca072b41454d572c7356c05fd4bc1e0f40b8bb8b4a9f6bce9be2c4623c399b0dca0dab05cb7281b71a21b0ebcd9e55670",
|
||||
"04b9cd3d20d221c09ac86913d3dc63041989a9a1e694f1e639a3ba7e451840f750c2fc191d56ad61f2e7936bc0ac8e094b60caeed878c18799045402d61ceaf9",
|
||||
"ec0e0ef707e4ed6c0c66f9e089e4954b058030d2dd86398fe84059631f9ee591d9d77375355149178c0cf8f8e7c49ed2a5e4f95488a2247067c208510fadc44c",
|
||||
"9a37cce273b79c09913677510eaf7688e89b3314d3532fd2764c39de022a2945b5710d13517af8ddc0316624e73bec1ce67df15228302036f330ab0cb4d218dd",
|
||||
"4cf9bb8fb3d4de8b38b2f262d3c40f46dfe747e8fc0a414c193d9fcf753106ce47a18f172f12e8a2f1c26726545358e5ee28c9e2213a8787aafbc516d2343152",
|
||||
"64e0c63af9c808fd893137129867fd91939d53f2af04be4fa268006100069b2d69daa5c5d8ed7fddcb2a70eeecdf2b105dd46a1e3b7311728f639ab489326bc9",
|
||||
"5e9c93158d659b2def06b0c3c7565045542662d6eee8a96a89b78ade09fe8b3dcc096d4fe48815d88d8f82620156602af541955e1f6ca30dce14e254c326b88f",
|
||||
"7775dff889458dd11aef417276853e21335eb88e4dec9cfb4e9edb49820088551a2ca60339f12066101169f0dfe84b098fddb148d9da6b3d613df263889ad64b",
|
||||
"f0d2805afbb91f743951351a6d024f9353a23c7ce1fc2b051b3a8b968c233f46f50f806ecb1568ffaa0b60661e334b21dde04f8fa155ac740eeb42e20b60d764",
|
||||
"86a2af316e7d7754201b942e275364ac12ea8962ab5bd8d7fb276dc5fbffc8f9a28cae4e4867df6780d9b72524160927c855da5b6078e0b554aa91e31cb9ca1d",
|
||||
"10bdf0caa0802705e706369baf8a3f79d72c0a03a80675a7bbb00be3a45e516424d1ee88efb56f6d5777545ae6e27765c3a8f5e493fc308915638933a1dfee55",
|
||||
"b01781092b1748459e2e4ec178696627bf4ebafebba774ecf018b79a68aeb84917bf0b84bb79d17b743151144cd66b7b33a4b9e52c76c4e112050ff5385b7f0b",
|
||||
"c6dbc61dec6eaeac81e3d5f755203c8e220551534a0b2fd105a91889945a638550204f44093dd998c076205dffad703a0e5cd3c7f438a7e634cd59fededb539e",
|
||||
"eba51acffb4cea31db4b8d87e9bf7dd48fe97b0253ae67aa580f9ac4a9d941f2bea518ee286818cc9f633f2a3b9fb68e594b48cdd6d515bf1d52ba6c85a203a7",
|
||||
"86221f3ada52037b72224f105d7999231c5e5534d03da9d9c0a12acb68460cd375daf8e24386286f9668f72326dbf99ba094392437d398e95bb8161d717f8991",
|
||||
"5595e05c13a7ec4dc8f41fb70cb50a71bce17c024ff6de7af618d0cc4e9c32d9570d6d3ea45b86525491030c0d8f2b1836d5778c1ce735c17707df364d054347",
|
||||
"ce0f4f6aca89590a37fe034dd74dd5fa65eb1cbd0a41508aaddc09351a3cea6d18cb2189c54b700c009f4cbf0521c7ea01be61c5ae09cb54f27bc1b44d658c82",
|
||||
"7ee80b06a215a3bca970c77cda8761822bc103d44fa4b33f4d07dcb997e36d55298bceae12241b3fa07fa63be5576068da387b8d5859aeab701369848b176d42",
|
||||
"940a84b6a84d109aab208c024c6ce9647676ba0aaa11f86dbb7018f9fd2220a6d901a9027f9abcf935372727cbf09ebd61a2a2eeb87653e8ecad1bab85dc8327",
|
||||
"2020b78264a82d9f4151141adba8d44bf20c5ec062eee9b595a11f9e84901bf148f298e0c9f8777dcdbc7cc4670aac356cc2ad8ccb1629f16f6a76bcefbee760",
|
||||
"d1b897b0e075ba68ab572adf9d9c436663e43eb3d8e62d92fc49c9be214e6f27873fe215a65170e6bea902408a25b49506f47babd07cecf7113ec10c5dd31252",
|
||||
"b14d0c62abfa469a357177e594c10c194243ed2025ab8aa5ad2fa41ad318e0ff48cd5e60bec07b13634a711d2326e488a985f31e31153399e73088efc86a5c55",
|
||||
"4169c5cc808d2697dc2a82430dc23e3cd356dc70a94566810502b8d655b39abf9e7f902fe717e0389219859e1945df1af6ada42e4ccda55a197b7100a30c30a1",
|
||||
"258a4edb113d66c839c8b1c91f15f35ade609f11cd7f8681a4045b9fef7b0b24c82cda06a5f2067b368825e3914e53d6948ede92efd6e8387fa2e537239b5bee",
|
||||
"79d2d8696d30f30fb34657761171a11e6c3f1e64cbe7bebee159cb95bfaf812b4f411e2f26d9c421dc2c284a3342d823ec293849e42d1e46b0a4ac1e3c86abaa",
|
||||
"8b9436010dc5dee992ae38aea97f2cd63b946d94fedd2ec9671dcde3bd4ce9564d555c66c15bb2b900df72edb6b891ebcadfeff63c9ea4036a998be7973981e7",
|
||||
"c8f68e696ed28242bf997f5b3b34959508e42d613810f1e2a435c96ed2ff560c7022f361a9234b9837feee90bf47922ee0fd5f8ddf823718d86d1e16c6090071",
|
||||
"b02d3eee4860d5868b2c39ce39bfe81011290564dd678c85e8783f29302dfc1399ba95b6b53cd9ebbf400cca1db0ab67e19a325f2d115812d25d00978ad1bca4",
|
||||
"7693ea73af3ac4dad21ca0d8da85b3118a7d1c6024cfaf557699868217bc0c2f44a199bc6c0edd519798ba05bd5b1b4484346a47c2cadf6bf30b785cc88b2baf",
|
||||
"a0e5c1c0031c02e48b7f09a5e896ee9aef2f17fc9e18e997d7f6cac7ae316422c2b1e77984e5f3a73cb45deed5d3f84600105e6ee38f2d090c7d0442ea34c46d",
|
||||
"41daa6adcfdb69f1440c37b596440165c15ada596813e2e22f060fcd551f24dee8e04ba6890387886ceec4a7a0d7fc6b44506392ec3822c0d8c1acfc7d5aebe8",
|
||||
"14d4d40d5984d84c5cf7523b7798b254e275a3a8cc0a1bd06ebc0bee726856acc3cbf516ff667cda2058ad5c3412254460a82c92187041363cc77a4dc215e487",
|
||||
"d0e7a1e2b9a447fee83e2277e9ff8010c2f375ae12fa7aaa8ca5a6317868a26a367a0b69fbc1cf32a55d34eb370663016f3d2110230eba754028a56f54acf57c",
|
||||
"e771aa8db5a3e043e8178f39a0857ba04a3f18e4aa05743cf8d222b0b095825350ba422f63382a23d92e4149074e816a36c1cd28284d146267940b31f8818ea2",
|
||||
"feb4fd6f9e87a56bef398b3284d2bda5b5b0e166583a66b61e538457ff0584872c21a32962b9928ffab58de4af2edd4e15d8b35570523207ff4e2a5aa7754caa",
|
||||
"462f17bf005fb1c1b9e671779f665209ec2873e3e411f98dabf240a1d5ec3f95ce6796b6fc23fe171903b502023467dec7273ff74879b92967a2a43a5a183d33",
|
||||
"d3338193b64553dbd38d144bea71c5915bb110e2d88180dbc5db364fd6171df317fc7268831b5aef75e4342b2fad8797ba39eddcef80e6ec08159350b1ad696d",
|
||||
"e1590d585a3d39f7cb599abd479070966409a6846d4377acf4471d065d5db94129cc9be92573b05ed226be1e9b7cb0cabe87918589f80dadd4ef5ef25a93d28e",
|
||||
"f8f3726ac5a26cc80132493a6fedcb0e60760c09cfc84cad178175986819665e76842d7b9fedf76dddebf5d3f56faaad4477587af21606d396ae570d8e719af2",
|
||||
"30186055c07949948183c850e9a756cc09937e247d9d928e869e20bafc3cd9721719d34e04a0899b92c736084550186886efba2e790d8be6ebf040b209c439a4",
|
||||
"f3c4276cb863637712c241c444c5cc1e3554e0fddb174d035819dd83eb700b4ce88df3ab3841ba02085e1a99b4e17310c5341075c0458ba376c95a6818fbb3e2",
|
||||
"0aa007c4dd9d5832393040a1583c930bca7dc5e77ea53add7e2b3f7c8e231368043520d4a3ef53c969b6bbfd025946f632bd7f765d53c21003b8f983f75e2a6a",
|
||||
"08e9464720533b23a04ec24f7ae8c103145f765387d738777d3d343477fd1c58db052142cab754ea674378e18766c53542f71970171cc4f81694246b717d7564",
|
||||
"d37ff7ad297993e7ec21e0f1b4b5ae719cdc83c5db687527f27516cbffa822888a6810ee5c1ca7bfe3321119be1ab7bfa0a502671c8329494df7ad6f522d440f",
|
||||
"dd9042f6e464dcf86b1262f6accfafbd8cfd902ed3ed89abf78ffa482dbdeeb6969842394c9a1168ae3d481a017842f660002d42447c6b22f7b72f21aae021c9",
|
||||
"bd965bf31e87d70327536f2a341cebc4768eca275fa05ef98f7f1b71a0351298de006fba73fe6733ed01d75801b4a928e54231b38e38c562b2e33ea1284992fa",
|
||||
"65676d800617972fbd87e4b9514e1c67402b7a331096d3bfac22f1abb95374abc942f16e9ab0ead33b87c91968a6e509e119ff07787b3ef483e1dcdccf6e3022",
|
||||
"939fa189699c5d2c81ddd1ffc1fa207c970b6a3685bb29ce1d3e99d42f2f7442da53e95a72907314f4588399a3ff5b0a92beb3f6be2694f9f86ecf2952d5b41c",
|
||||
"c516541701863f91005f314108ceece3c643e04fc8c42fd2ff556220e616aaa6a48aeb97a84bad74782e8dff96a1a2fa949339d722edcaa32b57067041df88cc",
|
||||
"987fd6e0d6857c553eaebb3d34970a2c2f6e89a3548f492521722b80a1c21a153892346d2cba6444212d56da9a26e324dccbc0dcde85d4d2ee4399eec5a64e8f",
|
||||
"ae56deb1c2328d9c4017706bce6e99d41349053ba9d336d677c4c27d9fd50ae6aee17e853154e1f4fe7672346da2eaa31eea53fcf24a22804f11d03da6abfc2b",
|
||||
"49d6a608c9bde4491870498572ac31aac3fa40938b38a7818f72383eb040ad39532bc06571e13d767e6945ab77c0bdc3b0284253343f9f6c1244ebf2ff0df866",
|
||||
"da582ad8c5370b4469af862aa6467a2293b2b28bd80ae0e91f425ad3d47249fdf98825cc86f14028c3308c9804c78bfeeeee461444ce243687e1a50522456a1d",
|
||||
"d5266aa3331194aef852eed86d7b5b2633a0af1c735906f2e13279f14931a9fc3b0eac5ce9245273bd1aa92905abe16278ef7efd47694789a7283b77da3c70f8",
|
||||
"2962734c28252186a9a1111c732ad4de4506d4b4480916303eb7991d659ccda07a9911914bc75c418ab7a4541757ad054796e26797feaf36e9f6ad43f14b35a4",
|
||||
"e8b79ec5d06e111bdfafd71e9f5760f00ac8ac5d8bf768f9ff6f08b8f026096b1cc3a4c973333019f1e3553e77da3f98cb9f542e0a90e5f8a940cc58e59844b3",
|
||||
"dfb320c44f9d41d1efdcc015f08dd5539e526e39c87d509ae6812a969e5431bf4fa7d91ffd03b981e0d544cf72d7b1c0374f8801482e6dea2ef903877eba675e",
|
||||
"d88675118fdb55a5fb365ac2af1d217bf526ce1ee9c94b2f0090b2c58a06ca58187d7fe57c7bed9d26fca067b4110eefcd9a0a345de872abe20de368001b0745",
|
||||
"b893f2fc41f7b0dd6e2f6aa2e0370c0cff7df09e3acfcc0e920b6e6fad0ef747c40668417d342b80d2351e8c175f20897a062e9765e6c67b539b6ba8b9170545",
|
||||
"6c67ec5697accd235c59b486d7b70baeedcbd4aa64ebd4eef3c7eac189561a726250aec4d48cadcafbbe2ce3c16ce2d691a8cce06e8879556d4483ed7165c063",
|
||||
"f1aa2b044f8f0c638a3f362e677b5d891d6fd2ab0765f6ee1e4987de057ead357883d9b405b9d609eea1b869d97fb16d9b51017c553f3b93c0a1e0f1296fedcd",
|
||||
"cbaa259572d4aebfc1917acddc582b9f8dfaa928a198ca7acd0f2aa76a134a90252e6298a65b08186a350d5b7626699f8cb721a3ea5921b753ae3a2dce24ba3a",
|
||||
"fa1549c9796cd4d303dcf452c1fbd5744fd9b9b47003d920b92de34839d07ef2a29ded68f6fc9e6c45e071a2e48bd50c5084e96b657dd0404045a1ddefe282ed",
|
||||
"5cf2ac897ab444dcb5c8d87c495dbdb34e1838b6b629427caa51702ad0f9688525f13bec503a3c3a2c80a65e0b5715e8afab00ffa56ec455a49a1ad30aa24fcd",
|
||||
"9aaf80207bace17bb7ab145757d5696bde32406ef22b44292ef65d4519c3bb2ad41a59b62cc3e94b6fa96d32a7faadae28af7d35097219aa3fd8cda31e40c275",
|
||||
"af88b163402c86745cb650c2988fb95211b94b03ef290eed9662034241fd51cf398f8073e369354c43eae1052f9b63b08191caa138aa54fea889cc7024236897",
|
||||
"48fa7d64e1ceee27b9864db5ada4b53d00c9bc7626555813d3cd6730ab3cc06ff342d727905e33171bde6e8476e77fb1720861e94b73a2c538d254746285f430",
|
||||
"0e6fd97a85e904f87bfe85bbeb34f69e1f18105cf4ed4f87aec36c6e8b5f68bd2a6f3dc8a9ecb2b61db4eedb6b2ea10bf9cb0251fb0f8b344abf7f366b6de5ab",
|
||||
"06622da5787176287fdc8fed440bad187d830099c94e6d04c8e9c954cda70c8bb9e1fc4a6d0baa831b9b78ef6648681a4867a11da93ee36e5e6a37d87fc63f6f",
|
||||
"1da6772b58fabf9c61f68d412c82f182c0236d7d575ef0b58dd22458d643cd1dfc93b03871c316d8430d312995d4197f0874c99172ba004a01ee295abac24e46",
|
||||
"3cd2d9320b7b1d5fb9aab951a76023fa667be14a9124e394513918a3f44096ae4904ba0ffc150b63bc7ab1eeb9a6e257e5c8f000a70394a5afd842715de15f29",
|
||||
"04cdc14f7434e0b4be70cb41db4c779a88eaef6accebcb41f2d42fffe7f32a8e281b5c103a27021d0d08362250753cdf70292195a53a48728ceb5844c2d98bab",
|
||||
"9071b7a8a075d0095b8fb3ae5113785735ab98e2b52faf91d5b89e44aac5b5d4ebbf91223b0ff4c71905da55342e64655d6ef8c89a4768c3f93a6dc0366b5bc8",
|
||||
"ebb30240dd96c7bc8d0abe49aa4edcbb4afdc51ff9aaf720d3f9e7fbb0f9c6d6571350501769fc4ebd0b2141247ff400d4fd4be414edf37757bb90a32ac5c65a",
|
||||
"8532c58bf3c8015d9d1cbe00eef1f5082f8f3632fbe9f1ed4f9dfb1fa79e8283066d77c44c4af943d76b300364aecbd0648c8a8939bd204123f4b56260422dec",
|
||||
"fe9846d64f7c7708696f840e2d76cb4408b6595c2f81ec6a28a7f2f20cb88cfe6ac0b9e9b8244f08bd7095c350c1d0842f64fb01bb7f532dfcd47371b0aeeb79",
|
||||
"28f17ea6fb6c42092dc264257e29746321fb5bdaea9873c2a7fa9d8f53818e899e161bc77dfe8090afd82bf2266c5c1bc930a8d1547624439e662ef695f26f24",
|
||||
"ec6b7d7f030d4850acae3cb615c21dd25206d63e84d1db8d957370737ba0e98467ea0ce274c66199901eaec18a08525715f53bfdb0aacb613d342ebdceeddc3b",
|
||||
"b403d3691c03b0d3418df327d5860d34bbfcc4519bfbce36bf33b208385fadb9186bc78a76c489d89fd57e7dc75412d23bcd1dae8470ce9274754bb8585b13c5",
|
||||
"31fc79738b8772b3f55cd8178813b3b52d0db5a419d30ba9495c4b9da0219fac6df8e7c23a811551a62b827f256ecdb8124ac8a6792ccfecc3b3012722e94463",
|
||||
"bb2039ec287091bcc9642fc90049e73732e02e577e2862b32216ae9bedcd730c4c284ef3968c368b7d37584f97bd4b4dc6ef6127acfe2e6ae2509124e66c8af4",
|
||||
"f53d68d13f45edfcb9bd415e2831e938350d5380d3432278fc1c0c381fcb7c65c82dafe051d8c8b0d44e0974a0e59ec7bf7ed0459f86e96f329fc79752510fd3",
|
||||
"8d568c7984f0ecdf7640fbc483b5d8c9f86634f6f43291841b309a350ab9c1137d24066b09da9944bac54d5bb6580d836047aac74ab724b887ebf93d4b32eca9",
|
||||
"c0b65ce5a96ff774c456cac3b5f2c4cd359b4ff53ef93a3da0778be4900d1e8da1601e769e8f1b02d2a2f8c5b9fa10b44f1c186985468feeb008730283a6657d",
|
||||
"4900bba6f5fb103ece8ec96ada13a5c3c85488e05551da6b6b33d988e611ec0fe2e3c2aa48ea6ae8986a3a231b223c5d27cec2eadde91ce07981ee652862d1e4",
|
||||
"c7f5c37c7285f927f76443414d4357ff789647d7a005a5a787e03c346b57f49f21b64fa9cf4b7e45573e23049017567121a9c3d4b2b73ec5e9413577525db45a",
|
||||
"ec7096330736fdb2d64b5653e7475da746c23a4613a82687a28062d3236364284ac01720ffb406cfe265c0df626a188c9e5963ace5d3d5bb363e32c38c2190a6",
|
||||
"82e744c75f4649ec52b80771a77d475a3bc091989556960e276a5f9ead92a03f718742cdcfeaee5cb85c44af198adc43a4a428f5f0c2ddb0be36059f06d7df73",
|
||||
"2834b7a7170f1f5b68559ab78c1050ec21c919740b784a9072f6e5d69f828d70c919c5039fb148e39e2c8a52118378b064ca8d5001cd10a5478387b966715ed6",
|
||||
"16b4ada883f72f853bb7ef253efcab0c3e2161687ad61543a0d2824f91c1f81347d86be709b16996e17f2dd486927b0288ad38d13063c4a9672c39397d3789b6",
|
||||
"78d048f3a69d8b54ae0ed63a573ae350d89f7c6cf1f3688930de899afa037697629b314e5cd303aa62feea72a25bf42b304b6c6bcb27fae21c16d925e1fbdac3",
|
||||
"0f746a48749287ada77a82961f05a4da4abdb7d77b1220f836d09ec814359c0ec0239b8c7b9ff9e02f569d1b301ef67c4612d1de4f730f81c12c40cc063c5caa",
|
||||
"f0fc859d3bd195fbdc2d591e4cdac15179ec0f1dc821c11df1f0c1d26e6260aaa65b79fafacafd7d3ad61e600f250905f5878c87452897647a35b995bcadc3a3",
|
||||
"2620f687e8625f6a412460b42e2cef67634208ce10a0cbd4dff7044a41b7880077e9f8dc3b8d1216d3376a21e015b58fb279b521d83f9388c7382c8505590b9b",
|
||||
"227e3aed8d2cb10b918fcb04f9de3e6d0a57e08476d93759cd7b2ed54a1cbf0239c528fb04bbf288253e601d3bc38b21794afef90b17094a182cac557745e75f",
|
||||
"1a929901b09c25f27d6b35be7b2f1c4745131fdebca7f3e2451926720434e0db6e74fd693ad29b777dc3355c592a361c4873b01133a57c2e3b7075cbdb86f4fc",
|
||||
"5fd7968bc2fe34f220b5e3dc5af9571742d73b7d60819f2888b629072b96a9d8ab2d91b82d0a9aaba61bbd39958132fcc4257023d1eca591b3054e2dc81c8200",
|
||||
"dfcce8cf32870cc6a503eadafc87fd6f78918b9b4d0737db6810be996b5497e7e5cc80e312f61e71ff3e9624436073156403f735f56b0b01845c18f6caf772e6",
|
||||
"02f7ef3a9ce0fff960f67032b296efca3061f4934d690749f2d01c35c81c14f39a67fa350bc8a0359bf1724bffc3bca6d7c7bba4791fd522a3ad353c02ec5aa8",
|
||||
"64be5c6aba65d594844ae78bb022e5bebe127fd6b6ffa5a13703855ab63b624dcd1a363f99203f632ec386f3ea767fc992e8ed9686586aa27555a8599d5b808f",
|
||||
"f78585505c4eaa54a8b5be70a61e735e0ff97af944ddb3001e35d86c4e2199d976104b6ae31750a36a726ed285064f5981b503889fef822fcdc2898dddb7889a",
|
||||
"e4b5566033869572edfd87479a5bb73c80e8759b91232879d96b1dda36c012076ee5a2ed7ae2de63ef8406a06aea82c188031b560beafb583fb3de9e57952a7e",
|
||||
"e1b3e7ed867f6c9484a2a97f7715f25e25294e992e41f6a7c161ffc2adc6daaeb7113102d5e6090287fe6ad94ce5d6b739c6ca240b05c76fb73f25dd024bf935",
|
||||
"85fd085fdc12a080983df07bd7012b0d402a0f4043fcb2775adf0bad174f9b08d1676e476985785c0a5dcc41dbff6d95ef4d66a3fbdc4a74b82ba52da0512b74",
|
||||
"aed8fa764b0fbff821e05233d2f7b0900ec44d826f95e93c343c1bc3ba5a24374b1d616e7e7aba453a0ada5e4fab5382409e0d42ce9c2bc7fb39a99c340c20f0",
|
||||
"7ba3b2e297233522eeb343bd3ebcfd835a04007735e87f0ca300cbee6d416565162171581e4020ff4cf176450f1291ea2285cb9ebffe4c56660627685145051c",
|
||||
"de748bcf89ec88084721e16b85f30adb1a6134d664b5843569babc5bbd1a15ca9b61803c901a4fef32965a1749c9f3a4e243e173939dc5a8dc495c671ab52145",
|
||||
"aaf4d2bdf200a919706d9842dce16c98140d34bc433df320aba9bd429e549aa7a3397652a4d768277786cf993cde2338673ed2e6b66c961fefb82cd20c93338f",
|
||||
"c408218968b788bf864f0997e6bc4c3dba68b276e2125a4843296052ff93bf5767b8cdce7131f0876430c1165fec6c4f47adaa4fd8bcfacef463b5d3d0fa61a0",
|
||||
"76d2d819c92bce55fa8e092ab1bf9b9eab237a25267986cacf2b8ee14d214d730dc9a5aa2d7b596e86a1fd8fa0804c77402d2fcd45083688b218b1cdfa0dcbcb",
|
||||
"72065ee4dd91c2d8509fa1fc28a37c7fc9fa7d5b3f8ad3d0d7a25626b57b1b44788d4caf806290425f9890a3a2a35a905ab4b37acfd0da6e4517b2525c9651e4",
|
||||
"64475dfe7600d7171bea0b394e27c9b00d8e74dd1e416a79473682ad3dfdbb706631558055cfc8a40e07bd015a4540dcdea15883cbbf31412df1de1cd4152b91",
|
||||
"12cd1674a4488a5d7c2b3160d2e2c4b58371bedad793418d6f19c6ee385d70b3e06739369d4df910edb0b0a54cbff43d54544cd37ab3a06cfa0a3ddac8b66c89",
|
||||
"60756966479dedc6dd4bcff8ea7d1d4ce4d4af2e7b097e32e3763518441147cc12b3c0ee6d2ecabf1198cec92e86a3616fba4f4e872f5825330adbb4c1dee444",
|
||||
"a7803bcb71bc1d0f4383dde1e0612e04f872b715ad30815c2249cf34abb8b024915cb2fc9f4e7cc4c8cfd45be2d5a91eab0941c7d270e2da4ca4a9f7ac68663a",
|
||||
"b84ef6a7229a34a750d9a98ee2529871816b87fbe3bc45b45fa5ae82d5141540211165c3c5d7a7476ba5a4aa06d66476f0d9dc49a3f1ee72c3acabd498967414",
|
||||
"fae4b6d8efc3f8c8e64d001dabec3a21f544e82714745251b2b4b393f2f43e0da3d403c64db95a2cb6e23ebb7b9e94cdd5ddac54f07c4a61bd3cb10aa6f93b49",
|
||||
"34f7286605a122369540141ded79b8957255da2d4155abbf5a8dbb89c8eb7ede8eeef1daa46dc29d751d045dc3b1d658bb64b80ff8589eddb3824b13da235a6b",
|
||||
"3b3b48434be27b9eababba43bf6b35f14b30f6a88dc2e750c358470d6b3aa3c18e47db4017fa55106d8252f016371a00f5f8b070b74ba5f23cffc5511c9f09f0",
|
||||
"ba289ebd6562c48c3e10a8ad6ce02e73433d1e93d7c9279d4d60a7e879ee11f441a000f48ed9f7c4ed87a45136d7dccdca482109c78a51062b3ba4044ada2469",
|
||||
"022939e2386c5a37049856c850a2bb10a13dfea4212b4c732a8840a9ffa5faf54875c5448816b2785a007da8a8d2bc7d71a54e4e6571f10b600cbdb25d13ede3",
|
||||
"e6fec19d89ce8717b1a087024670fe026f6c7cbda11caef959bb2d351bf856f8055d1c0ebdaaa9d1b17886fc2c562b5e99642fc064710c0d3488a02b5ed7f6fd",
|
||||
"94c96f02a8f576aca32ba61c2b206f907285d9299b83ac175c209a8d43d53bfe683dd1d83e7549cb906c28f59ab7c46f8751366a28c39dd5fe2693c9019666c8",
|
||||
"31a0cd215ebd2cb61de5b9edc91e6195e31c59a5648d5c9f737e125b2605708f2e325ab3381c8dce1a3e958886f1ecdc60318f882cfe20a24191352e617b0f21",
|
||||
"91ab504a522dce78779f4c6c6ba2e6b6db5565c76d3e7e7c920caf7f757ef9db7c8fcf10e57f03379ea9bf75eb59895d96e149800b6aae01db778bb90afbc989",
|
||||
"d85cabc6bd5b1a01a5afd8c6734740da9fd1c1acc6db29bfc8a2e5b668b028b6b3154bfb8703fa3180251d589ad38040ceb707c4bad1b5343cb426b61eaa49c1",
|
||||
"d62efbec2ca9c1f8bd66ce8b3f6a898cb3f7566ba6568c618ad1feb2b65b76c3ce1dd20f7395372faf28427f61c9278049cf0140df434f5633048c86b81e0399",
|
||||
"7c8fdc6175439e2c3db15bafa7fb06143a6a23bc90f449e79deef73c3d492a671715c193b6fea9f036050b946069856b897e08c00768f5ee5ddcf70b7cd6d0e0",
|
||||
"58602ee7468e6bc9df21bd51b23c005f72d6cb013f0a1b48cbec5eca299299f97f09f54a9a01483eaeb315a6478bad37ba47ca1347c7c8fc9e6695592c91d723",
|
||||
"27f5b79ed256b050993d793496edf4807c1d85a7b0a67c9c4fa99860750b0ae66989670a8ffd7856d7ce411599e58c4d77b232a62bef64d15275be46a68235ff",
|
||||
"3957a976b9f1887bf004a8dca942c92d2b37ea52600f25e0c9bc5707d0279c00c6e85a839b0d2d8eb59c51d94788ebe62474a791cadf52cccf20f5070b6573fc",
|
||||
"eaa2376d55380bf772ecca9cb0aa4668c95c707162fa86d518c8ce0ca9bf7362b9f2a0adc3ff59922df921b94567e81e452f6c1a07fc817cebe99604b3505d38",
|
||||
"c1e2c78b6b2734e2480ec550434cb5d613111adcc21d475545c3b1b7e6ff12444476e5c055132e2229dc0f807044bb919b1a5662dd38a9ee65e243a3911aed1a",
|
||||
"8ab48713389dd0fcf9f965d3ce66b1e559a1f8c58741d67683cd971354f452e62d0207a65e436c5d5d8f8ee71c6abfe50e669004c302b31a7ea8311d4a916051",
|
||||
"24ce0addaa4c65038bd1b1c0f1452a0b128777aabc94a29df2fd6c7e2f85f8ab9ac7eff516b0e0a825c84a24cfe492eaad0a6308e46dd42fe8333ab971bb30ca",
|
||||
"5154f929ee03045b6b0c0004fa778edee1d139893267cc84825ad7b36c63de32798e4a166d24686561354f63b00709a1364b3c241de3febf0754045897467cd4",
|
||||
"e74e907920fd87bd5ad636dd11085e50ee70459c443e1ce5809af2bc2eba39f9e6d7128e0e3712c316da06f4705d78a4838e28121d4344a2c79c5e0db307a677",
|
||||
"bf91a22334bac20f3fd80663b3cd06c4e8802f30e6b59f90d3035cc9798a217ed5a31abbda7fa6842827bdf2a7a1c21f6fcfccbb54c6c52926f32da816269be1",
|
||||
"d9d5c74be5121b0bd742f26bffb8c89f89171f3f934913492b0903c271bbe2b3395ef259669bef43b57f7fcc3027db01823f6baee66e4f9fead4d6726c741fce",
|
||||
"50c8b8cf34cd879f80e2faab3230b0c0e1cc3e9dcadeb1b9d97ab923415dd9a1fe38addd5c11756c67990b256e95ad6d8f9fedce10bf1c90679cde0ecf1be347",
|
||||
"0a386e7cd5dd9b77a035e09fe6fee2c8ce61b5383c87ea43205059c5e4cd4f4408319bb0a82360f6a58e6c9ce3f487c446063bf813bc6ba535e17fc1826cfc91",
|
||||
"1f1459cb6b61cbac5f0efe8fc487538f42548987fcd56221cfa7beb22504769e792c45adfb1d6b3d60d7b749c8a75b0bdf14e8ea721b95dca538ca6e25711209",
|
||||
"e58b3836b7d8fedbb50ca5725c6571e74c0785e97821dab8b6298c10e4c079d4a6cdf22f0fedb55032925c16748115f01a105e77e00cee3d07924dc0d8f90659",
|
||||
"b929cc6505f020158672deda56d0db081a2ee34c00c1100029bdf8ea98034fa4bf3e8655ec697fe36f40553c5bb46801644a627d3342f4fc92b61f03290fb381",
|
||||
"72d353994b49d3e03153929a1e4d4f188ee58ab9e72ee8e512f29bc773913819ce057ddd7002c0433ee0a16114e3d156dd2c4a7e80ee53378b8670f23e33ef56",
|
||||
"c70ef9bfd775d408176737a0736d68517ce1aaad7e81a93c8c1ed967ea214f56c8a377b1763e676615b60f3988241eae6eab9685a5124929d28188f29eab06f7",
|
||||
"c230f0802679cb33822ef8b3b21bf7a9a28942092901d7dac3760300831026cf354c9232df3e084d9903130c601f63c1f4a4a4b8106e468cd443bbe5a734f45f",
|
||||
"6f43094cafb5ebf1f7a4937ec50f56a4c9da303cbb55ac1f27f1f1976cd96beda9464f0e7b9c54620b8a9fba983164b8be3578425a024f5fe199c36356b88972",
|
||||
"3745273f4c38225db2337381871a0c6aafd3af9b018c88aa02025850a5dc3a42a1a3e03e56cbf1b0876d63a441f1d2856a39b8801eb5af325201c415d65e97fe",
|
||||
"c50c44cca3ec3edaae779a7e179450ebdda2f97067c690aa6c5a4ac7c30139bb27c0df4db3220e63cb110d64f37ffe078db72653e2daacf93ae3f0a2d1a7eb2e",
|
||||
"8aef263e385cbc61e19b28914243262af5afe8726af3ce39a79c27028cf3ecd3f8d2dfd9cfc9ad91b58f6f20778fd5f02894a3d91c7d57d1e4b866a7f364b6be",
|
||||
"28696141de6e2d9bcb3235578a66166c1448d3e905a1b482d423be4bc5369bc8c74dae0acc9cc123e1d8ddce9f97917e8c019c552da32d39d2219b9abf0fa8c8",
|
||||
"2fb9eb2085830181903a9dafe3db428ee15be7662224efd643371fb25646aee716e531eca69b2bdc8233f1a8081fa43da1500302975a77f42fa592136710e9dc",
|
||||
"66f9a7143f7a3314a669bf2e24bbb35014261d639f495b6c9c1f104fe8e320aca60d4550d69d52edbd5a3cdeb4014ae65b1d87aa770b69ae5c15f4330b0b0ad8",
|
||||
"f4c4dd1d594c3565e3e25ca43dad82f62abea4835ed4cd811bcd975e46279828d44d4c62c3679f1b7f7b9dd4571d7b49557347b8c5460cbdc1bef690fb2a08c0",
|
||||
"8f1dc9649c3a84551f8f6e91cac68242a43b1f8f328ee92280257387fa7559aa6db12e4aeadc2d26099178749c6864b357f3f83b2fb3efa8d2a8db056bed6bcc",
|
||||
"3139c1a7f97afd1675d460ebbc07f2728aa150df849624511ee04b743ba0a833092f18c12dc91b4dd243f333402f59fe28abdbbbae301e7b659c7a26d5c0f979",
|
||||
"06f94a2996158a819fe34c40de3cf0379fd9fb85b3e363ba3926a0e7d960e3f4c2e0c70c7ce0ccb2a64fc29869f6e7ab12bd4d3f14fce943279027e785fb5c29",
|
||||
"c29c399ef3eee8961e87565c1ce263925fc3d0ce267d13e48dd9e732ee67b0f69fad56401b0f10fcaac119201046cca28c5b14abdea3212ae65562f7f138db3d",
|
||||
"4cec4c9df52eef05c3f6faaa9791bc7445937183224ecc37a1e58d0132d35617531d7e795f52af7b1eb9d147de1292d345fe341823f8e6bc1e5badca5c656108",
|
||||
"898bfbae93b3e18d00697eab7d9704fa36ec339d076131cefdf30edbe8d9cc81c3a80b129659b163a323bab9793d4feed92d54dae966c77529764a09be88db45",
|
||||
"ee9bd0469d3aaf4f14035be48a2c3b84d9b4b1fff1d945e1f1c1d38980a951be197b25fe22c731f20aeacc930ba9c4a1f4762227617ad350fdabb4e80273a0f4",
|
||||
"3d4d3113300581cd96acbf091c3d0f3c310138cd6979e6026cde623e2dd1b24d4a8638bed1073344783ad0649cc6305ccec04beb49f31c633088a99b65130267",
|
||||
"95c0591ad91f921ac7be6d9ce37e0663ed8011c1cfd6d0162a5572e94368bac02024485e6a39854aa46fe38e97d6c6b1947cd272d86b06bb5b2f78b9b68d559d",
|
||||
"227b79ded368153bf46c0a3ca978bfdbef31f3024a5665842468490b0ff748ae04e7832ed4c9f49de9b1706709d623e5c8c15e3caecae8d5e433430ff72f20eb",
|
||||
"5d34f3952f0105eef88ae8b64c6ce95ebfade0e02c69b08762a8712d2e4911ad3f941fc4034dc9b2e479fdbcd279b902faf5d838bb2e0c6495d372b5b7029813",
|
||||
"7f939bf8353abce49e77f14f3750af20b7b03902e1a1e7fb6aaf76d0259cd401a83190f15640e74f3e6c5a90e839c7821f6474757f75c7bf9002084ddc7a62dc",
|
||||
"062b61a2f9a33a71d7d0a06119644c70b0716a504de7e5e1be49bd7b86e7ed6817714f9f0fc313d06129597e9a2235ec8521de36f7290a90ccfc1ffa6d0aee29",
|
||||
"f29e01eeae64311eb7f1c6422f946bf7bea36379523e7b2bbaba7d1d34a22d5ea5f1c5a09d5ce1fe682cced9a4798d1a05b46cd72dff5c1b355440b2a2d476bc",
|
||||
"ec38cd3bbab3ef35d7cb6d5c914298351d8a9dc97fcee051a8a02f58e3ed6184d0b7810a5615411ab1b95209c3c810114fdeb22452084e77f3f847c6dbaafe16",
|
||||
"c2aef5e0ca43e82641565b8cb943aa8ba53550caef793b6532fafad94b816082f0113a3ea2f63608ab40437ecc0f0229cb8fa224dcf1c478a67d9b64162b92d1",
|
||||
"15f534efff7105cd1c254d074e27d5898b89313b7d366dc2d7d87113fa7d53aae13f6dba487ad8103d5e854c91fdb6e1e74b2ef6d1431769c30767dde067a35c",
|
||||
"89acbca0b169897a0a2714c2df8c95b5b79cb69390142b7d6018bb3e3076b099b79a964152a9d912b1b86412b7e372e9cecad7f25d4cbab8a317be36492a67d7",
|
||||
"e3c0739190ed849c9c962fd9dbb55e207e624fcac1eb417691515499eea8d8267b7e8f1287a63633af5011fde8c4ddf55bfdf722edf88831414f2cfaed59cb9a",
|
||||
"8d6cf87c08380d2d1506eee46fd4222d21d8c04e585fbfd08269c98f702833a156326a0724656400ee09351d57b440175e2a5de93cc5f80db6daf83576cf75fa",
|
||||
"da24bede383666d563eeed37f6319baf20d5c75d1635a6ba5ef4cfa1ac95487e96f8c08af600aab87c986ebad49fc70a58b4890b9c876e091016daf49e1d322e",
|
||||
"f9d1d1b1e87ea7ae753a029750cc1cf3d0157d41805e245c5617bb934e732f0ae3180b78e05bfe76c7c3051e3e3ac78b9b50c05142657e1e03215d6ec7bfd0fc",
|
||||
"11b7bc1668032048aa43343de476395e814bbbc223678db951a1b03a021efac948cfbe215f97fe9a72a2f6bc039e3956bfa417c1a9f10d6d7ba5d3d32ff323e5",
|
||||
"b8d9000e4fc2b066edb91afee8e7eb0f24e3a201db8b6793c0608581e628ed0bcc4e5aa6787992a4bcc44e288093e63ee83abd0bc3ec6d0934a674a4da13838a",
|
||||
"ce325e294f9b6719d6b61278276ae06a2564c03bb0b783fafe785bdf89c7d5acd83e78756d301b445699024eaeb77b54d477336ec2a4f332f2b3f88765ddb0c3",
|
||||
"29acc30e9603ae2fccf90bf97e6cc463ebe28c1b2f9b4b765e70537c25c702a29dcbfbf14c99c54345ba2b51f17b77b5f15db92bbad8fa95c471f5d070a137cc",
|
||||
"3379cbaae562a87b4c0425550ffdd6bfe1203f0d666cc7ea095be407a5dfe61ee91441cd5154b3e53b4f5fb31ad4c7a9ad5c7af4ae679aa51a54003a54ca6b2d",
|
||||
"3095a349d245708c7cf550118703d7302c27b60af5d4e67fc978f8a4e60953c7a04f92fcf41aee64321ccb707a895851552b1e37b00bc5e6b72fa5bcef9e3fff",
|
||||
"07262d738b09321f4dbccec4bb26f48cb0f0ed246ce0b31b9a6e7bc683049f1f3e5545f28ce932dd985c5ab0f43bd6de0770560af329065ed2e49d34624c2cbb",
|
||||
"b6405eca8ee3316c87061cc6ec18dba53e6c250c63ba1f3bae9e55dd3498036af08cd272aa24d713c6020d77ab2f3919af1a32f307420618ab97e73953994fb4",
|
||||
"7ee682f63148ee45f6e5315da81e5c6e557c2c34641fc509c7a5701088c38a74756168e2cd8d351e88fd1a451f360a01f5b2580f9b5a2e8cfc138f3dd59a3ffc",
|
||||
"1d263c179d6b268f6fa016f3a4f29e943891125ed8593c81256059f5a7b44af2dcb2030d175c00e62ecaf7ee96682aa07ab20a611024a28532b1c25b86657902",
|
||||
"106d132cbdb4cd2597812846e2bc1bf732fec5f0a5f65dbb39ec4e6dc64ab2ce6d24630d0f15a805c3540025d84afa98e36703c3dbee713e72dde8465bc1be7e",
|
||||
"0e79968226650667a8d862ea8da4891af56a4e3a8b6d1750e394f0dea76d640d85077bcec2cc86886e506751b4f6a5838f7f0b5fef765d9dc90dcdcbaf079f08",
|
||||
"521156a82ab0c4e566e5844d5e31ad9aaf144bbd5a464fdca34dbd5717e8ff711d3ffebbfa085d67fe996a34f6d3e4e60b1396bf4b1610c263bdbb834d560816",
|
||||
"1aba88befc55bc25efbce02db8b9933e46f57661baeabeb21cc2574d2a518a3cba5dc5a38e49713440b25f9c744e75f6b85c9d8f4681f676160f6105357b8406",
|
||||
"5a9949fcb2c473cda968ac1b5d08566dc2d816d960f57e63b898fa701cf8ebd3f59b124d95bfbbedc5f1cf0e17d5eaed0c02c50b69d8a402cabcca4433b51fd4",
|
||||
"b0cead09807c672af2eb2b0f06dde46cf5370e15a4096b1a7d7cbb36ec31c205fbefca00b7a4162fa89fb4fb3eb78d79770c23f44e7206664ce3cd931c291e5d",
|
||||
"bb6664931ec97044e45b2ae420ae1c551a8874bc937d08e969399c3964ebdba8346cdd5d09caafe4c28ba7ec788191ceca65ddd6f95f18583e040d0f30d0364d",
|
||||
"65bc770a5faa3792369803683e844b0be7ee96f29f6d6a35568006bd5590f9a4ef639b7a8061c7b0424b66b60ac34af3119905f33a9d8c3ae18382ca9b689900",
|
||||
"ea9b4dca333336aaf839a45c6eaa48b8cb4c7ddabffea4f643d6357ea6628a480a5b45f2b052c1b07d1fedca918b6f1139d80f74c24510dcbaa4be70eacc1b06",
|
||||
"e6342fb4a780ad975d0e24bce149989b91d360557e87994f6b457b895575cc02d0c15bad3ce7577f4c63927ff13f3e381ff7e72bdbe745324844a9d27e3f1c01",
|
||||
"3e209c9b33e8e461178ab46b1c64b49a07fb745f1c8bc95fbfb94c6b87c69516651b264ef980937fad41238b91ddc011a5dd777c7efd4494b4b6ecd3a9c22ac0",
|
||||
"fd6a3d5b1875d80486d6e69694a56dbb04a99a4d051f15db2689776ba1c4882e6d462a603b7015dc9f4b7450f05394303b8652cfb404a266962c41bae6e18a94",
|
||||
"951e27517e6bad9e4195fc8671dee3e7e9be69cee1422cb9fecfce0dba875f7b310b93ee3a3d558f941f635f668ff832d2c1d033c5e2f0997e4c66f147344e02",
|
||||
"8eba2f874f1ae84041903c7c4253c82292530fc8509550bfdc34c95c7e2889d5650b0ad8cb988e5c4894cb87fbfbb19612ea93ccc4c5cad17158b9763464b492",
|
||||
"16f712eaa1b7c6354719a8e7dbdfaf55e4063a4d277d947550019b38dfb564830911057d50506136e2394c3b28945cc964967d54e3000c2181626cfb9b73efd2",
|
||||
"c39639e7d5c7fb8cdd0fd3e6a52096039437122f21c78f1679cea9d78a734c56ecbeb28654b4f18e342c331f6f7229ec4b4bc281b2d80a6eb50043f31796c88c",
|
||||
"72d081af99f8a173dcc9a0ac4eb3557405639a29084b54a40172912a2f8a395129d5536f0918e902f9e8fa6000995f4168ddc5f893011be6a0dbc9b8a1a3f5bb",
|
||||
"c11aa81e5efd24d5fc27ee586cfd8847fbb0e27601ccece5ecca0198e3c7765393bb74457c7e7a27eb9170350e1fb53857177506be3e762cc0f14d8c3afe9077",
|
||||
"c28f2150b452e6c0c424bcde6f8d72007f9310fed7f2f87de0dbb64f4479d6c1441ba66f44b2accee61609177ed340128b407ecec7c64bbe50d63d22d8627727",
|
||||
"f63d88122877ec30b8c8b00d22e89000a966426112bd44166e2f525b769ccbe9b286d437a0129130dde1a86c43e04bedb594e671d98283afe64ce331de9828fd",
|
||||
"348b0532880b88a6614a8d7408c3f913357fbb60e995c60205be9139e74998aede7f4581e42f6b52698f7fa1219708c14498067fd1e09502de83a77dd281150c",
|
||||
"5133dc8bef725359dff59792d85eaf75b7e1dcd1978b01c35b1b85fcebc63388ad99a17b6346a217dc1a9622ebd122ecf6913c4d31a6b52a695b86af00d741a0",
|
||||
"2753c4c0e98ecad806e88780ec27fccd0f5c1ab547f9e4bf1659d192c23aa2cc971b58b6802580baef8adc3b776ef7086b2545c2987f348ee3719cdef258c403",
|
||||
"b1663573ce4b9d8caefc865012f3e39714b9898a5da6ce17c25a6a47931a9ddb9bbe98adaa553beed436e89578455416c2a52a525cf2862b8d1d49a2531b7391",
|
||||
"64f58bd6bfc856f5e873b2a2956ea0eda0d6db0da39c8c7fc67c9f9feefcff3072cdf9e6ea37f69a44f0c61aa0da3693c2db5b54960c0281a088151db42b11e8",
|
||||
"0764c7be28125d9065c4b98a69d60aede703547c66a12e17e1c618994132f5ef82482c1e3fe3146cc65376cc109f0138ed9a80e49f1f3c7d610d2f2432f20605",
|
||||
"f748784398a2ff03ebeb07e155e66116a839741a336e32da71ec696001f0ad1b25cd48c69cfca7265eca1dd71904a0ce748ac4124f3571076dfa7116a9cf00e9",
|
||||
"3f0dbc0186bceb6b785ba78d2a2a013c910be157bdaffae81bb6663b1a73722f7f1228795f3ecada87cf6ef0078474af73f31eca0cc200ed975b6893f761cb6d",
|
||||
"d4762cd4599876ca75b2b8fe249944dbd27ace741fdab93616cbc6e425460feb51d4e7adcc38180e7fc47c89024a7f56191adb878dfde4ead62223f5a2610efe",
|
||||
"cd36b3d5b4c91b90fcbba79513cfee1907d8645a162afd0cd4cf4192d4a5f4c892183a8eacdb2b6b6a9d9aa8c11ac1b261b380dbee24ca468f1bfd043c58eefe",
|
||||
"98593452281661a53c48a9d8cd790826c1a1ce567738053d0bee4a91a3d5bd92eefdbabebe3204f2031ca5f781bda99ef5d8ae56e5b04a9e1ecd21b0eb05d3e1",
|
||||
"771f57dd2775ccdab55921d3e8e30ccf484d61fe1c1b9c2ae819d0fb2a12fab9be70c4a7a138da84e8280435daade5bbe66af0836a154f817fb17f3397e725a3",
|
||||
"c60897c6f828e21f16fbb5f15b323f87b6c8955eabf1d38061f707f608abdd993fac3070633e286cf8339ce295dd352df4b4b40b2f29da1dd50b3a05d079e6bb",
|
||||
"8210cd2c2d3b135c2cf07fa0d1433cd771f325d075c6469d9c7f1ba0943cd4ab09808cabf4acb9ce5bb88b498929b4b847f681ad2c490d042db2aec94214b06b",
|
||||
"1d4edfffd8fd80f7e4107840fa3aa31e32598491e4af7013c197a65b7f36dd3ac4b478456111cd4309d9243510782fa31b7c4c95fa951520d020eb7e5c36e4ef",
|
||||
"af8e6e91fab46ce4873e1a50a8ef448cc29121f7f74deef34a71ef89cc00d9274bc6c2454bbb3230d8b2ec94c62b1dec85f3593bfa30ea6f7a44d7c09465a253",
|
||||
"29fd384ed4906f2d13aa9fe7af905990938bed807f1832454a372ab412eea1f5625a1fcc9ac8343b7c67c5aba6e0b1cc4644654913692c6b39eb9187ceacd3ec",
|
||||
"a268c7885d9874a51c44dffed8ea53e94f78456e0b2ed99ff5a3924760813826d960a15edbedbb5de5226ba4b074e71b05c55b9756bb79e55c02754c2c7b6c8a",
|
||||
"0cf8545488d56a86817cd7ecb10f7116b7ea530a45b6ea497b6c72c997e09e3d0da8698f46bb006fc977c2cd3d1177463ac9057fdd1662c85d0c126443c10473",
|
||||
"b39614268fdd8781515e2cfebf89b4d5402bab10c226e6344e6b9ae000fb0d6c79cb2f3ec80e80eaeb1980d2f8698916bd2e9f747236655116649cd3ca23a837",
|
||||
"74bef092fc6f1e5dba3663a3fb003b2a5ba257496536d99f62b9d73f8f9eb3ce9ff3eec709eb883655ec9eb896b9128f2afc89cf7d1ab58a72f4a3bf034d2b4a",
|
||||
"3a988d38d75611f3ef38b8774980b33e573b6c57bee0469ba5eed9b44f29945e7347967fba2c162e1c3be7f310f2f75ee2381e7bfd6b3f0baea8d95dfb1dafb1",
|
||||
"58aedfce6f67ddc85a28c992f1c0bd0969f041e66f1ee88020a125cbfcfebcd61709c9c4eba192c15e69f020d462486019fa8dea0cd7a42921a19d2fe546d43d",
|
||||
"9347bd291473e6b4e368437b8e561e065f649a6d8ada479ad09b1999a8f26b91cf6120fd3bfe014e83f23acfa4c0ad7b3712b2c3c0733270663112ccd9285cd9",
|
||||
"b32163e7c5dbb5f51fdc11d2eac875efbbcb7e7699090a7e7ff8a8d50795af5d74d9ff98543ef8cdf89ac13d0485278756e0ef00c817745661e1d59fe38e7537",
|
||||
"1085d78307b1c4b008c57a2e7e5b234658a0a82e4ff1e4aaac72b312fda0fe27d233bc5b10e9cc17fdc7697b540c7d95eb215a19a1a0e20e1abfa126efd568c7",
|
||||
"4e5c734c7dde011d83eac2b7347b373594f92d7091b9ca34cb9c6f39bdf5a8d2f134379e16d822f6522170ccf2ddd55c84b9e6c64fc927ac4cf8dfb2a17701f2",
|
||||
"695d83bd990a1117b3d0ce06cc888027d12a054c2677fd82f0d4fbfc93575523e7991a5e35a3752e9b70ce62992e268a877744cdd435f5f130869c9a2074b338",
|
||||
"a6213743568e3b3158b9184301f3690847554c68457cb40fc9a4b8cfd8d4a118c301a07737aeda0f929c68913c5f51c80394f53bff1c3e83b2e40ca97eba9e15",
|
||||
"d444bfa2362a96df213d070e33fa841f51334e4e76866b8139e8af3bb3398be2dfaddcbc56b9146de9f68118dc5829e74b0c28d7711907b121f9161cb92b69a9",
|
||||
"142709d62e28fcccd0af97fad0f8465b971e82201dc51070faa0372aa43e92484be1c1e73ba10906d5d1853db6a4106e0a7bf9800d373d6dee2d46d62ef2a461",
|
||||
}
|
||||
1420
vendor/github.com/wg/ecies/vendor/github.com/dchest/blake2b/block.go
generated
vendored
Normal file
1420
vendor/github.com/wg/ecies/vendor/github.com/dchest/blake2b/block.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
3
vendor/github.com/wg/ecies/vendor/golang.org/x/crypto/AUTHORS
generated
vendored
Normal file
3
vendor/github.com/wg/ecies/vendor/golang.org/x/crypto/AUTHORS
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
# This source code refers to The Go Authors for copyright purposes.
|
||||
# The master list of authors is in the main Go distribution,
|
||||
# visible at http://tip.golang.org/AUTHORS.
|
||||
3
vendor/github.com/wg/ecies/vendor/golang.org/x/crypto/CONTRIBUTORS
generated
vendored
Normal file
3
vendor/github.com/wg/ecies/vendor/golang.org/x/crypto/CONTRIBUTORS
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
# This source code was written by the Go contributors.
|
||||
# The master list of contributors is in the main Go distribution,
|
||||
# visible at http://tip.golang.org/CONTRIBUTORS.
|
||||
27
vendor/github.com/wg/ecies/vendor/golang.org/x/crypto/LICENSE
generated
vendored
Normal file
27
vendor/github.com/wg/ecies/vendor/golang.org/x/crypto/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
Copyright (c) 2009 The Go Authors. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Google Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
22
vendor/github.com/wg/ecies/vendor/golang.org/x/crypto/PATENTS
generated
vendored
Normal file
22
vendor/github.com/wg/ecies/vendor/golang.org/x/crypto/PATENTS
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
Additional IP Rights Grant (Patents)
|
||||
|
||||
"This implementation" means the copyrightable works distributed by
|
||||
Google as part of the Go project.
|
||||
|
||||
Google hereby grants to You a perpetual, worldwide, non-exclusive,
|
||||
no-charge, royalty-free, irrevocable (except as stated in this section)
|
||||
patent license to make, have made, use, offer to sell, sell, import,
|
||||
transfer and otherwise run, modify and propagate the contents of this
|
||||
implementation of Go, where such license applies only to those patent
|
||||
claims, both currently owned or controlled by Google and acquired in
|
||||
the future, licensable by Google that are necessarily infringed by this
|
||||
implementation of Go. This grant does not include claims that would be
|
||||
infringed only as a consequence of further modification of this
|
||||
implementation. If you or your agent or exclusive licensee institute or
|
||||
order or agree to the institution of patent litigation against any
|
||||
entity (including a cross-claim or counterclaim in a lawsuit) alleging
|
||||
that this implementation of Go or any code incorporated within this
|
||||
implementation of Go constitutes direct or contributory patent
|
||||
infringement, or inducement of patent infringement, then any patent
|
||||
rights granted to you under this License for this implementation of Go
|
||||
shall terminate as of the date such litigation is filed.
|
||||
3
vendor/github.com/wg/ecies/vendor/golang.org/x/crypto/README
generated
vendored
Normal file
3
vendor/github.com/wg/ecies/vendor/golang.org/x/crypto/README
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
This repository holds supplementary Go cryptography libraries.
|
||||
|
||||
To submit changes to this repository, see http://golang.org/doc/contribute.html.
|
||||
20
vendor/github.com/wg/ecies/vendor/golang.org/x/crypto/curve25519/const_amd64.s
generated
vendored
Normal file
20
vendor/github.com/wg/ecies/vendor/golang.org/x/crypto/curve25519/const_amd64.s
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
// Copyright 2012 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.
|
||||
|
||||
// This code was translated into a form compatible with 6a from the public
|
||||
// domain sources in SUPERCOP: http://bench.cr.yp.to/supercop.html
|
||||
|
||||
// +build amd64,!gccgo,!appengine
|
||||
|
||||
DATA ·REDMASK51(SB)/8, $0x0007FFFFFFFFFFFF
|
||||
GLOBL ·REDMASK51(SB), 8, $8
|
||||
|
||||
DATA ·_121666_213(SB)/8, $996687872
|
||||
GLOBL ·_121666_213(SB), 8, $8
|
||||
|
||||
DATA ·_2P0(SB)/8, $0xFFFFFFFFFFFDA
|
||||
GLOBL ·_2P0(SB), 8, $8
|
||||
|
||||
DATA ·_2P1234(SB)/8, $0xFFFFFFFFFFFFE
|
||||
GLOBL ·_2P1234(SB), 8, $8
|
||||
88
vendor/github.com/wg/ecies/vendor/golang.org/x/crypto/curve25519/cswap_amd64.s
generated
vendored
Normal file
88
vendor/github.com/wg/ecies/vendor/golang.org/x/crypto/curve25519/cswap_amd64.s
generated
vendored
Normal file
@@ -0,0 +1,88 @@
|
||||
// Copyright 2012 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.
|
||||
|
||||
// This code was translated into a form compatible with 6a from the public
|
||||
// domain sources in SUPERCOP: http://bench.cr.yp.to/supercop.html
|
||||
|
||||
// +build amd64,!gccgo,!appengine
|
||||
|
||||
// func cswap(inout *[5]uint64, v uint64)
|
||||
TEXT ·cswap(SB),7,$0
|
||||
MOVQ inout+0(FP),DI
|
||||
MOVQ v+8(FP),SI
|
||||
|
||||
CMPQ SI,$1
|
||||
MOVQ 0(DI),SI
|
||||
MOVQ 80(DI),DX
|
||||
MOVQ 8(DI),CX
|
||||
MOVQ 88(DI),R8
|
||||
MOVQ SI,R9
|
||||
CMOVQEQ DX,SI
|
||||
CMOVQEQ R9,DX
|
||||
MOVQ CX,R9
|
||||
CMOVQEQ R8,CX
|
||||
CMOVQEQ R9,R8
|
||||
MOVQ SI,0(DI)
|
||||
MOVQ DX,80(DI)
|
||||
MOVQ CX,8(DI)
|
||||
MOVQ R8,88(DI)
|
||||
MOVQ 16(DI),SI
|
||||
MOVQ 96(DI),DX
|
||||
MOVQ 24(DI),CX
|
||||
MOVQ 104(DI),R8
|
||||
MOVQ SI,R9
|
||||
CMOVQEQ DX,SI
|
||||
CMOVQEQ R9,DX
|
||||
MOVQ CX,R9
|
||||
CMOVQEQ R8,CX
|
||||
CMOVQEQ R9,R8
|
||||
MOVQ SI,16(DI)
|
||||
MOVQ DX,96(DI)
|
||||
MOVQ CX,24(DI)
|
||||
MOVQ R8,104(DI)
|
||||
MOVQ 32(DI),SI
|
||||
MOVQ 112(DI),DX
|
||||
MOVQ 40(DI),CX
|
||||
MOVQ 120(DI),R8
|
||||
MOVQ SI,R9
|
||||
CMOVQEQ DX,SI
|
||||
CMOVQEQ R9,DX
|
||||
MOVQ CX,R9
|
||||
CMOVQEQ R8,CX
|
||||
CMOVQEQ R9,R8
|
||||
MOVQ SI,32(DI)
|
||||
MOVQ DX,112(DI)
|
||||
MOVQ CX,40(DI)
|
||||
MOVQ R8,120(DI)
|
||||
MOVQ 48(DI),SI
|
||||
MOVQ 128(DI),DX
|
||||
MOVQ 56(DI),CX
|
||||
MOVQ 136(DI),R8
|
||||
MOVQ SI,R9
|
||||
CMOVQEQ DX,SI
|
||||
CMOVQEQ R9,DX
|
||||
MOVQ CX,R9
|
||||
CMOVQEQ R8,CX
|
||||
CMOVQEQ R9,R8
|
||||
MOVQ SI,48(DI)
|
||||
MOVQ DX,128(DI)
|
||||
MOVQ CX,56(DI)
|
||||
MOVQ R8,136(DI)
|
||||
MOVQ 64(DI),SI
|
||||
MOVQ 144(DI),DX
|
||||
MOVQ 72(DI),CX
|
||||
MOVQ 152(DI),R8
|
||||
MOVQ SI,R9
|
||||
CMOVQEQ DX,SI
|
||||
CMOVQEQ R9,DX
|
||||
MOVQ CX,R9
|
||||
CMOVQEQ R8,CX
|
||||
CMOVQEQ R9,R8
|
||||
MOVQ SI,64(DI)
|
||||
MOVQ DX,144(DI)
|
||||
MOVQ CX,72(DI)
|
||||
MOVQ R8,152(DI)
|
||||
MOVQ DI,AX
|
||||
MOVQ SI,DX
|
||||
RET
|
||||
841
vendor/github.com/wg/ecies/vendor/golang.org/x/crypto/curve25519/curve25519.go
generated
vendored
Normal file
841
vendor/github.com/wg/ecies/vendor/golang.org/x/crypto/curve25519/curve25519.go
generated
vendored
Normal file
@@ -0,0 +1,841 @@
|
||||
// Copyright 2013 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.
|
||||
|
||||
// We have a implementation in amd64 assembly so this code is only run on
|
||||
// non-amd64 platforms. The amd64 assembly does not support gccgo.
|
||||
// +build !amd64 gccgo appengine
|
||||
|
||||
package curve25519
|
||||
|
||||
// This code is a port of the public domain, "ref10" implementation of
|
||||
// curve25519 from SUPERCOP 20130419 by D. J. Bernstein.
|
||||
|
||||
// fieldElement represents an element of the field GF(2^255 - 19). An element
|
||||
// t, entries t[0]...t[9], represents the integer t[0]+2^26 t[1]+2^51 t[2]+2^77
|
||||
// t[3]+2^102 t[4]+...+2^230 t[9]. Bounds on each t[i] vary depending on
|
||||
// context.
|
||||
type fieldElement [10]int32
|
||||
|
||||
func feZero(fe *fieldElement) {
|
||||
for i := range fe {
|
||||
fe[i] = 0
|
||||
}
|
||||
}
|
||||
|
||||
func feOne(fe *fieldElement) {
|
||||
feZero(fe)
|
||||
fe[0] = 1
|
||||
}
|
||||
|
||||
func feAdd(dst, a, b *fieldElement) {
|
||||
for i := range dst {
|
||||
dst[i] = a[i] + b[i]
|
||||
}
|
||||
}
|
||||
|
||||
func feSub(dst, a, b *fieldElement) {
|
||||
for i := range dst {
|
||||
dst[i] = a[i] - b[i]
|
||||
}
|
||||
}
|
||||
|
||||
func feCopy(dst, src *fieldElement) {
|
||||
for i := range dst {
|
||||
dst[i] = src[i]
|
||||
}
|
||||
}
|
||||
|
||||
// feCSwap replaces (f,g) with (g,f) if b == 1; replaces (f,g) with (f,g) if b == 0.
|
||||
//
|
||||
// Preconditions: b in {0,1}.
|
||||
func feCSwap(f, g *fieldElement, b int32) {
|
||||
var x fieldElement
|
||||
b = -b
|
||||
for i := range x {
|
||||
x[i] = b & (f[i] ^ g[i])
|
||||
}
|
||||
|
||||
for i := range f {
|
||||
f[i] ^= x[i]
|
||||
}
|
||||
for i := range g {
|
||||
g[i] ^= x[i]
|
||||
}
|
||||
}
|
||||
|
||||
// load3 reads a 24-bit, little-endian value from in.
|
||||
func load3(in []byte) int64 {
|
||||
var r int64
|
||||
r = int64(in[0])
|
||||
r |= int64(in[1]) << 8
|
||||
r |= int64(in[2]) << 16
|
||||
return r
|
||||
}
|
||||
|
||||
// load4 reads a 32-bit, little-endian value from in.
|
||||
func load4(in []byte) int64 {
|
||||
var r int64
|
||||
r = int64(in[0])
|
||||
r |= int64(in[1]) << 8
|
||||
r |= int64(in[2]) << 16
|
||||
r |= int64(in[3]) << 24
|
||||
return r
|
||||
}
|
||||
|
||||
func feFromBytes(dst *fieldElement, src *[32]byte) {
|
||||
h0 := load4(src[:])
|
||||
h1 := load3(src[4:]) << 6
|
||||
h2 := load3(src[7:]) << 5
|
||||
h3 := load3(src[10:]) << 3
|
||||
h4 := load3(src[13:]) << 2
|
||||
h5 := load4(src[16:])
|
||||
h6 := load3(src[20:]) << 7
|
||||
h7 := load3(src[23:]) << 5
|
||||
h8 := load3(src[26:]) << 4
|
||||
h9 := load3(src[29:]) << 2
|
||||
|
||||
var carry [10]int64
|
||||
carry[9] = (h9 + 1<<24) >> 25
|
||||
h0 += carry[9] * 19
|
||||
h9 -= carry[9] << 25
|
||||
carry[1] = (h1 + 1<<24) >> 25
|
||||
h2 += carry[1]
|
||||
h1 -= carry[1] << 25
|
||||
carry[3] = (h3 + 1<<24) >> 25
|
||||
h4 += carry[3]
|
||||
h3 -= carry[3] << 25
|
||||
carry[5] = (h5 + 1<<24) >> 25
|
||||
h6 += carry[5]
|
||||
h5 -= carry[5] << 25
|
||||
carry[7] = (h7 + 1<<24) >> 25
|
||||
h8 += carry[7]
|
||||
h7 -= carry[7] << 25
|
||||
|
||||
carry[0] = (h0 + 1<<25) >> 26
|
||||
h1 += carry[0]
|
||||
h0 -= carry[0] << 26
|
||||
carry[2] = (h2 + 1<<25) >> 26
|
||||
h3 += carry[2]
|
||||
h2 -= carry[2] << 26
|
||||
carry[4] = (h4 + 1<<25) >> 26
|
||||
h5 += carry[4]
|
||||
h4 -= carry[4] << 26
|
||||
carry[6] = (h6 + 1<<25) >> 26
|
||||
h7 += carry[6]
|
||||
h6 -= carry[6] << 26
|
||||
carry[8] = (h8 + 1<<25) >> 26
|
||||
h9 += carry[8]
|
||||
h8 -= carry[8] << 26
|
||||
|
||||
dst[0] = int32(h0)
|
||||
dst[1] = int32(h1)
|
||||
dst[2] = int32(h2)
|
||||
dst[3] = int32(h3)
|
||||
dst[4] = int32(h4)
|
||||
dst[5] = int32(h5)
|
||||
dst[6] = int32(h6)
|
||||
dst[7] = int32(h7)
|
||||
dst[8] = int32(h8)
|
||||
dst[9] = int32(h9)
|
||||
}
|
||||
|
||||
// feToBytes marshals h to s.
|
||||
// Preconditions:
|
||||
// |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
|
||||
//
|
||||
// Write p=2^255-19; q=floor(h/p).
|
||||
// Basic claim: q = floor(2^(-255)(h + 19 2^(-25)h9 + 2^(-1))).
|
||||
//
|
||||
// Proof:
|
||||
// Have |h|<=p so |q|<=1 so |19^2 2^(-255) q|<1/4.
|
||||
// Also have |h-2^230 h9|<2^230 so |19 2^(-255)(h-2^230 h9)|<1/4.
|
||||
//
|
||||
// Write y=2^(-1)-19^2 2^(-255)q-19 2^(-255)(h-2^230 h9).
|
||||
// Then 0<y<1.
|
||||
//
|
||||
// Write r=h-pq.
|
||||
// Have 0<=r<=p-1=2^255-20.
|
||||
// Thus 0<=r+19(2^-255)r<r+19(2^-255)2^255<=2^255-1.
|
||||
//
|
||||
// Write x=r+19(2^-255)r+y.
|
||||
// Then 0<x<2^255 so floor(2^(-255)x) = 0 so floor(q+2^(-255)x) = q.
|
||||
//
|
||||
// Have q+2^(-255)x = 2^(-255)(h + 19 2^(-25) h9 + 2^(-1))
|
||||
// so floor(2^(-255)(h + 19 2^(-25) h9 + 2^(-1))) = q.
|
||||
func feToBytes(s *[32]byte, h *fieldElement) {
|
||||
var carry [10]int32
|
||||
|
||||
q := (19*h[9] + (1 << 24)) >> 25
|
||||
q = (h[0] + q) >> 26
|
||||
q = (h[1] + q) >> 25
|
||||
q = (h[2] + q) >> 26
|
||||
q = (h[3] + q) >> 25
|
||||
q = (h[4] + q) >> 26
|
||||
q = (h[5] + q) >> 25
|
||||
q = (h[6] + q) >> 26
|
||||
q = (h[7] + q) >> 25
|
||||
q = (h[8] + q) >> 26
|
||||
q = (h[9] + q) >> 25
|
||||
|
||||
// Goal: Output h-(2^255-19)q, which is between 0 and 2^255-20.
|
||||
h[0] += 19 * q
|
||||
// Goal: Output h-2^255 q, which is between 0 and 2^255-20.
|
||||
|
||||
carry[0] = h[0] >> 26
|
||||
h[1] += carry[0]
|
||||
h[0] -= carry[0] << 26
|
||||
carry[1] = h[1] >> 25
|
||||
h[2] += carry[1]
|
||||
h[1] -= carry[1] << 25
|
||||
carry[2] = h[2] >> 26
|
||||
h[3] += carry[2]
|
||||
h[2] -= carry[2] << 26
|
||||
carry[3] = h[3] >> 25
|
||||
h[4] += carry[3]
|
||||
h[3] -= carry[3] << 25
|
||||
carry[4] = h[4] >> 26
|
||||
h[5] += carry[4]
|
||||
h[4] -= carry[4] << 26
|
||||
carry[5] = h[5] >> 25
|
||||
h[6] += carry[5]
|
||||
h[5] -= carry[5] << 25
|
||||
carry[6] = h[6] >> 26
|
||||
h[7] += carry[6]
|
||||
h[6] -= carry[6] << 26
|
||||
carry[7] = h[7] >> 25
|
||||
h[8] += carry[7]
|
||||
h[7] -= carry[7] << 25
|
||||
carry[8] = h[8] >> 26
|
||||
h[9] += carry[8]
|
||||
h[8] -= carry[8] << 26
|
||||
carry[9] = h[9] >> 25
|
||||
h[9] -= carry[9] << 25
|
||||
// h10 = carry9
|
||||
|
||||
// Goal: Output h[0]+...+2^255 h10-2^255 q, which is between 0 and 2^255-20.
|
||||
// Have h[0]+...+2^230 h[9] between 0 and 2^255-1;
|
||||
// evidently 2^255 h10-2^255 q = 0.
|
||||
// Goal: Output h[0]+...+2^230 h[9].
|
||||
|
||||
s[0] = byte(h[0] >> 0)
|
||||
s[1] = byte(h[0] >> 8)
|
||||
s[2] = byte(h[0] >> 16)
|
||||
s[3] = byte((h[0] >> 24) | (h[1] << 2))
|
||||
s[4] = byte(h[1] >> 6)
|
||||
s[5] = byte(h[1] >> 14)
|
||||
s[6] = byte((h[1] >> 22) | (h[2] << 3))
|
||||
s[7] = byte(h[2] >> 5)
|
||||
s[8] = byte(h[2] >> 13)
|
||||
s[9] = byte((h[2] >> 21) | (h[3] << 5))
|
||||
s[10] = byte(h[3] >> 3)
|
||||
s[11] = byte(h[3] >> 11)
|
||||
s[12] = byte((h[3] >> 19) | (h[4] << 6))
|
||||
s[13] = byte(h[4] >> 2)
|
||||
s[14] = byte(h[4] >> 10)
|
||||
s[15] = byte(h[4] >> 18)
|
||||
s[16] = byte(h[5] >> 0)
|
||||
s[17] = byte(h[5] >> 8)
|
||||
s[18] = byte(h[5] >> 16)
|
||||
s[19] = byte((h[5] >> 24) | (h[6] << 1))
|
||||
s[20] = byte(h[6] >> 7)
|
||||
s[21] = byte(h[6] >> 15)
|
||||
s[22] = byte((h[6] >> 23) | (h[7] << 3))
|
||||
s[23] = byte(h[7] >> 5)
|
||||
s[24] = byte(h[7] >> 13)
|
||||
s[25] = byte((h[7] >> 21) | (h[8] << 4))
|
||||
s[26] = byte(h[8] >> 4)
|
||||
s[27] = byte(h[8] >> 12)
|
||||
s[28] = byte((h[8] >> 20) | (h[9] << 6))
|
||||
s[29] = byte(h[9] >> 2)
|
||||
s[30] = byte(h[9] >> 10)
|
||||
s[31] = byte(h[9] >> 18)
|
||||
}
|
||||
|
||||
// feMul calculates h = f * g
|
||||
// Can overlap h with f or g.
|
||||
//
|
||||
// Preconditions:
|
||||
// |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
|
||||
// |g| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
|
||||
//
|
||||
// Postconditions:
|
||||
// |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
|
||||
//
|
||||
// Notes on implementation strategy:
|
||||
//
|
||||
// Using schoolbook multiplication.
|
||||
// Karatsuba would save a little in some cost models.
|
||||
//
|
||||
// Most multiplications by 2 and 19 are 32-bit precomputations;
|
||||
// cheaper than 64-bit postcomputations.
|
||||
//
|
||||
// There is one remaining multiplication by 19 in the carry chain;
|
||||
// one *19 precomputation can be merged into this,
|
||||
// but the resulting data flow is considerably less clean.
|
||||
//
|
||||
// There are 12 carries below.
|
||||
// 10 of them are 2-way parallelizable and vectorizable.
|
||||
// Can get away with 11 carries, but then data flow is much deeper.
|
||||
//
|
||||
// With tighter constraints on inputs can squeeze carries into int32.
|
||||
func feMul(h, f, g *fieldElement) {
|
||||
f0 := f[0]
|
||||
f1 := f[1]
|
||||
f2 := f[2]
|
||||
f3 := f[3]
|
||||
f4 := f[4]
|
||||
f5 := f[5]
|
||||
f6 := f[6]
|
||||
f7 := f[7]
|
||||
f8 := f[8]
|
||||
f9 := f[9]
|
||||
g0 := g[0]
|
||||
g1 := g[1]
|
||||
g2 := g[2]
|
||||
g3 := g[3]
|
||||
g4 := g[4]
|
||||
g5 := g[5]
|
||||
g6 := g[6]
|
||||
g7 := g[7]
|
||||
g8 := g[8]
|
||||
g9 := g[9]
|
||||
g1_19 := 19 * g1 // 1.4*2^29
|
||||
g2_19 := 19 * g2 // 1.4*2^30; still ok
|
||||
g3_19 := 19 * g3
|
||||
g4_19 := 19 * g4
|
||||
g5_19 := 19 * g5
|
||||
g6_19 := 19 * g6
|
||||
g7_19 := 19 * g7
|
||||
g8_19 := 19 * g8
|
||||
g9_19 := 19 * g9
|
||||
f1_2 := 2 * f1
|
||||
f3_2 := 2 * f3
|
||||
f5_2 := 2 * f5
|
||||
f7_2 := 2 * f7
|
||||
f9_2 := 2 * f9
|
||||
f0g0 := int64(f0) * int64(g0)
|
||||
f0g1 := int64(f0) * int64(g1)
|
||||
f0g2 := int64(f0) * int64(g2)
|
||||
f0g3 := int64(f0) * int64(g3)
|
||||
f0g4 := int64(f0) * int64(g4)
|
||||
f0g5 := int64(f0) * int64(g5)
|
||||
f0g6 := int64(f0) * int64(g6)
|
||||
f0g7 := int64(f0) * int64(g7)
|
||||
f0g8 := int64(f0) * int64(g8)
|
||||
f0g9 := int64(f0) * int64(g9)
|
||||
f1g0 := int64(f1) * int64(g0)
|
||||
f1g1_2 := int64(f1_2) * int64(g1)
|
||||
f1g2 := int64(f1) * int64(g2)
|
||||
f1g3_2 := int64(f1_2) * int64(g3)
|
||||
f1g4 := int64(f1) * int64(g4)
|
||||
f1g5_2 := int64(f1_2) * int64(g5)
|
||||
f1g6 := int64(f1) * int64(g6)
|
||||
f1g7_2 := int64(f1_2) * int64(g7)
|
||||
f1g8 := int64(f1) * int64(g8)
|
||||
f1g9_38 := int64(f1_2) * int64(g9_19)
|
||||
f2g0 := int64(f2) * int64(g0)
|
||||
f2g1 := int64(f2) * int64(g1)
|
||||
f2g2 := int64(f2) * int64(g2)
|
||||
f2g3 := int64(f2) * int64(g3)
|
||||
f2g4 := int64(f2) * int64(g4)
|
||||
f2g5 := int64(f2) * int64(g5)
|
||||
f2g6 := int64(f2) * int64(g6)
|
||||
f2g7 := int64(f2) * int64(g7)
|
||||
f2g8_19 := int64(f2) * int64(g8_19)
|
||||
f2g9_19 := int64(f2) * int64(g9_19)
|
||||
f3g0 := int64(f3) * int64(g0)
|
||||
f3g1_2 := int64(f3_2) * int64(g1)
|
||||
f3g2 := int64(f3) * int64(g2)
|
||||
f3g3_2 := int64(f3_2) * int64(g3)
|
||||
f3g4 := int64(f3) * int64(g4)
|
||||
f3g5_2 := int64(f3_2) * int64(g5)
|
||||
f3g6 := int64(f3) * int64(g6)
|
||||
f3g7_38 := int64(f3_2) * int64(g7_19)
|
||||
f3g8_19 := int64(f3) * int64(g8_19)
|
||||
f3g9_38 := int64(f3_2) * int64(g9_19)
|
||||
f4g0 := int64(f4) * int64(g0)
|
||||
f4g1 := int64(f4) * int64(g1)
|
||||
f4g2 := int64(f4) * int64(g2)
|
||||
f4g3 := int64(f4) * int64(g3)
|
||||
f4g4 := int64(f4) * int64(g4)
|
||||
f4g5 := int64(f4) * int64(g5)
|
||||
f4g6_19 := int64(f4) * int64(g6_19)
|
||||
f4g7_19 := int64(f4) * int64(g7_19)
|
||||
f4g8_19 := int64(f4) * int64(g8_19)
|
||||
f4g9_19 := int64(f4) * int64(g9_19)
|
||||
f5g0 := int64(f5) * int64(g0)
|
||||
f5g1_2 := int64(f5_2) * int64(g1)
|
||||
f5g2 := int64(f5) * int64(g2)
|
||||
f5g3_2 := int64(f5_2) * int64(g3)
|
||||
f5g4 := int64(f5) * int64(g4)
|
||||
f5g5_38 := int64(f5_2) * int64(g5_19)
|
||||
f5g6_19 := int64(f5) * int64(g6_19)
|
||||
f5g7_38 := int64(f5_2) * int64(g7_19)
|
||||
f5g8_19 := int64(f5) * int64(g8_19)
|
||||
f5g9_38 := int64(f5_2) * int64(g9_19)
|
||||
f6g0 := int64(f6) * int64(g0)
|
||||
f6g1 := int64(f6) * int64(g1)
|
||||
f6g2 := int64(f6) * int64(g2)
|
||||
f6g3 := int64(f6) * int64(g3)
|
||||
f6g4_19 := int64(f6) * int64(g4_19)
|
||||
f6g5_19 := int64(f6) * int64(g5_19)
|
||||
f6g6_19 := int64(f6) * int64(g6_19)
|
||||
f6g7_19 := int64(f6) * int64(g7_19)
|
||||
f6g8_19 := int64(f6) * int64(g8_19)
|
||||
f6g9_19 := int64(f6) * int64(g9_19)
|
||||
f7g0 := int64(f7) * int64(g0)
|
||||
f7g1_2 := int64(f7_2) * int64(g1)
|
||||
f7g2 := int64(f7) * int64(g2)
|
||||
f7g3_38 := int64(f7_2) * int64(g3_19)
|
||||
f7g4_19 := int64(f7) * int64(g4_19)
|
||||
f7g5_38 := int64(f7_2) * int64(g5_19)
|
||||
f7g6_19 := int64(f7) * int64(g6_19)
|
||||
f7g7_38 := int64(f7_2) * int64(g7_19)
|
||||
f7g8_19 := int64(f7) * int64(g8_19)
|
||||
f7g9_38 := int64(f7_2) * int64(g9_19)
|
||||
f8g0 := int64(f8) * int64(g0)
|
||||
f8g1 := int64(f8) * int64(g1)
|
||||
f8g2_19 := int64(f8) * int64(g2_19)
|
||||
f8g3_19 := int64(f8) * int64(g3_19)
|
||||
f8g4_19 := int64(f8) * int64(g4_19)
|
||||
f8g5_19 := int64(f8) * int64(g5_19)
|
||||
f8g6_19 := int64(f8) * int64(g6_19)
|
||||
f8g7_19 := int64(f8) * int64(g7_19)
|
||||
f8g8_19 := int64(f8) * int64(g8_19)
|
||||
f8g9_19 := int64(f8) * int64(g9_19)
|
||||
f9g0 := int64(f9) * int64(g0)
|
||||
f9g1_38 := int64(f9_2) * int64(g1_19)
|
||||
f9g2_19 := int64(f9) * int64(g2_19)
|
||||
f9g3_38 := int64(f9_2) * int64(g3_19)
|
||||
f9g4_19 := int64(f9) * int64(g4_19)
|
||||
f9g5_38 := int64(f9_2) * int64(g5_19)
|
||||
f9g6_19 := int64(f9) * int64(g6_19)
|
||||
f9g7_38 := int64(f9_2) * int64(g7_19)
|
||||
f9g8_19 := int64(f9) * int64(g8_19)
|
||||
f9g9_38 := int64(f9_2) * int64(g9_19)
|
||||
h0 := f0g0 + f1g9_38 + f2g8_19 + f3g7_38 + f4g6_19 + f5g5_38 + f6g4_19 + f7g3_38 + f8g2_19 + f9g1_38
|
||||
h1 := f0g1 + f1g0 + f2g9_19 + f3g8_19 + f4g7_19 + f5g6_19 + f6g5_19 + f7g4_19 + f8g3_19 + f9g2_19
|
||||
h2 := f0g2 + f1g1_2 + f2g0 + f3g9_38 + f4g8_19 + f5g7_38 + f6g6_19 + f7g5_38 + f8g4_19 + f9g3_38
|
||||
h3 := f0g3 + f1g2 + f2g1 + f3g0 + f4g9_19 + f5g8_19 + f6g7_19 + f7g6_19 + f8g5_19 + f9g4_19
|
||||
h4 := f0g4 + f1g3_2 + f2g2 + f3g1_2 + f4g0 + f5g9_38 + f6g8_19 + f7g7_38 + f8g6_19 + f9g5_38
|
||||
h5 := f0g5 + f1g4 + f2g3 + f3g2 + f4g1 + f5g0 + f6g9_19 + f7g8_19 + f8g7_19 + f9g6_19
|
||||
h6 := f0g6 + f1g5_2 + f2g4 + f3g3_2 + f4g2 + f5g1_2 + f6g0 + f7g9_38 + f8g8_19 + f9g7_38
|
||||
h7 := f0g7 + f1g6 + f2g5 + f3g4 + f4g3 + f5g2 + f6g1 + f7g0 + f8g9_19 + f9g8_19
|
||||
h8 := f0g8 + f1g7_2 + f2g6 + f3g5_2 + f4g4 + f5g3_2 + f6g2 + f7g1_2 + f8g0 + f9g9_38
|
||||
h9 := f0g9 + f1g8 + f2g7 + f3g6 + f4g5 + f5g4 + f6g3 + f7g2 + f8g1 + f9g0
|
||||
var carry [10]int64
|
||||
|
||||
// |h0| <= (1.1*1.1*2^52*(1+19+19+19+19)+1.1*1.1*2^50*(38+38+38+38+38))
|
||||
// i.e. |h0| <= 1.2*2^59; narrower ranges for h2, h4, h6, h8
|
||||
// |h1| <= (1.1*1.1*2^51*(1+1+19+19+19+19+19+19+19+19))
|
||||
// i.e. |h1| <= 1.5*2^58; narrower ranges for h3, h5, h7, h9
|
||||
|
||||
carry[0] = (h0 + (1 << 25)) >> 26
|
||||
h1 += carry[0]
|
||||
h0 -= carry[0] << 26
|
||||
carry[4] = (h4 + (1 << 25)) >> 26
|
||||
h5 += carry[4]
|
||||
h4 -= carry[4] << 26
|
||||
// |h0| <= 2^25
|
||||
// |h4| <= 2^25
|
||||
// |h1| <= 1.51*2^58
|
||||
// |h5| <= 1.51*2^58
|
||||
|
||||
carry[1] = (h1 + (1 << 24)) >> 25
|
||||
h2 += carry[1]
|
||||
h1 -= carry[1] << 25
|
||||
carry[5] = (h5 + (1 << 24)) >> 25
|
||||
h6 += carry[5]
|
||||
h5 -= carry[5] << 25
|
||||
// |h1| <= 2^24; from now on fits into int32
|
||||
// |h5| <= 2^24; from now on fits into int32
|
||||
// |h2| <= 1.21*2^59
|
||||
// |h6| <= 1.21*2^59
|
||||
|
||||
carry[2] = (h2 + (1 << 25)) >> 26
|
||||
h3 += carry[2]
|
||||
h2 -= carry[2] << 26
|
||||
carry[6] = (h6 + (1 << 25)) >> 26
|
||||
h7 += carry[6]
|
||||
h6 -= carry[6] << 26
|
||||
// |h2| <= 2^25; from now on fits into int32 unchanged
|
||||
// |h6| <= 2^25; from now on fits into int32 unchanged
|
||||
// |h3| <= 1.51*2^58
|
||||
// |h7| <= 1.51*2^58
|
||||
|
||||
carry[3] = (h3 + (1 << 24)) >> 25
|
||||
h4 += carry[3]
|
||||
h3 -= carry[3] << 25
|
||||
carry[7] = (h7 + (1 << 24)) >> 25
|
||||
h8 += carry[7]
|
||||
h7 -= carry[7] << 25
|
||||
// |h3| <= 2^24; from now on fits into int32 unchanged
|
||||
// |h7| <= 2^24; from now on fits into int32 unchanged
|
||||
// |h4| <= 1.52*2^33
|
||||
// |h8| <= 1.52*2^33
|
||||
|
||||
carry[4] = (h4 + (1 << 25)) >> 26
|
||||
h5 += carry[4]
|
||||
h4 -= carry[4] << 26
|
||||
carry[8] = (h8 + (1 << 25)) >> 26
|
||||
h9 += carry[8]
|
||||
h8 -= carry[8] << 26
|
||||
// |h4| <= 2^25; from now on fits into int32 unchanged
|
||||
// |h8| <= 2^25; from now on fits into int32 unchanged
|
||||
// |h5| <= 1.01*2^24
|
||||
// |h9| <= 1.51*2^58
|
||||
|
||||
carry[9] = (h9 + (1 << 24)) >> 25
|
||||
h0 += carry[9] * 19
|
||||
h9 -= carry[9] << 25
|
||||
// |h9| <= 2^24; from now on fits into int32 unchanged
|
||||
// |h0| <= 1.8*2^37
|
||||
|
||||
carry[0] = (h0 + (1 << 25)) >> 26
|
||||
h1 += carry[0]
|
||||
h0 -= carry[0] << 26
|
||||
// |h0| <= 2^25; from now on fits into int32 unchanged
|
||||
// |h1| <= 1.01*2^24
|
||||
|
||||
h[0] = int32(h0)
|
||||
h[1] = int32(h1)
|
||||
h[2] = int32(h2)
|
||||
h[3] = int32(h3)
|
||||
h[4] = int32(h4)
|
||||
h[5] = int32(h5)
|
||||
h[6] = int32(h6)
|
||||
h[7] = int32(h7)
|
||||
h[8] = int32(h8)
|
||||
h[9] = int32(h9)
|
||||
}
|
||||
|
||||
// feSquare calculates h = f*f. Can overlap h with f.
|
||||
//
|
||||
// Preconditions:
|
||||
// |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
|
||||
//
|
||||
// Postconditions:
|
||||
// |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
|
||||
func feSquare(h, f *fieldElement) {
|
||||
f0 := f[0]
|
||||
f1 := f[1]
|
||||
f2 := f[2]
|
||||
f3 := f[3]
|
||||
f4 := f[4]
|
||||
f5 := f[5]
|
||||
f6 := f[6]
|
||||
f7 := f[7]
|
||||
f8 := f[8]
|
||||
f9 := f[9]
|
||||
f0_2 := 2 * f0
|
||||
f1_2 := 2 * f1
|
||||
f2_2 := 2 * f2
|
||||
f3_2 := 2 * f3
|
||||
f4_2 := 2 * f4
|
||||
f5_2 := 2 * f5
|
||||
f6_2 := 2 * f6
|
||||
f7_2 := 2 * f7
|
||||
f5_38 := 38 * f5 // 1.31*2^30
|
||||
f6_19 := 19 * f6 // 1.31*2^30
|
||||
f7_38 := 38 * f7 // 1.31*2^30
|
||||
f8_19 := 19 * f8 // 1.31*2^30
|
||||
f9_38 := 38 * f9 // 1.31*2^30
|
||||
f0f0 := int64(f0) * int64(f0)
|
||||
f0f1_2 := int64(f0_2) * int64(f1)
|
||||
f0f2_2 := int64(f0_2) * int64(f2)
|
||||
f0f3_2 := int64(f0_2) * int64(f3)
|
||||
f0f4_2 := int64(f0_2) * int64(f4)
|
||||
f0f5_2 := int64(f0_2) * int64(f5)
|
||||
f0f6_2 := int64(f0_2) * int64(f6)
|
||||
f0f7_2 := int64(f0_2) * int64(f7)
|
||||
f0f8_2 := int64(f0_2) * int64(f8)
|
||||
f0f9_2 := int64(f0_2) * int64(f9)
|
||||
f1f1_2 := int64(f1_2) * int64(f1)
|
||||
f1f2_2 := int64(f1_2) * int64(f2)
|
||||
f1f3_4 := int64(f1_2) * int64(f3_2)
|
||||
f1f4_2 := int64(f1_2) * int64(f4)
|
||||
f1f5_4 := int64(f1_2) * int64(f5_2)
|
||||
f1f6_2 := int64(f1_2) * int64(f6)
|
||||
f1f7_4 := int64(f1_2) * int64(f7_2)
|
||||
f1f8_2 := int64(f1_2) * int64(f8)
|
||||
f1f9_76 := int64(f1_2) * int64(f9_38)
|
||||
f2f2 := int64(f2) * int64(f2)
|
||||
f2f3_2 := int64(f2_2) * int64(f3)
|
||||
f2f4_2 := int64(f2_2) * int64(f4)
|
||||
f2f5_2 := int64(f2_2) * int64(f5)
|
||||
f2f6_2 := int64(f2_2) * int64(f6)
|
||||
f2f7_2 := int64(f2_2) * int64(f7)
|
||||
f2f8_38 := int64(f2_2) * int64(f8_19)
|
||||
f2f9_38 := int64(f2) * int64(f9_38)
|
||||
f3f3_2 := int64(f3_2) * int64(f3)
|
||||
f3f4_2 := int64(f3_2) * int64(f4)
|
||||
f3f5_4 := int64(f3_2) * int64(f5_2)
|
||||
f3f6_2 := int64(f3_2) * int64(f6)
|
||||
f3f7_76 := int64(f3_2) * int64(f7_38)
|
||||
f3f8_38 := int64(f3_2) * int64(f8_19)
|
||||
f3f9_76 := int64(f3_2) * int64(f9_38)
|
||||
f4f4 := int64(f4) * int64(f4)
|
||||
f4f5_2 := int64(f4_2) * int64(f5)
|
||||
f4f6_38 := int64(f4_2) * int64(f6_19)
|
||||
f4f7_38 := int64(f4) * int64(f7_38)
|
||||
f4f8_38 := int64(f4_2) * int64(f8_19)
|
||||
f4f9_38 := int64(f4) * int64(f9_38)
|
||||
f5f5_38 := int64(f5) * int64(f5_38)
|
||||
f5f6_38 := int64(f5_2) * int64(f6_19)
|
||||
f5f7_76 := int64(f5_2) * int64(f7_38)
|
||||
f5f8_38 := int64(f5_2) * int64(f8_19)
|
||||
f5f9_76 := int64(f5_2) * int64(f9_38)
|
||||
f6f6_19 := int64(f6) * int64(f6_19)
|
||||
f6f7_38 := int64(f6) * int64(f7_38)
|
||||
f6f8_38 := int64(f6_2) * int64(f8_19)
|
||||
f6f9_38 := int64(f6) * int64(f9_38)
|
||||
f7f7_38 := int64(f7) * int64(f7_38)
|
||||
f7f8_38 := int64(f7_2) * int64(f8_19)
|
||||
f7f9_76 := int64(f7_2) * int64(f9_38)
|
||||
f8f8_19 := int64(f8) * int64(f8_19)
|
||||
f8f9_38 := int64(f8) * int64(f9_38)
|
||||
f9f9_38 := int64(f9) * int64(f9_38)
|
||||
h0 := f0f0 + f1f9_76 + f2f8_38 + f3f7_76 + f4f6_38 + f5f5_38
|
||||
h1 := f0f1_2 + f2f9_38 + f3f8_38 + f4f7_38 + f5f6_38
|
||||
h2 := f0f2_2 + f1f1_2 + f3f9_76 + f4f8_38 + f5f7_76 + f6f6_19
|
||||
h3 := f0f3_2 + f1f2_2 + f4f9_38 + f5f8_38 + f6f7_38
|
||||
h4 := f0f4_2 + f1f3_4 + f2f2 + f5f9_76 + f6f8_38 + f7f7_38
|
||||
h5 := f0f5_2 + f1f4_2 + f2f3_2 + f6f9_38 + f7f8_38
|
||||
h6 := f0f6_2 + f1f5_4 + f2f4_2 + f3f3_2 + f7f9_76 + f8f8_19
|
||||
h7 := f0f7_2 + f1f6_2 + f2f5_2 + f3f4_2 + f8f9_38
|
||||
h8 := f0f8_2 + f1f7_4 + f2f6_2 + f3f5_4 + f4f4 + f9f9_38
|
||||
h9 := f0f9_2 + f1f8_2 + f2f7_2 + f3f6_2 + f4f5_2
|
||||
var carry [10]int64
|
||||
|
||||
carry[0] = (h0 + (1 << 25)) >> 26
|
||||
h1 += carry[0]
|
||||
h0 -= carry[0] << 26
|
||||
carry[4] = (h4 + (1 << 25)) >> 26
|
||||
h5 += carry[4]
|
||||
h4 -= carry[4] << 26
|
||||
|
||||
carry[1] = (h1 + (1 << 24)) >> 25
|
||||
h2 += carry[1]
|
||||
h1 -= carry[1] << 25
|
||||
carry[5] = (h5 + (1 << 24)) >> 25
|
||||
h6 += carry[5]
|
||||
h5 -= carry[5] << 25
|
||||
|
||||
carry[2] = (h2 + (1 << 25)) >> 26
|
||||
h3 += carry[2]
|
||||
h2 -= carry[2] << 26
|
||||
carry[6] = (h6 + (1 << 25)) >> 26
|
||||
h7 += carry[6]
|
||||
h6 -= carry[6] << 26
|
||||
|
||||
carry[3] = (h3 + (1 << 24)) >> 25
|
||||
h4 += carry[3]
|
||||
h3 -= carry[3] << 25
|
||||
carry[7] = (h7 + (1 << 24)) >> 25
|
||||
h8 += carry[7]
|
||||
h7 -= carry[7] << 25
|
||||
|
||||
carry[4] = (h4 + (1 << 25)) >> 26
|
||||
h5 += carry[4]
|
||||
h4 -= carry[4] << 26
|
||||
carry[8] = (h8 + (1 << 25)) >> 26
|
||||
h9 += carry[8]
|
||||
h8 -= carry[8] << 26
|
||||
|
||||
carry[9] = (h9 + (1 << 24)) >> 25
|
||||
h0 += carry[9] * 19
|
||||
h9 -= carry[9] << 25
|
||||
|
||||
carry[0] = (h0 + (1 << 25)) >> 26
|
||||
h1 += carry[0]
|
||||
h0 -= carry[0] << 26
|
||||
|
||||
h[0] = int32(h0)
|
||||
h[1] = int32(h1)
|
||||
h[2] = int32(h2)
|
||||
h[3] = int32(h3)
|
||||
h[4] = int32(h4)
|
||||
h[5] = int32(h5)
|
||||
h[6] = int32(h6)
|
||||
h[7] = int32(h7)
|
||||
h[8] = int32(h8)
|
||||
h[9] = int32(h9)
|
||||
}
|
||||
|
||||
// feMul121666 calculates h = f * 121666. Can overlap h with f.
|
||||
//
|
||||
// Preconditions:
|
||||
// |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
|
||||
//
|
||||
// Postconditions:
|
||||
// |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
|
||||
func feMul121666(h, f *fieldElement) {
|
||||
h0 := int64(f[0]) * 121666
|
||||
h1 := int64(f[1]) * 121666
|
||||
h2 := int64(f[2]) * 121666
|
||||
h3 := int64(f[3]) * 121666
|
||||
h4 := int64(f[4]) * 121666
|
||||
h5 := int64(f[5]) * 121666
|
||||
h6 := int64(f[6]) * 121666
|
||||
h7 := int64(f[7]) * 121666
|
||||
h8 := int64(f[8]) * 121666
|
||||
h9 := int64(f[9]) * 121666
|
||||
var carry [10]int64
|
||||
|
||||
carry[9] = (h9 + (1 << 24)) >> 25
|
||||
h0 += carry[9] * 19
|
||||
h9 -= carry[9] << 25
|
||||
carry[1] = (h1 + (1 << 24)) >> 25
|
||||
h2 += carry[1]
|
||||
h1 -= carry[1] << 25
|
||||
carry[3] = (h3 + (1 << 24)) >> 25
|
||||
h4 += carry[3]
|
||||
h3 -= carry[3] << 25
|
||||
carry[5] = (h5 + (1 << 24)) >> 25
|
||||
h6 += carry[5]
|
||||
h5 -= carry[5] << 25
|
||||
carry[7] = (h7 + (1 << 24)) >> 25
|
||||
h8 += carry[7]
|
||||
h7 -= carry[7] << 25
|
||||
|
||||
carry[0] = (h0 + (1 << 25)) >> 26
|
||||
h1 += carry[0]
|
||||
h0 -= carry[0] << 26
|
||||
carry[2] = (h2 + (1 << 25)) >> 26
|
||||
h3 += carry[2]
|
||||
h2 -= carry[2] << 26
|
||||
carry[4] = (h4 + (1 << 25)) >> 26
|
||||
h5 += carry[4]
|
||||
h4 -= carry[4] << 26
|
||||
carry[6] = (h6 + (1 << 25)) >> 26
|
||||
h7 += carry[6]
|
||||
h6 -= carry[6] << 26
|
||||
carry[8] = (h8 + (1 << 25)) >> 26
|
||||
h9 += carry[8]
|
||||
h8 -= carry[8] << 26
|
||||
|
||||
h[0] = int32(h0)
|
||||
h[1] = int32(h1)
|
||||
h[2] = int32(h2)
|
||||
h[3] = int32(h3)
|
||||
h[4] = int32(h4)
|
||||
h[5] = int32(h5)
|
||||
h[6] = int32(h6)
|
||||
h[7] = int32(h7)
|
||||
h[8] = int32(h8)
|
||||
h[9] = int32(h9)
|
||||
}
|
||||
|
||||
// feInvert sets out = z^-1.
|
||||
func feInvert(out, z *fieldElement) {
|
||||
var t0, t1, t2, t3 fieldElement
|
||||
var i int
|
||||
|
||||
feSquare(&t0, z)
|
||||
for i = 1; i < 1; i++ {
|
||||
feSquare(&t0, &t0)
|
||||
}
|
||||
feSquare(&t1, &t0)
|
||||
for i = 1; i < 2; i++ {
|
||||
feSquare(&t1, &t1)
|
||||
}
|
||||
feMul(&t1, z, &t1)
|
||||
feMul(&t0, &t0, &t1)
|
||||
feSquare(&t2, &t0)
|
||||
for i = 1; i < 1; i++ {
|
||||
feSquare(&t2, &t2)
|
||||
}
|
||||
feMul(&t1, &t1, &t2)
|
||||
feSquare(&t2, &t1)
|
||||
for i = 1; i < 5; i++ {
|
||||
feSquare(&t2, &t2)
|
||||
}
|
||||
feMul(&t1, &t2, &t1)
|
||||
feSquare(&t2, &t1)
|
||||
for i = 1; i < 10; i++ {
|
||||
feSquare(&t2, &t2)
|
||||
}
|
||||
feMul(&t2, &t2, &t1)
|
||||
feSquare(&t3, &t2)
|
||||
for i = 1; i < 20; i++ {
|
||||
feSquare(&t3, &t3)
|
||||
}
|
||||
feMul(&t2, &t3, &t2)
|
||||
feSquare(&t2, &t2)
|
||||
for i = 1; i < 10; i++ {
|
||||
feSquare(&t2, &t2)
|
||||
}
|
||||
feMul(&t1, &t2, &t1)
|
||||
feSquare(&t2, &t1)
|
||||
for i = 1; i < 50; i++ {
|
||||
feSquare(&t2, &t2)
|
||||
}
|
||||
feMul(&t2, &t2, &t1)
|
||||
feSquare(&t3, &t2)
|
||||
for i = 1; i < 100; i++ {
|
||||
feSquare(&t3, &t3)
|
||||
}
|
||||
feMul(&t2, &t3, &t2)
|
||||
feSquare(&t2, &t2)
|
||||
for i = 1; i < 50; i++ {
|
||||
feSquare(&t2, &t2)
|
||||
}
|
||||
feMul(&t1, &t2, &t1)
|
||||
feSquare(&t1, &t1)
|
||||
for i = 1; i < 5; i++ {
|
||||
feSquare(&t1, &t1)
|
||||
}
|
||||
feMul(out, &t1, &t0)
|
||||
}
|
||||
|
||||
func scalarMult(out, in, base *[32]byte) {
|
||||
var e [32]byte
|
||||
|
||||
copy(e[:], in[:])
|
||||
e[0] &= 248
|
||||
e[31] &= 127
|
||||
e[31] |= 64
|
||||
|
||||
var x1, x2, z2, x3, z3, tmp0, tmp1 fieldElement
|
||||
feFromBytes(&x1, base)
|
||||
feOne(&x2)
|
||||
feCopy(&x3, &x1)
|
||||
feOne(&z3)
|
||||
|
||||
swap := int32(0)
|
||||
for pos := 254; pos >= 0; pos-- {
|
||||
b := e[pos/8] >> uint(pos&7)
|
||||
b &= 1
|
||||
swap ^= int32(b)
|
||||
feCSwap(&x2, &x3, swap)
|
||||
feCSwap(&z2, &z3, swap)
|
||||
swap = int32(b)
|
||||
|
||||
feSub(&tmp0, &x3, &z3)
|
||||
feSub(&tmp1, &x2, &z2)
|
||||
feAdd(&x2, &x2, &z2)
|
||||
feAdd(&z2, &x3, &z3)
|
||||
feMul(&z3, &tmp0, &x2)
|
||||
feMul(&z2, &z2, &tmp1)
|
||||
feSquare(&tmp0, &tmp1)
|
||||
feSquare(&tmp1, &x2)
|
||||
feAdd(&x3, &z3, &z2)
|
||||
feSub(&z2, &z3, &z2)
|
||||
feMul(&x2, &tmp1, &tmp0)
|
||||
feSub(&tmp1, &tmp1, &tmp0)
|
||||
feSquare(&z2, &z2)
|
||||
feMul121666(&z3, &tmp1)
|
||||
feSquare(&x3, &x3)
|
||||
feAdd(&tmp0, &tmp0, &z3)
|
||||
feMul(&z3, &x1, &z2)
|
||||
feMul(&z2, &tmp1, &tmp0)
|
||||
}
|
||||
|
||||
feCSwap(&x2, &x3, swap)
|
||||
feCSwap(&z2, &z3, swap)
|
||||
|
||||
feInvert(&z2, &z2)
|
||||
feMul(&x2, &x2, &z2)
|
||||
feToBytes(out, &x2)
|
||||
}
|
||||
29
vendor/github.com/wg/ecies/vendor/golang.org/x/crypto/curve25519/curve25519_test.go
generated
vendored
Normal file
29
vendor/github.com/wg/ecies/vendor/golang.org/x/crypto/curve25519/curve25519_test.go
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
// Copyright 2012 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 curve25519
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
const expectedHex = "89161fde887b2b53de549af483940106ecc114d6982daa98256de23bdf77661a"
|
||||
|
||||
func TestBaseScalarMult(t *testing.T) {
|
||||
var a, b [32]byte
|
||||
in := &a
|
||||
out := &b
|
||||
a[0] = 1
|
||||
|
||||
for i := 0; i < 200; i++ {
|
||||
ScalarBaseMult(out, in)
|
||||
in, out = out, in
|
||||
}
|
||||
|
||||
result := fmt.Sprintf("%x", in[:])
|
||||
if result != expectedHex {
|
||||
t.Errorf("incorrect result: got %s, want %s", result, expectedHex)
|
||||
}
|
||||
}
|
||||
23
vendor/github.com/wg/ecies/vendor/golang.org/x/crypto/curve25519/doc.go
generated
vendored
Normal file
23
vendor/github.com/wg/ecies/vendor/golang.org/x/crypto/curve25519/doc.go
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
// Copyright 2012 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 curve25519 provides an implementation of scalar multiplication on
|
||||
// the elliptic curve known as curve25519. See http://cr.yp.to/ecdh.html
|
||||
package curve25519 // import "golang.org/x/crypto/curve25519"
|
||||
|
||||
// basePoint is the x coordinate of the generator of the curve.
|
||||
var basePoint = [32]byte{9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
|
||||
// ScalarMult sets dst to the product in*base where dst and base are the x
|
||||
// coordinates of group points and all values are in little-endian form.
|
||||
func ScalarMult(dst, in, base *[32]byte) {
|
||||
scalarMult(dst, in, base)
|
||||
}
|
||||
|
||||
// ScalarBaseMult sets dst to the product in*base where dst and base are the x
|
||||
// coordinates of group points, base is the standard generator and all values
|
||||
// are in little-endian form.
|
||||
func ScalarBaseMult(dst, in *[32]byte) {
|
||||
ScalarMult(dst, in, &basePoint)
|
||||
}
|
||||
94
vendor/github.com/wg/ecies/vendor/golang.org/x/crypto/curve25519/freeze_amd64.s
generated
vendored
Normal file
94
vendor/github.com/wg/ecies/vendor/golang.org/x/crypto/curve25519/freeze_amd64.s
generated
vendored
Normal file
@@ -0,0 +1,94 @@
|
||||
// Copyright 2012 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.
|
||||
|
||||
// This code was translated into a form compatible with 6a from the public
|
||||
// domain sources in SUPERCOP: http://bench.cr.yp.to/supercop.html
|
||||
|
||||
// +build amd64,!gccgo,!appengine
|
||||
|
||||
// func freeze(inout *[5]uint64)
|
||||
TEXT ·freeze(SB),7,$96-8
|
||||
MOVQ inout+0(FP), DI
|
||||
|
||||
MOVQ SP,R11
|
||||
MOVQ $31,CX
|
||||
NOTQ CX
|
||||
ANDQ CX,SP
|
||||
ADDQ $32,SP
|
||||
|
||||
MOVQ R11,0(SP)
|
||||
MOVQ R12,8(SP)
|
||||
MOVQ R13,16(SP)
|
||||
MOVQ R14,24(SP)
|
||||
MOVQ R15,32(SP)
|
||||
MOVQ BX,40(SP)
|
||||
MOVQ BP,48(SP)
|
||||
MOVQ 0(DI),SI
|
||||
MOVQ 8(DI),DX
|
||||
MOVQ 16(DI),CX
|
||||
MOVQ 24(DI),R8
|
||||
MOVQ 32(DI),R9
|
||||
MOVQ ·REDMASK51(SB),AX
|
||||
MOVQ AX,R10
|
||||
SUBQ $18,R10
|
||||
MOVQ $3,R11
|
||||
REDUCELOOP:
|
||||
MOVQ SI,R12
|
||||
SHRQ $51,R12
|
||||
ANDQ AX,SI
|
||||
ADDQ R12,DX
|
||||
MOVQ DX,R12
|
||||
SHRQ $51,R12
|
||||
ANDQ AX,DX
|
||||
ADDQ R12,CX
|
||||
MOVQ CX,R12
|
||||
SHRQ $51,R12
|
||||
ANDQ AX,CX
|
||||
ADDQ R12,R8
|
||||
MOVQ R8,R12
|
||||
SHRQ $51,R12
|
||||
ANDQ AX,R8
|
||||
ADDQ R12,R9
|
||||
MOVQ R9,R12
|
||||
SHRQ $51,R12
|
||||
ANDQ AX,R9
|
||||
IMUL3Q $19,R12,R12
|
||||
ADDQ R12,SI
|
||||
SUBQ $1,R11
|
||||
JA REDUCELOOP
|
||||
MOVQ $1,R12
|
||||
CMPQ R10,SI
|
||||
CMOVQLT R11,R12
|
||||
CMPQ AX,DX
|
||||
CMOVQNE R11,R12
|
||||
CMPQ AX,CX
|
||||
CMOVQNE R11,R12
|
||||
CMPQ AX,R8
|
||||
CMOVQNE R11,R12
|
||||
CMPQ AX,R9
|
||||
CMOVQNE R11,R12
|
||||
NEGQ R12
|
||||
ANDQ R12,AX
|
||||
ANDQ R12,R10
|
||||
SUBQ R10,SI
|
||||
SUBQ AX,DX
|
||||
SUBQ AX,CX
|
||||
SUBQ AX,R8
|
||||
SUBQ AX,R9
|
||||
MOVQ SI,0(DI)
|
||||
MOVQ DX,8(DI)
|
||||
MOVQ CX,16(DI)
|
||||
MOVQ R8,24(DI)
|
||||
MOVQ R9,32(DI)
|
||||
MOVQ 0(SP),R11
|
||||
MOVQ 8(SP),R12
|
||||
MOVQ 16(SP),R13
|
||||
MOVQ 24(SP),R14
|
||||
MOVQ 32(SP),R15
|
||||
MOVQ 40(SP),BX
|
||||
MOVQ 48(SP),BP
|
||||
MOVQ R11,SP
|
||||
MOVQ DI,AX
|
||||
MOVQ SI,DX
|
||||
RET
|
||||
1398
vendor/github.com/wg/ecies/vendor/golang.org/x/crypto/curve25519/ladderstep_amd64.s
generated
vendored
Normal file
1398
vendor/github.com/wg/ecies/vendor/golang.org/x/crypto/curve25519/ladderstep_amd64.s
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
240
vendor/github.com/wg/ecies/vendor/golang.org/x/crypto/curve25519/mont25519_amd64.go
generated
vendored
Normal file
240
vendor/github.com/wg/ecies/vendor/golang.org/x/crypto/curve25519/mont25519_amd64.go
generated
vendored
Normal file
@@ -0,0 +1,240 @@
|
||||
// Copyright 2012 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.
|
||||
|
||||
// +build amd64,!gccgo,!appengine
|
||||
|
||||
package curve25519
|
||||
|
||||
// These functions are implemented in the .s files. The names of the functions
|
||||
// in the rest of the file are also taken from the SUPERCOP sources to help
|
||||
// people following along.
|
||||
|
||||
//go:noescape
|
||||
|
||||
func cswap(inout *[5]uint64, v uint64)
|
||||
|
||||
//go:noescape
|
||||
|
||||
func ladderstep(inout *[5][5]uint64)
|
||||
|
||||
//go:noescape
|
||||
|
||||
func freeze(inout *[5]uint64)
|
||||
|
||||
//go:noescape
|
||||
|
||||
func mul(dest, a, b *[5]uint64)
|
||||
|
||||
//go:noescape
|
||||
|
||||
func square(out, in *[5]uint64)
|
||||
|
||||
// mladder uses a Montgomery ladder to calculate (xr/zr) *= s.
|
||||
func mladder(xr, zr *[5]uint64, s *[32]byte) {
|
||||
var work [5][5]uint64
|
||||
|
||||
work[0] = *xr
|
||||
setint(&work[1], 1)
|
||||
setint(&work[2], 0)
|
||||
work[3] = *xr
|
||||
setint(&work[4], 1)
|
||||
|
||||
j := uint(6)
|
||||
var prevbit byte
|
||||
|
||||
for i := 31; i >= 0; i-- {
|
||||
for j < 8 {
|
||||
bit := ((*s)[i] >> j) & 1
|
||||
swap := bit ^ prevbit
|
||||
prevbit = bit
|
||||
cswap(&work[1], uint64(swap))
|
||||
ladderstep(&work)
|
||||
j--
|
||||
}
|
||||
j = 7
|
||||
}
|
||||
|
||||
*xr = work[1]
|
||||
*zr = work[2]
|
||||
}
|
||||
|
||||
func scalarMult(out, in, base *[32]byte) {
|
||||
var e [32]byte
|
||||
copy(e[:], (*in)[:])
|
||||
e[0] &= 248
|
||||
e[31] &= 127
|
||||
e[31] |= 64
|
||||
|
||||
var t, z [5]uint64
|
||||
unpack(&t, base)
|
||||
mladder(&t, &z, &e)
|
||||
invert(&z, &z)
|
||||
mul(&t, &t, &z)
|
||||
pack(out, &t)
|
||||
}
|
||||
|
||||
func setint(r *[5]uint64, v uint64) {
|
||||
r[0] = v
|
||||
r[1] = 0
|
||||
r[2] = 0
|
||||
r[3] = 0
|
||||
r[4] = 0
|
||||
}
|
||||
|
||||
// unpack sets r = x where r consists of 5, 51-bit limbs in little-endian
|
||||
// order.
|
||||
func unpack(r *[5]uint64, x *[32]byte) {
|
||||
r[0] = uint64(x[0]) |
|
||||
uint64(x[1])<<8 |
|
||||
uint64(x[2])<<16 |
|
||||
uint64(x[3])<<24 |
|
||||
uint64(x[4])<<32 |
|
||||
uint64(x[5])<<40 |
|
||||
uint64(x[6]&7)<<48
|
||||
|
||||
r[1] = uint64(x[6])>>3 |
|
||||
uint64(x[7])<<5 |
|
||||
uint64(x[8])<<13 |
|
||||
uint64(x[9])<<21 |
|
||||
uint64(x[10])<<29 |
|
||||
uint64(x[11])<<37 |
|
||||
uint64(x[12]&63)<<45
|
||||
|
||||
r[2] = uint64(x[12])>>6 |
|
||||
uint64(x[13])<<2 |
|
||||
uint64(x[14])<<10 |
|
||||
uint64(x[15])<<18 |
|
||||
uint64(x[16])<<26 |
|
||||
uint64(x[17])<<34 |
|
||||
uint64(x[18])<<42 |
|
||||
uint64(x[19]&1)<<50
|
||||
|
||||
r[3] = uint64(x[19])>>1 |
|
||||
uint64(x[20])<<7 |
|
||||
uint64(x[21])<<15 |
|
||||
uint64(x[22])<<23 |
|
||||
uint64(x[23])<<31 |
|
||||
uint64(x[24])<<39 |
|
||||
uint64(x[25]&15)<<47
|
||||
|
||||
r[4] = uint64(x[25])>>4 |
|
||||
uint64(x[26])<<4 |
|
||||
uint64(x[27])<<12 |
|
||||
uint64(x[28])<<20 |
|
||||
uint64(x[29])<<28 |
|
||||
uint64(x[30])<<36 |
|
||||
uint64(x[31]&127)<<44
|
||||
}
|
||||
|
||||
// pack sets out = x where out is the usual, little-endian form of the 5,
|
||||
// 51-bit limbs in x.
|
||||
func pack(out *[32]byte, x *[5]uint64) {
|
||||
t := *x
|
||||
freeze(&t)
|
||||
|
||||
out[0] = byte(t[0])
|
||||
out[1] = byte(t[0] >> 8)
|
||||
out[2] = byte(t[0] >> 16)
|
||||
out[3] = byte(t[0] >> 24)
|
||||
out[4] = byte(t[0] >> 32)
|
||||
out[5] = byte(t[0] >> 40)
|
||||
out[6] = byte(t[0] >> 48)
|
||||
|
||||
out[6] ^= byte(t[1]<<3) & 0xf8
|
||||
out[7] = byte(t[1] >> 5)
|
||||
out[8] = byte(t[1] >> 13)
|
||||
out[9] = byte(t[1] >> 21)
|
||||
out[10] = byte(t[1] >> 29)
|
||||
out[11] = byte(t[1] >> 37)
|
||||
out[12] = byte(t[1] >> 45)
|
||||
|
||||
out[12] ^= byte(t[2]<<6) & 0xc0
|
||||
out[13] = byte(t[2] >> 2)
|
||||
out[14] = byte(t[2] >> 10)
|
||||
out[15] = byte(t[2] >> 18)
|
||||
out[16] = byte(t[2] >> 26)
|
||||
out[17] = byte(t[2] >> 34)
|
||||
out[18] = byte(t[2] >> 42)
|
||||
out[19] = byte(t[2] >> 50)
|
||||
|
||||
out[19] ^= byte(t[3]<<1) & 0xfe
|
||||
out[20] = byte(t[3] >> 7)
|
||||
out[21] = byte(t[3] >> 15)
|
||||
out[22] = byte(t[3] >> 23)
|
||||
out[23] = byte(t[3] >> 31)
|
||||
out[24] = byte(t[3] >> 39)
|
||||
out[25] = byte(t[3] >> 47)
|
||||
|
||||
out[25] ^= byte(t[4]<<4) & 0xf0
|
||||
out[26] = byte(t[4] >> 4)
|
||||
out[27] = byte(t[4] >> 12)
|
||||
out[28] = byte(t[4] >> 20)
|
||||
out[29] = byte(t[4] >> 28)
|
||||
out[30] = byte(t[4] >> 36)
|
||||
out[31] = byte(t[4] >> 44)
|
||||
}
|
||||
|
||||
// invert calculates r = x^-1 mod p using Fermat's little theorem.
|
||||
func invert(r *[5]uint64, x *[5]uint64) {
|
||||
var z2, z9, z11, z2_5_0, z2_10_0, z2_20_0, z2_50_0, z2_100_0, t [5]uint64
|
||||
|
||||
square(&z2, x) /* 2 */
|
||||
square(&t, &z2) /* 4 */
|
||||
square(&t, &t) /* 8 */
|
||||
mul(&z9, &t, x) /* 9 */
|
||||
mul(&z11, &z9, &z2) /* 11 */
|
||||
square(&t, &z11) /* 22 */
|
||||
mul(&z2_5_0, &t, &z9) /* 2^5 - 2^0 = 31 */
|
||||
|
||||
square(&t, &z2_5_0) /* 2^6 - 2^1 */
|
||||
for i := 1; i < 5; i++ { /* 2^20 - 2^10 */
|
||||
square(&t, &t)
|
||||
}
|
||||
mul(&z2_10_0, &t, &z2_5_0) /* 2^10 - 2^0 */
|
||||
|
||||
square(&t, &z2_10_0) /* 2^11 - 2^1 */
|
||||
for i := 1; i < 10; i++ { /* 2^20 - 2^10 */
|
||||
square(&t, &t)
|
||||
}
|
||||
mul(&z2_20_0, &t, &z2_10_0) /* 2^20 - 2^0 */
|
||||
|
||||
square(&t, &z2_20_0) /* 2^21 - 2^1 */
|
||||
for i := 1; i < 20; i++ { /* 2^40 - 2^20 */
|
||||
square(&t, &t)
|
||||
}
|
||||
mul(&t, &t, &z2_20_0) /* 2^40 - 2^0 */
|
||||
|
||||
square(&t, &t) /* 2^41 - 2^1 */
|
||||
for i := 1; i < 10; i++ { /* 2^50 - 2^10 */
|
||||
square(&t, &t)
|
||||
}
|
||||
mul(&z2_50_0, &t, &z2_10_0) /* 2^50 - 2^0 */
|
||||
|
||||
square(&t, &z2_50_0) /* 2^51 - 2^1 */
|
||||
for i := 1; i < 50; i++ { /* 2^100 - 2^50 */
|
||||
square(&t, &t)
|
||||
}
|
||||
mul(&z2_100_0, &t, &z2_50_0) /* 2^100 - 2^0 */
|
||||
|
||||
square(&t, &z2_100_0) /* 2^101 - 2^1 */
|
||||
for i := 1; i < 100; i++ { /* 2^200 - 2^100 */
|
||||
square(&t, &t)
|
||||
}
|
||||
mul(&t, &t, &z2_100_0) /* 2^200 - 2^0 */
|
||||
|
||||
square(&t, &t) /* 2^201 - 2^1 */
|
||||
for i := 1; i < 50; i++ { /* 2^250 - 2^50 */
|
||||
square(&t, &t)
|
||||
}
|
||||
mul(&t, &t, &z2_50_0) /* 2^250 - 2^0 */
|
||||
|
||||
square(&t, &t) /* 2^251 - 2^1 */
|
||||
square(&t, &t) /* 2^252 - 2^2 */
|
||||
square(&t, &t) /* 2^253 - 2^3 */
|
||||
|
||||
square(&t, &t) /* 2^254 - 2^4 */
|
||||
|
||||
square(&t, &t) /* 2^255 - 2^5 */
|
||||
mul(r, &t, &z11) /* 2^255 - 21 */
|
||||
}
|
||||
191
vendor/github.com/wg/ecies/vendor/golang.org/x/crypto/curve25519/mul_amd64.s
generated
vendored
Normal file
191
vendor/github.com/wg/ecies/vendor/golang.org/x/crypto/curve25519/mul_amd64.s
generated
vendored
Normal file
@@ -0,0 +1,191 @@
|
||||
// Copyright 2012 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.
|
||||
|
||||
// This code was translated into a form compatible with 6a from the public
|
||||
// domain sources in SUPERCOP: http://bench.cr.yp.to/supercop.html
|
||||
|
||||
// +build amd64,!gccgo,!appengine
|
||||
|
||||
// func mul(dest, a, b *[5]uint64)
|
||||
TEXT ·mul(SB),0,$128-24
|
||||
MOVQ dest+0(FP), DI
|
||||
MOVQ a+8(FP), SI
|
||||
MOVQ b+16(FP), DX
|
||||
|
||||
MOVQ SP,R11
|
||||
MOVQ $31,CX
|
||||
NOTQ CX
|
||||
ANDQ CX,SP
|
||||
ADDQ $32,SP
|
||||
|
||||
MOVQ R11,0(SP)
|
||||
MOVQ R12,8(SP)
|
||||
MOVQ R13,16(SP)
|
||||
MOVQ R14,24(SP)
|
||||
MOVQ R15,32(SP)
|
||||
MOVQ BX,40(SP)
|
||||
MOVQ BP,48(SP)
|
||||
MOVQ DI,56(SP)
|
||||
MOVQ DX,CX
|
||||
MOVQ 24(SI),DX
|
||||
IMUL3Q $19,DX,AX
|
||||
MOVQ AX,64(SP)
|
||||
MULQ 16(CX)
|
||||
MOVQ AX,R8
|
||||
MOVQ DX,R9
|
||||
MOVQ 32(SI),DX
|
||||
IMUL3Q $19,DX,AX
|
||||
MOVQ AX,72(SP)
|
||||
MULQ 8(CX)
|
||||
ADDQ AX,R8
|
||||
ADCQ DX,R9
|
||||
MOVQ 0(SI),AX
|
||||
MULQ 0(CX)
|
||||
ADDQ AX,R8
|
||||
ADCQ DX,R9
|
||||
MOVQ 0(SI),AX
|
||||
MULQ 8(CX)
|
||||
MOVQ AX,R10
|
||||
MOVQ DX,R11
|
||||
MOVQ 0(SI),AX
|
||||
MULQ 16(CX)
|
||||
MOVQ AX,R12
|
||||
MOVQ DX,R13
|
||||
MOVQ 0(SI),AX
|
||||
MULQ 24(CX)
|
||||
MOVQ AX,R14
|
||||
MOVQ DX,R15
|
||||
MOVQ 0(SI),AX
|
||||
MULQ 32(CX)
|
||||
MOVQ AX,BX
|
||||
MOVQ DX,BP
|
||||
MOVQ 8(SI),AX
|
||||
MULQ 0(CX)
|
||||
ADDQ AX,R10
|
||||
ADCQ DX,R11
|
||||
MOVQ 8(SI),AX
|
||||
MULQ 8(CX)
|
||||
ADDQ AX,R12
|
||||
ADCQ DX,R13
|
||||
MOVQ 8(SI),AX
|
||||
MULQ 16(CX)
|
||||
ADDQ AX,R14
|
||||
ADCQ DX,R15
|
||||
MOVQ 8(SI),AX
|
||||
MULQ 24(CX)
|
||||
ADDQ AX,BX
|
||||
ADCQ DX,BP
|
||||
MOVQ 8(SI),DX
|
||||
IMUL3Q $19,DX,AX
|
||||
MULQ 32(CX)
|
||||
ADDQ AX,R8
|
||||
ADCQ DX,R9
|
||||
MOVQ 16(SI),AX
|
||||
MULQ 0(CX)
|
||||
ADDQ AX,R12
|
||||
ADCQ DX,R13
|
||||
MOVQ 16(SI),AX
|
||||
MULQ 8(CX)
|
||||
ADDQ AX,R14
|
||||
ADCQ DX,R15
|
||||
MOVQ 16(SI),AX
|
||||
MULQ 16(CX)
|
||||
ADDQ AX,BX
|
||||
ADCQ DX,BP
|
||||
MOVQ 16(SI),DX
|
||||
IMUL3Q $19,DX,AX
|
||||
MULQ 24(CX)
|
||||
ADDQ AX,R8
|
||||
ADCQ DX,R9
|
||||
MOVQ 16(SI),DX
|
||||
IMUL3Q $19,DX,AX
|
||||
MULQ 32(CX)
|
||||
ADDQ AX,R10
|
||||
ADCQ DX,R11
|
||||
MOVQ 24(SI),AX
|
||||
MULQ 0(CX)
|
||||
ADDQ AX,R14
|
||||
ADCQ DX,R15
|
||||
MOVQ 24(SI),AX
|
||||
MULQ 8(CX)
|
||||
ADDQ AX,BX
|
||||
ADCQ DX,BP
|
||||
MOVQ 64(SP),AX
|
||||
MULQ 24(CX)
|
||||
ADDQ AX,R10
|
||||
ADCQ DX,R11
|
||||
MOVQ 64(SP),AX
|
||||
MULQ 32(CX)
|
||||
ADDQ AX,R12
|
||||
ADCQ DX,R13
|
||||
MOVQ 32(SI),AX
|
||||
MULQ 0(CX)
|
||||
ADDQ AX,BX
|
||||
ADCQ DX,BP
|
||||
MOVQ 72(SP),AX
|
||||
MULQ 16(CX)
|
||||
ADDQ AX,R10
|
||||
ADCQ DX,R11
|
||||
MOVQ 72(SP),AX
|
||||
MULQ 24(CX)
|
||||
ADDQ AX,R12
|
||||
ADCQ DX,R13
|
||||
MOVQ 72(SP),AX
|
||||
MULQ 32(CX)
|
||||
ADDQ AX,R14
|
||||
ADCQ DX,R15
|
||||
MOVQ ·REDMASK51(SB),SI
|
||||
SHLQ $13,R9:R8
|
||||
ANDQ SI,R8
|
||||
SHLQ $13,R11:R10
|
||||
ANDQ SI,R10
|
||||
ADDQ R9,R10
|
||||
SHLQ $13,R13:R12
|
||||
ANDQ SI,R12
|
||||
ADDQ R11,R12
|
||||
SHLQ $13,R15:R14
|
||||
ANDQ SI,R14
|
||||
ADDQ R13,R14
|
||||
SHLQ $13,BP:BX
|
||||
ANDQ SI,BX
|
||||
ADDQ R15,BX
|
||||
IMUL3Q $19,BP,DX
|
||||
ADDQ DX,R8
|
||||
MOVQ R8,DX
|
||||
SHRQ $51,DX
|
||||
ADDQ R10,DX
|
||||
MOVQ DX,CX
|
||||
SHRQ $51,DX
|
||||
ANDQ SI,R8
|
||||
ADDQ R12,DX
|
||||
MOVQ DX,R9
|
||||
SHRQ $51,DX
|
||||
ANDQ SI,CX
|
||||
ADDQ R14,DX
|
||||
MOVQ DX,AX
|
||||
SHRQ $51,DX
|
||||
ANDQ SI,R9
|
||||
ADDQ BX,DX
|
||||
MOVQ DX,R10
|
||||
SHRQ $51,DX
|
||||
ANDQ SI,AX
|
||||
IMUL3Q $19,DX,DX
|
||||
ADDQ DX,R8
|
||||
ANDQ SI,R10
|
||||
MOVQ R8,0(DI)
|
||||
MOVQ CX,8(DI)
|
||||
MOVQ R9,16(DI)
|
||||
MOVQ AX,24(DI)
|
||||
MOVQ R10,32(DI)
|
||||
MOVQ 0(SP),R11
|
||||
MOVQ 8(SP),R12
|
||||
MOVQ 16(SP),R13
|
||||
MOVQ 24(SP),R14
|
||||
MOVQ 32(SP),R15
|
||||
MOVQ 40(SP),BX
|
||||
MOVQ 48(SP),BP
|
||||
MOVQ R11,SP
|
||||
MOVQ DI,AX
|
||||
MOVQ SI,DX
|
||||
RET
|
||||
153
vendor/github.com/wg/ecies/vendor/golang.org/x/crypto/curve25519/square_amd64.s
generated
vendored
Normal file
153
vendor/github.com/wg/ecies/vendor/golang.org/x/crypto/curve25519/square_amd64.s
generated
vendored
Normal file
@@ -0,0 +1,153 @@
|
||||
// Copyright 2012 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.
|
||||
|
||||
// This code was translated into a form compatible with 6a from the public
|
||||
// domain sources in SUPERCOP: http://bench.cr.yp.to/supercop.html
|
||||
|
||||
// +build amd64,!gccgo,!appengine
|
||||
|
||||
// func square(out, in *[5]uint64)
|
||||
TEXT ·square(SB),7,$96-16
|
||||
MOVQ out+0(FP), DI
|
||||
MOVQ in+8(FP), SI
|
||||
|
||||
MOVQ SP,R11
|
||||
MOVQ $31,CX
|
||||
NOTQ CX
|
||||
ANDQ CX,SP
|
||||
ADDQ $32, SP
|
||||
|
||||
MOVQ R11,0(SP)
|
||||
MOVQ R12,8(SP)
|
||||
MOVQ R13,16(SP)
|
||||
MOVQ R14,24(SP)
|
||||
MOVQ R15,32(SP)
|
||||
MOVQ BX,40(SP)
|
||||
MOVQ BP,48(SP)
|
||||
MOVQ 0(SI),AX
|
||||
MULQ 0(SI)
|
||||
MOVQ AX,CX
|
||||
MOVQ DX,R8
|
||||
MOVQ 0(SI),AX
|
||||
SHLQ $1,AX
|
||||
MULQ 8(SI)
|
||||
MOVQ AX,R9
|
||||
MOVQ DX,R10
|
||||
MOVQ 0(SI),AX
|
||||
SHLQ $1,AX
|
||||
MULQ 16(SI)
|
||||
MOVQ AX,R11
|
||||
MOVQ DX,R12
|
||||
MOVQ 0(SI),AX
|
||||
SHLQ $1,AX
|
||||
MULQ 24(SI)
|
||||
MOVQ AX,R13
|
||||
MOVQ DX,R14
|
||||
MOVQ 0(SI),AX
|
||||
SHLQ $1,AX
|
||||
MULQ 32(SI)
|
||||
MOVQ AX,R15
|
||||
MOVQ DX,BX
|
||||
MOVQ 8(SI),AX
|
||||
MULQ 8(SI)
|
||||
ADDQ AX,R11
|
||||
ADCQ DX,R12
|
||||
MOVQ 8(SI),AX
|
||||
SHLQ $1,AX
|
||||
MULQ 16(SI)
|
||||
ADDQ AX,R13
|
||||
ADCQ DX,R14
|
||||
MOVQ 8(SI),AX
|
||||
SHLQ $1,AX
|
||||
MULQ 24(SI)
|
||||
ADDQ AX,R15
|
||||
ADCQ DX,BX
|
||||
MOVQ 8(SI),DX
|
||||
IMUL3Q $38,DX,AX
|
||||
MULQ 32(SI)
|
||||
ADDQ AX,CX
|
||||
ADCQ DX,R8
|
||||
MOVQ 16(SI),AX
|
||||
MULQ 16(SI)
|
||||
ADDQ AX,R15
|
||||
ADCQ DX,BX
|
||||
MOVQ 16(SI),DX
|
||||
IMUL3Q $38,DX,AX
|
||||
MULQ 24(SI)
|
||||
ADDQ AX,CX
|
||||
ADCQ DX,R8
|
||||
MOVQ 16(SI),DX
|
||||
IMUL3Q $38,DX,AX
|
||||
MULQ 32(SI)
|
||||
ADDQ AX,R9
|
||||
ADCQ DX,R10
|
||||
MOVQ 24(SI),DX
|
||||
IMUL3Q $19,DX,AX
|
||||
MULQ 24(SI)
|
||||
ADDQ AX,R9
|
||||
ADCQ DX,R10
|
||||
MOVQ 24(SI),DX
|
||||
IMUL3Q $38,DX,AX
|
||||
MULQ 32(SI)
|
||||
ADDQ AX,R11
|
||||
ADCQ DX,R12
|
||||
MOVQ 32(SI),DX
|
||||
IMUL3Q $19,DX,AX
|
||||
MULQ 32(SI)
|
||||
ADDQ AX,R13
|
||||
ADCQ DX,R14
|
||||
MOVQ ·REDMASK51(SB),SI
|
||||
SHLQ $13,R8:CX
|
||||
ANDQ SI,CX
|
||||
SHLQ $13,R10:R9
|
||||
ANDQ SI,R9
|
||||
ADDQ R8,R9
|
||||
SHLQ $13,R12:R11
|
||||
ANDQ SI,R11
|
||||
ADDQ R10,R11
|
||||
SHLQ $13,R14:R13
|
||||
ANDQ SI,R13
|
||||
ADDQ R12,R13
|
||||
SHLQ $13,BX:R15
|
||||
ANDQ SI,R15
|
||||
ADDQ R14,R15
|
||||
IMUL3Q $19,BX,DX
|
||||
ADDQ DX,CX
|
||||
MOVQ CX,DX
|
||||
SHRQ $51,DX
|
||||
ADDQ R9,DX
|
||||
ANDQ SI,CX
|
||||
MOVQ DX,R8
|
||||
SHRQ $51,DX
|
||||
ADDQ R11,DX
|
||||
ANDQ SI,R8
|
||||
MOVQ DX,R9
|
||||
SHRQ $51,DX
|
||||
ADDQ R13,DX
|
||||
ANDQ SI,R9
|
||||
MOVQ DX,AX
|
||||
SHRQ $51,DX
|
||||
ADDQ R15,DX
|
||||
ANDQ SI,AX
|
||||
MOVQ DX,R10
|
||||
SHRQ $51,DX
|
||||
IMUL3Q $19,DX,DX
|
||||
ADDQ DX,CX
|
||||
ANDQ SI,R10
|
||||
MOVQ CX,0(DI)
|
||||
MOVQ R8,8(DI)
|
||||
MOVQ R9,16(DI)
|
||||
MOVQ AX,24(DI)
|
||||
MOVQ R10,32(DI)
|
||||
MOVQ 0(SP),R11
|
||||
MOVQ 8(SP),R12
|
||||
MOVQ 16(SP),R13
|
||||
MOVQ 24(SP),R14
|
||||
MOVQ 32(SP),R15
|
||||
MOVQ 40(SP),BX
|
||||
MOVQ 48(SP),BP
|
||||
MOVQ R11,SP
|
||||
MOVQ DI,AX
|
||||
MOVQ SI,DX
|
||||
RET
|
||||
122
vendor/github.com/wg/ecies/vendor/schwanenlied.me/yawning/chacha20/LICENSE
generated
vendored
Normal file
122
vendor/github.com/wg/ecies/vendor/schwanenlied.me/yawning/chacha20/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,122 @@
|
||||
Creative Commons Legal Code
|
||||
|
||||
CC0 1.0 Universal
|
||||
|
||||
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
|
||||
LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
|
||||
ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
|
||||
INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
|
||||
REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
|
||||
PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
|
||||
THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
|
||||
HEREUNDER.
|
||||
|
||||
Statement of Purpose
|
||||
|
||||
The laws of most jurisdictions throughout the world automatically confer
|
||||
exclusive Copyright and Related Rights (defined below) upon the creator
|
||||
and subsequent owner(s) (each and all, an "owner") of an original work of
|
||||
authorship and/or a database (each, a "Work").
|
||||
|
||||
Certain owners wish to permanently relinquish those rights to a Work for
|
||||
the purpose of contributing to a commons of creative, cultural and
|
||||
scientific works ("Commons") that the public can reliably and without fear
|
||||
of later claims of infringement build upon, modify, incorporate in other
|
||||
works, reuse and redistribute as freely as possible in any form whatsoever
|
||||
and for any purposes, including without limitation commercial purposes.
|
||||
These owners may contribute to the Commons to promote the ideal of a free
|
||||
culture and the further production of creative, cultural and scientific
|
||||
works, or to gain reputation or greater distribution for their Work in
|
||||
part through the use and efforts of others.
|
||||
|
||||
For these and/or other purposes and motivations, and without any
|
||||
expectation of additional consideration or compensation, the person
|
||||
associating CC0 with a Work (the "Affirmer"), to the extent that he or she
|
||||
is an owner of Copyright and Related Rights in the Work, voluntarily
|
||||
elects to apply CC0 to the Work and publicly distribute the Work under its
|
||||
terms, with knowledge of his or her Copyright and Related Rights in the
|
||||
Work and the meaning and intended legal effect of CC0 on those rights.
|
||||
|
||||
1. Copyright and Related Rights. A Work made available under CC0 may be
|
||||
protected by copyright and related or neighboring rights ("Copyright and
|
||||
Related Rights"). Copyright and Related Rights include, but are not
|
||||
limited to, the following:
|
||||
|
||||
i. the right to reproduce, adapt, distribute, perform, display,
|
||||
communicate, and translate a Work;
|
||||
ii. moral rights retained by the original author(s) and/or performer(s);
|
||||
iii. publicity and privacy rights pertaining to a person's image or
|
||||
likeness depicted in a Work;
|
||||
iv. rights protecting against unfair competition in regards to a Work,
|
||||
subject to the limitations in paragraph 4(a), below;
|
||||
v. rights protecting the extraction, dissemination, use and reuse of data
|
||||
in a Work;
|
||||
vi. database rights (such as those arising under Directive 96/9/EC of the
|
||||
European Parliament and of the Council of 11 March 1996 on the legal
|
||||
protection of databases, and under any national implementation
|
||||
thereof, including any amended or successor version of such
|
||||
directive); and
|
||||
vii. other similar, equivalent or corresponding rights throughout the
|
||||
world based on applicable law or treaty, and any national
|
||||
implementations thereof.
|
||||
|
||||
2. Waiver. To the greatest extent permitted by, but not in contravention
|
||||
of, applicable law, Affirmer hereby overtly, fully, permanently,
|
||||
irrevocably and unconditionally waives, abandons, and surrenders all of
|
||||
Affirmer's Copyright and Related Rights and associated claims and causes
|
||||
of action, whether now known or unknown (including existing as well as
|
||||
future claims and causes of action), in the Work (i) in all territories
|
||||
worldwide, (ii) for the maximum duration provided by applicable law or
|
||||
treaty (including future time extensions), (iii) in any current or future
|
||||
medium and for any number of copies, and (iv) for any purpose whatsoever,
|
||||
including without limitation commercial, advertising or promotional
|
||||
purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
|
||||
member of the public at large and to the detriment of Affirmer's heirs and
|
||||
successors, fully intending that such Waiver shall not be subject to
|
||||
revocation, rescission, cancellation, termination, or any other legal or
|
||||
equitable action to disrupt the quiet enjoyment of the Work by the public
|
||||
as contemplated by Affirmer's express Statement of Purpose.
|
||||
|
||||
3. Public License Fallback. Should any part of the Waiver for any reason
|
||||
be judged legally invalid or ineffective under applicable law, then the
|
||||
Waiver shall be preserved to the maximum extent permitted taking into
|
||||
account Affirmer's express Statement of Purpose. In addition, to the
|
||||
extent the Waiver is so judged Affirmer hereby grants to each affected
|
||||
person a royalty-free, non transferable, non sublicensable, non exclusive,
|
||||
irrevocable and unconditional license to exercise Affirmer's Copyright and
|
||||
Related Rights in the Work (i) in all territories worldwide, (ii) for the
|
||||
maximum duration provided by applicable law or treaty (including future
|
||||
time extensions), (iii) in any current or future medium and for any number
|
||||
of copies, and (iv) for any purpose whatsoever, including without
|
||||
limitation commercial, advertising or promotional purposes (the
|
||||
"License"). The License shall be deemed effective as of the date CC0 was
|
||||
applied by Affirmer to the Work. Should any part of the License for any
|
||||
reason be judged legally invalid or ineffective under applicable law, such
|
||||
partial invalidity or ineffectiveness shall not invalidate the remainder
|
||||
of the License, and in such case Affirmer hereby affirms that he or she
|
||||
will not (i) exercise any of his or her remaining Copyright and Related
|
||||
Rights in the Work or (ii) assert any associated claims and causes of
|
||||
action with respect to the Work, in either case contrary to Affirmer's
|
||||
express Statement of Purpose.
|
||||
|
||||
4. Limitations and Disclaimers.
|
||||
|
||||
a. No trademark or patent rights held by Affirmer are waived, abandoned,
|
||||
surrendered, licensed or otherwise affected by this document.
|
||||
b. Affirmer offers the Work as-is and makes no representations or
|
||||
warranties of any kind concerning the Work, express, implied,
|
||||
statutory or otherwise, including without limitation warranties of
|
||||
title, merchantability, fitness for a particular purpose, non
|
||||
infringement, or the absence of latent or other defects, accuracy, or
|
||||
the present or absence of errors, whether or not discoverable, all to
|
||||
the greatest extent permissible under applicable law.
|
||||
c. Affirmer disclaims responsibility for clearing rights of other persons
|
||||
that may apply to the Work or any use thereof, including without
|
||||
limitation any person's Copyright and Related Rights in the Work.
|
||||
Further, Affirmer disclaims responsibility for obtaining any necessary
|
||||
consents, permissions or other rights required for any use of the
|
||||
Work.
|
||||
d. Affirmer understands and acknowledges that Creative Commons is not a
|
||||
party to this document and has no duty or obligation with respect to
|
||||
this CC0 or use of the Work.
|
||||
|
||||
14
vendor/github.com/wg/ecies/vendor/schwanenlied.me/yawning/chacha20/README.md
generated
vendored
Normal file
14
vendor/github.com/wg/ecies/vendor/schwanenlied.me/yawning/chacha20/README.md
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
### chacha20 - ChaCha20
|
||||
#### Yawning Angel (yawning at schwanenlied dot me)
|
||||
|
||||
Yet another Go ChaCha20 implementation. Everything else I found was slow,
|
||||
didn't support all the variants I need to use, or relied on cgo to go fast.
|
||||
|
||||
Features:
|
||||
|
||||
* 20 round, 256 bit key only. Everything else is pointless and stupid.
|
||||
* IETF 96 bit nonce variant.
|
||||
* XChaCha 24 byte nonce variant.
|
||||
* SSE2 and AVX2 support on amd64 targets.
|
||||
* Incremental encrypt/decrypt support, unlike golang.org/x/crypto/salsa20.
|
||||
|
||||
273
vendor/github.com/wg/ecies/vendor/schwanenlied.me/yawning/chacha20/chacha20.go
generated
vendored
Normal file
273
vendor/github.com/wg/ecies/vendor/schwanenlied.me/yawning/chacha20/chacha20.go
generated
vendored
Normal file
@@ -0,0 +1,273 @@
|
||||
// chacha20.go - A ChaCha stream cipher implementation.
|
||||
//
|
||||
// To the extent possible under law, Yawning Angel has waived all copyright
|
||||
// and related or neighboring rights to chacha20, using the Creative
|
||||
// Commons "CC0" public domain dedication. See LICENSE or
|
||||
// <http://creativecommons.org/publicdomain/zero/1.0/> for full details.
|
||||
|
||||
package chacha20
|
||||
|
||||
import (
|
||||
"crypto/cipher"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"math"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
const (
|
||||
// KeySize is the ChaCha20 key size in bytes.
|
||||
KeySize = 32
|
||||
|
||||
// NonceSize is the ChaCha20 nonce size in bytes.
|
||||
NonceSize = 8
|
||||
|
||||
// INonceSize is the IETF ChaCha20 nonce size in bytes.
|
||||
INonceSize = 12
|
||||
|
||||
// XNonceSize is the XChaCha20 nonce size in bytes.
|
||||
XNonceSize = 24
|
||||
|
||||
// HNonceSize is the HChaCha20 nonce size in bytes.
|
||||
HNonceSize = 16
|
||||
|
||||
// BlockSize is the ChaCha20 block size in bytes.
|
||||
BlockSize = 64
|
||||
|
||||
stateSize = 16
|
||||
chachaRounds = 20
|
||||
|
||||
// The constant "expand 32-byte k" as little endian uint32s.
|
||||
sigma0 = uint32(0x61707865)
|
||||
sigma1 = uint32(0x3320646e)
|
||||
sigma2 = uint32(0x79622d32)
|
||||
sigma3 = uint32(0x6b206574)
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrInvalidKey is the error returned when the key is invalid.
|
||||
ErrInvalidKey = errors.New("key length must be KeySize bytes")
|
||||
|
||||
// ErrInvalidNonce is the error returned when the nonce is invalid.
|
||||
ErrInvalidNonce = errors.New("nonce length must be NonceSize/INonceSize/XNonceSize bytes")
|
||||
|
||||
// ErrInvalidCounter is the error returned when the counter is invalid.
|
||||
ErrInvalidCounter = errors.New("block counter is invalid (out of range)")
|
||||
|
||||
useUnsafe = false
|
||||
usingVectors = false
|
||||
blocksFn = blocksRef
|
||||
)
|
||||
|
||||
// A Cipher is an instance of ChaCha20/XChaCha20 using a particular key and
|
||||
// nonce.
|
||||
type Cipher struct {
|
||||
state [stateSize]uint32
|
||||
|
||||
buf [BlockSize]byte
|
||||
off int
|
||||
ietf bool
|
||||
}
|
||||
|
||||
// Reset zeros the key data so that it will no longer appear in the process's
|
||||
// memory.
|
||||
func (c *Cipher) Reset() {
|
||||
for i := range c.state {
|
||||
c.state[i] = 0
|
||||
}
|
||||
for i := range c.buf {
|
||||
c.buf[i] = 0
|
||||
}
|
||||
}
|
||||
|
||||
// XORKeyStream sets dst to the result of XORing src with the key stream. Dst
|
||||
// and src may be the same slice but otherwise should not overlap.
|
||||
func (c *Cipher) XORKeyStream(dst, src []byte) {
|
||||
if len(dst) < len(src) {
|
||||
src = src[:len(dst)]
|
||||
}
|
||||
|
||||
for remaining := len(src); remaining > 0; {
|
||||
// Process multiple blocks at once.
|
||||
if c.off == BlockSize {
|
||||
nrBlocks := remaining / BlockSize
|
||||
directBytes := nrBlocks * BlockSize
|
||||
if nrBlocks > 0 {
|
||||
blocksFn(&c.state, src, dst, nrBlocks, c.ietf)
|
||||
remaining -= directBytes
|
||||
if remaining == 0 {
|
||||
return
|
||||
}
|
||||
dst = dst[directBytes:]
|
||||
src = src[directBytes:]
|
||||
}
|
||||
|
||||
// If there's a partial block, generate 1 block of keystream into
|
||||
// the internal buffer.
|
||||
blocksFn(&c.state, nil, c.buf[:], 1, c.ietf)
|
||||
c.off = 0
|
||||
}
|
||||
|
||||
// Process partial blocks from the buffered keystream.
|
||||
toXor := BlockSize - c.off
|
||||
if remaining < toXor {
|
||||
toXor = remaining
|
||||
}
|
||||
if toXor > 0 {
|
||||
for i, v := range src[:toXor] {
|
||||
dst[i] = v ^ c.buf[c.off+i]
|
||||
}
|
||||
dst = dst[toXor:]
|
||||
src = src[toXor:]
|
||||
|
||||
remaining -= toXor
|
||||
c.off += toXor
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// KeyStream sets dst to the raw keystream.
|
||||
func (c *Cipher) KeyStream(dst []byte) {
|
||||
for remaining := len(dst); remaining > 0; {
|
||||
// Process multiple blocks at once.
|
||||
if c.off == BlockSize {
|
||||
nrBlocks := remaining / BlockSize
|
||||
directBytes := nrBlocks * BlockSize
|
||||
if nrBlocks > 0 {
|
||||
blocksFn(&c.state, nil, dst, nrBlocks, c.ietf)
|
||||
remaining -= directBytes
|
||||
if remaining == 0 {
|
||||
return
|
||||
}
|
||||
dst = dst[directBytes:]
|
||||
}
|
||||
|
||||
// If there's a partial block, generate 1 block of keystream into
|
||||
// the internal buffer.
|
||||
blocksFn(&c.state, nil, c.buf[:], 1, c.ietf)
|
||||
c.off = 0
|
||||
}
|
||||
|
||||
// Process partial blocks from the buffered keystream.
|
||||
toCopy := BlockSize - c.off
|
||||
if remaining < toCopy {
|
||||
toCopy = remaining
|
||||
}
|
||||
if toCopy > 0 {
|
||||
copy(dst[:toCopy], c.buf[c.off:c.off+toCopy])
|
||||
dst = dst[toCopy:]
|
||||
remaining -= toCopy
|
||||
c.off += toCopy
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ReKey reinitializes the ChaCha20/XChaCha20 instance with the provided key
|
||||
// and nonce.
|
||||
func (c *Cipher) ReKey(key, nonce []byte) error {
|
||||
if len(key) != KeySize {
|
||||
return ErrInvalidKey
|
||||
}
|
||||
|
||||
switch len(nonce) {
|
||||
case NonceSize:
|
||||
case INonceSize:
|
||||
case XNonceSize:
|
||||
var subkey [KeySize]byte
|
||||
var subnonce [HNonceSize]byte
|
||||
copy(subnonce[:], nonce[0:16])
|
||||
HChaCha(key, &subnonce, &subkey)
|
||||
key = subkey[:]
|
||||
nonce = nonce[16:24]
|
||||
defer func() {
|
||||
for i := range subkey {
|
||||
subkey[i] = 0
|
||||
}
|
||||
}()
|
||||
default:
|
||||
return ErrInvalidNonce
|
||||
}
|
||||
|
||||
c.Reset()
|
||||
c.state[0] = sigma0
|
||||
c.state[1] = sigma1
|
||||
c.state[2] = sigma2
|
||||
c.state[3] = sigma3
|
||||
c.state[4] = binary.LittleEndian.Uint32(key[0:4])
|
||||
c.state[5] = binary.LittleEndian.Uint32(key[4:8])
|
||||
c.state[6] = binary.LittleEndian.Uint32(key[8:12])
|
||||
c.state[7] = binary.LittleEndian.Uint32(key[12:16])
|
||||
c.state[8] = binary.LittleEndian.Uint32(key[16:20])
|
||||
c.state[9] = binary.LittleEndian.Uint32(key[20:24])
|
||||
c.state[10] = binary.LittleEndian.Uint32(key[24:28])
|
||||
c.state[11] = binary.LittleEndian.Uint32(key[28:32])
|
||||
c.state[12] = 0
|
||||
if len(nonce) == INonceSize {
|
||||
c.state[13] = binary.LittleEndian.Uint32(nonce[0:4])
|
||||
c.state[14] = binary.LittleEndian.Uint32(nonce[4:8])
|
||||
c.state[15] = binary.LittleEndian.Uint32(nonce[8:12])
|
||||
c.ietf = true
|
||||
} else {
|
||||
c.state[13] = 0
|
||||
c.state[14] = binary.LittleEndian.Uint32(nonce[0:4])
|
||||
c.state[15] = binary.LittleEndian.Uint32(nonce[4:8])
|
||||
c.ietf = false
|
||||
}
|
||||
c.off = BlockSize
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
// Seek sets the block counter to a given offset.
|
||||
func (c *Cipher) Seek(blockCounter uint64) error {
|
||||
if c.ietf {
|
||||
if blockCounter > math.MaxUint32 {
|
||||
return ErrInvalidCounter
|
||||
}
|
||||
c.state[12] = uint32(blockCounter)
|
||||
} else {
|
||||
c.state[12] = uint32(blockCounter)
|
||||
c.state[13] = uint32(blockCounter >> 32)
|
||||
}
|
||||
c.off = BlockSize
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewCipher returns a new ChaCha20/XChaCha20 instance.
|
||||
func NewCipher(key, nonce []byte) (*Cipher, error) {
|
||||
c := new(Cipher)
|
||||
if err := c.ReKey(key, nonce); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return c, nil
|
||||
}
|
||||
|
||||
// HChaCha is the HChaCha20 hash function used to make XChaCha.
|
||||
func HChaCha(key []byte, nonce *[HNonceSize]byte, out *[32]byte) {
|
||||
var x [stateSize]uint32 // Last 4 slots unused, sigma hardcoded.
|
||||
x[0] = binary.LittleEndian.Uint32(key[0:4])
|
||||
x[1] = binary.LittleEndian.Uint32(key[4:8])
|
||||
x[2] = binary.LittleEndian.Uint32(key[8:12])
|
||||
x[3] = binary.LittleEndian.Uint32(key[12:16])
|
||||
x[4] = binary.LittleEndian.Uint32(key[16:20])
|
||||
x[5] = binary.LittleEndian.Uint32(key[20:24])
|
||||
x[6] = binary.LittleEndian.Uint32(key[24:28])
|
||||
x[7] = binary.LittleEndian.Uint32(key[28:32])
|
||||
x[8] = binary.LittleEndian.Uint32(nonce[0:4])
|
||||
x[9] = binary.LittleEndian.Uint32(nonce[4:8])
|
||||
x[10] = binary.LittleEndian.Uint32(nonce[8:12])
|
||||
x[11] = binary.LittleEndian.Uint32(nonce[12:16])
|
||||
hChaChaRef(&x, out)
|
||||
}
|
||||
|
||||
func init() {
|
||||
switch runtime.GOARCH {
|
||||
case "386", "amd64":
|
||||
// Abuse unsafe to skip calling binary.LittleEndian.PutUint32
|
||||
// in the critical path. This is a big boost on systems that are
|
||||
// little endian and not overly picky about alignment.
|
||||
useUnsafe = true
|
||||
}
|
||||
}
|
||||
|
||||
var _ cipher.Stream = (*Cipher)(nil)
|
||||
95
vendor/github.com/wg/ecies/vendor/schwanenlied.me/yawning/chacha20/chacha20_amd64.go
generated
vendored
Normal file
95
vendor/github.com/wg/ecies/vendor/schwanenlied.me/yawning/chacha20/chacha20_amd64.go
generated
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
// chacha20_amd64.go - AMD64 optimized chacha20.
|
||||
//
|
||||
// To the extent possible under law, Yawning Angel has waived all copyright
|
||||
// and related or neighboring rights to chacha20, using the Creative
|
||||
// Commons "CC0" public domain dedication. See LICENSE or
|
||||
// <http://creativecommons.org/publicdomain/zero/1.0/> for full details.
|
||||
|
||||
// +build amd64,!gccgo,!appengine
|
||||
|
||||
package chacha20
|
||||
|
||||
import (
|
||||
"math"
|
||||
)
|
||||
|
||||
var usingAVX2 = false
|
||||
|
||||
func blocksAmd64SSE2(x *uint32, inp, outp *byte, nrBlocks uint)
|
||||
|
||||
func blocksAmd64AVX2(x *uint32, inp, outp *byte, nrBlocks uint)
|
||||
|
||||
func cpuidAmd64(cpuidParams *uint32)
|
||||
|
||||
func xgetbv0Amd64(xcrVec *uint32)
|
||||
|
||||
func blocksAmd64(x *[stateSize]uint32, in []byte, out []byte, nrBlocks int, isIetf bool) {
|
||||
// Probably unneeded, but stating this explicitly simplifies the assembly.
|
||||
if nrBlocks == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
if isIetf {
|
||||
var totalBlocks uint64
|
||||
totalBlocks = uint64(x[8]) + uint64(nrBlocks)
|
||||
if totalBlocks > math.MaxUint32 {
|
||||
panic("chacha20: Exceeded keystream per nonce limit")
|
||||
}
|
||||
}
|
||||
|
||||
if in == nil {
|
||||
for i := range out {
|
||||
out[i] = 0
|
||||
}
|
||||
in = out
|
||||
}
|
||||
|
||||
// Pointless to call the AVX2 code for just a single block, since half of
|
||||
// the output gets discarded...
|
||||
if usingAVX2 && nrBlocks > 1 {
|
||||
blocksAmd64AVX2(&x[0], &in[0], &out[0], uint(nrBlocks))
|
||||
} else {
|
||||
blocksAmd64SSE2(&x[0], &in[0], &out[0], uint(nrBlocks))
|
||||
}
|
||||
}
|
||||
|
||||
func supportsAVX2() bool {
|
||||
// https://software.intel.com/en-us/articles/how-to-detect-new-instruction-support-in-the-4th-generation-intel-core-processor-family
|
||||
const (
|
||||
osXsaveBit = 1 << 27
|
||||
avx2Bit = 1 << 5
|
||||
)
|
||||
|
||||
// Check to see if CPUID actually supports the leaf that indicates AVX2.
|
||||
// CPUID.(EAX=0H, ECX=0H) >= 7
|
||||
regs := [4]uint32{0x00}
|
||||
cpuidAmd64(®s[0])
|
||||
if regs[0] < 7 {
|
||||
return false
|
||||
}
|
||||
|
||||
// Check to see if the OS knows how to save/restore XMM/YMM state.
|
||||
// CPUID.(EAX=01H, ECX=0H):ECX.OSXSAVE[bit 27]==1
|
||||
regs = [4]uint32{0x01}
|
||||
cpuidAmd64(®s[0])
|
||||
if regs[2]&osXsaveBit == 0 {
|
||||
return false
|
||||
}
|
||||
xcrRegs := [2]uint32{}
|
||||
xgetbv0Amd64(&xcrRegs[0])
|
||||
if xcrRegs[0]&6 != 6 {
|
||||
return false
|
||||
}
|
||||
|
||||
// Check for AVX2 support.
|
||||
// CPUID.(EAX=07H, ECX=0H):EBX.AVX2[bit 5]==1
|
||||
regs = [4]uint32{0x07}
|
||||
cpuidAmd64(®s[0])
|
||||
return regs[1]&avx2Bit != 0
|
||||
}
|
||||
|
||||
func init() {
|
||||
blocksFn = blocksAmd64
|
||||
usingVectors = true
|
||||
usingAVX2 = supportsAVX2()
|
||||
}
|
||||
1303
vendor/github.com/wg/ecies/vendor/schwanenlied.me/yawning/chacha20/chacha20_amd64.py
generated
vendored
Normal file
1303
vendor/github.com/wg/ecies/vendor/schwanenlied.me/yawning/chacha20/chacha20_amd64.py
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1187
vendor/github.com/wg/ecies/vendor/schwanenlied.me/yawning/chacha20/chacha20_amd64.s
generated
vendored
Normal file
1187
vendor/github.com/wg/ecies/vendor/schwanenlied.me/yawning/chacha20/chacha20_amd64.s
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
392
vendor/github.com/wg/ecies/vendor/schwanenlied.me/yawning/chacha20/chacha20_ref.go
generated
vendored
Normal file
392
vendor/github.com/wg/ecies/vendor/schwanenlied.me/yawning/chacha20/chacha20_ref.go
generated
vendored
Normal file
@@ -0,0 +1,392 @@
|
||||
// chacha20_ref.go - Reference ChaCha20.
|
||||
//
|
||||
// To the extent possible under law, Yawning Angel has waived all copyright
|
||||
// and related or neighboring rights to chacha20, using the Creative
|
||||
// Commons "CC0" public domain dedication. See LICENSE or
|
||||
// <http://creativecommons.org/publicdomain/zero/1.0/> for full details.
|
||||
|
||||
package chacha20
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"math"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func blocksRef(x *[stateSize]uint32, in []byte, out []byte, nrBlocks int, isIetf bool) {
|
||||
if isIetf {
|
||||
var totalBlocks uint64
|
||||
totalBlocks = uint64(x[8]) + uint64(nrBlocks)
|
||||
if totalBlocks > math.MaxUint32 {
|
||||
panic("chacha20: Exceeded keystream per nonce limit")
|
||||
}
|
||||
}
|
||||
|
||||
// This routine ignores x[0]...x[4] in favor the const values since it's
|
||||
// ever so slightly faster.
|
||||
|
||||
for n := 0; n < nrBlocks; n++ {
|
||||
x0, x1, x2, x3 := sigma0, sigma1, sigma2, sigma3
|
||||
x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15 := x[4], x[5], x[6], x[7], x[8], x[9], x[10], x[11], x[12], x[13], x[14], x[15]
|
||||
|
||||
for i := chachaRounds; i > 0; i -= 2 {
|
||||
// quarterround(x, 0, 4, 8, 12)
|
||||
x0 += x4
|
||||
x12 ^= x0
|
||||
x12 = (x12 << 16) | (x12 >> 16)
|
||||
x8 += x12
|
||||
x4 ^= x8
|
||||
x4 = (x4 << 12) | (x4 >> 20)
|
||||
x0 += x4
|
||||
x12 ^= x0
|
||||
x12 = (x12 << 8) | (x12 >> 24)
|
||||
x8 += x12
|
||||
x4 ^= x8
|
||||
x4 = (x4 << 7) | (x4 >> 25)
|
||||
|
||||
// quarterround(x, 1, 5, 9, 13)
|
||||
x1 += x5
|
||||
x13 ^= x1
|
||||
x13 = (x13 << 16) | (x13 >> 16)
|
||||
x9 += x13
|
||||
x5 ^= x9
|
||||
x5 = (x5 << 12) | (x5 >> 20)
|
||||
x1 += x5
|
||||
x13 ^= x1
|
||||
x13 = (x13 << 8) | (x13 >> 24)
|
||||
x9 += x13
|
||||
x5 ^= x9
|
||||
x5 = (x5 << 7) | (x5 >> 25)
|
||||
|
||||
// quarterround(x, 2, 6, 10, 14)
|
||||
x2 += x6
|
||||
x14 ^= x2
|
||||
x14 = (x14 << 16) | (x14 >> 16)
|
||||
x10 += x14
|
||||
x6 ^= x10
|
||||
x6 = (x6 << 12) | (x6 >> 20)
|
||||
x2 += x6
|
||||
x14 ^= x2
|
||||
x14 = (x14 << 8) | (x14 >> 24)
|
||||
x10 += x14
|
||||
x6 ^= x10
|
||||
x6 = (x6 << 7) | (x6 >> 25)
|
||||
|
||||
// quarterround(x, 3, 7, 11, 15)
|
||||
x3 += x7
|
||||
x15 ^= x3
|
||||
x15 = (x15 << 16) | (x15 >> 16)
|
||||
x11 += x15
|
||||
x7 ^= x11
|
||||
x7 = (x7 << 12) | (x7 >> 20)
|
||||
x3 += x7
|
||||
x15 ^= x3
|
||||
x15 = (x15 << 8) | (x15 >> 24)
|
||||
x11 += x15
|
||||
x7 ^= x11
|
||||
x7 = (x7 << 7) | (x7 >> 25)
|
||||
|
||||
// quarterround(x, 0, 5, 10, 15)
|
||||
x0 += x5
|
||||
x15 ^= x0
|
||||
x15 = (x15 << 16) | (x15 >> 16)
|
||||
x10 += x15
|
||||
x5 ^= x10
|
||||
x5 = (x5 << 12) | (x5 >> 20)
|
||||
x0 += x5
|
||||
x15 ^= x0
|
||||
x15 = (x15 << 8) | (x15 >> 24)
|
||||
x10 += x15
|
||||
x5 ^= x10
|
||||
x5 = (x5 << 7) | (x5 >> 25)
|
||||
|
||||
// quarterround(x, 1, 6, 11, 12)
|
||||
x1 += x6
|
||||
x12 ^= x1
|
||||
x12 = (x12 << 16) | (x12 >> 16)
|
||||
x11 += x12
|
||||
x6 ^= x11
|
||||
x6 = (x6 << 12) | (x6 >> 20)
|
||||
x1 += x6
|
||||
x12 ^= x1
|
||||
x12 = (x12 << 8) | (x12 >> 24)
|
||||
x11 += x12
|
||||
x6 ^= x11
|
||||
x6 = (x6 << 7) | (x6 >> 25)
|
||||
|
||||
// quarterround(x, 2, 7, 8, 13)
|
||||
x2 += x7
|
||||
x13 ^= x2
|
||||
x13 = (x13 << 16) | (x13 >> 16)
|
||||
x8 += x13
|
||||
x7 ^= x8
|
||||
x7 = (x7 << 12) | (x7 >> 20)
|
||||
x2 += x7
|
||||
x13 ^= x2
|
||||
x13 = (x13 << 8) | (x13 >> 24)
|
||||
x8 += x13
|
||||
x7 ^= x8
|
||||
x7 = (x7 << 7) | (x7 >> 25)
|
||||
|
||||
// quarterround(x, 3, 4, 9, 14)
|
||||
x3 += x4
|
||||
x14 ^= x3
|
||||
x14 = (x14 << 16) | (x14 >> 16)
|
||||
x9 += x14
|
||||
x4 ^= x9
|
||||
x4 = (x4 << 12) | (x4 >> 20)
|
||||
x3 += x4
|
||||
x14 ^= x3
|
||||
x14 = (x14 << 8) | (x14 >> 24)
|
||||
x9 += x14
|
||||
x4 ^= x9
|
||||
x4 = (x4 << 7) | (x4 >> 25)
|
||||
}
|
||||
|
||||
// On amd64 at least, this is a rather big boost.
|
||||
if useUnsafe {
|
||||
if in != nil {
|
||||
inArr := (*[16]uint32)(unsafe.Pointer(&in[n*BlockSize]))
|
||||
outArr := (*[16]uint32)(unsafe.Pointer(&out[n*BlockSize]))
|
||||
outArr[0] = inArr[0] ^ (x0 + sigma0)
|
||||
outArr[1] = inArr[1] ^ (x1 + sigma1)
|
||||
outArr[2] = inArr[2] ^ (x2 + sigma2)
|
||||
outArr[3] = inArr[3] ^ (x3 + sigma3)
|
||||
outArr[4] = inArr[4] ^ (x4 + x[4])
|
||||
outArr[5] = inArr[5] ^ (x5 + x[5])
|
||||
outArr[6] = inArr[6] ^ (x6 + x[6])
|
||||
outArr[7] = inArr[7] ^ (x7 + x[7])
|
||||
outArr[8] = inArr[8] ^ (x8 + x[8])
|
||||
outArr[9] = inArr[9] ^ (x9 + x[9])
|
||||
outArr[10] = inArr[10] ^ (x10 + x[10])
|
||||
outArr[11] = inArr[11] ^ (x11 + x[11])
|
||||
outArr[12] = inArr[12] ^ (x12 + x[12])
|
||||
outArr[13] = inArr[13] ^ (x13 + x[13])
|
||||
outArr[14] = inArr[14] ^ (x14 + x[14])
|
||||
outArr[15] = inArr[15] ^ (x15 + x[15])
|
||||
} else {
|
||||
outArr := (*[16]uint32)(unsafe.Pointer(&out[n*BlockSize]))
|
||||
outArr[0] = x0 + sigma0
|
||||
outArr[1] = x1 + sigma1
|
||||
outArr[2] = x2 + sigma2
|
||||
outArr[3] = x3 + sigma3
|
||||
outArr[4] = x4 + x[4]
|
||||
outArr[5] = x5 + x[5]
|
||||
outArr[6] = x6 + x[6]
|
||||
outArr[7] = x7 + x[7]
|
||||
outArr[8] = x8 + x[8]
|
||||
outArr[9] = x9 + x[9]
|
||||
outArr[10] = x10 + x[10]
|
||||
outArr[11] = x11 + x[11]
|
||||
outArr[12] = x12 + x[12]
|
||||
outArr[13] = x13 + x[13]
|
||||
outArr[14] = x14 + x[14]
|
||||
outArr[15] = x15 + x[15]
|
||||
}
|
||||
} else {
|
||||
// Slow path, either the architecture cares about alignment, or is not little endian.
|
||||
x0 += sigma0
|
||||
x1 += sigma1
|
||||
x2 += sigma2
|
||||
x3 += sigma3
|
||||
x4 += x[4]
|
||||
x5 += x[5]
|
||||
x6 += x[6]
|
||||
x7 += x[7]
|
||||
x8 += x[8]
|
||||
x9 += x[9]
|
||||
x10 += x[10]
|
||||
x11 += x[11]
|
||||
x12 += x[12]
|
||||
x13 += x[13]
|
||||
x14 += x[14]
|
||||
x15 += x[15]
|
||||
if in != nil {
|
||||
binary.LittleEndian.PutUint32(out[0:4], binary.LittleEndian.Uint32(in[0:4])^x0)
|
||||
binary.LittleEndian.PutUint32(out[4:8], binary.LittleEndian.Uint32(in[4:8])^x1)
|
||||
binary.LittleEndian.PutUint32(out[8:12], binary.LittleEndian.Uint32(in[8:12])^x2)
|
||||
binary.LittleEndian.PutUint32(out[12:16], binary.LittleEndian.Uint32(in[12:16])^x3)
|
||||
binary.LittleEndian.PutUint32(out[16:20], binary.LittleEndian.Uint32(in[16:20])^x4)
|
||||
binary.LittleEndian.PutUint32(out[20:24], binary.LittleEndian.Uint32(in[20:24])^x5)
|
||||
binary.LittleEndian.PutUint32(out[24:28], binary.LittleEndian.Uint32(in[24:28])^x6)
|
||||
binary.LittleEndian.PutUint32(out[28:32], binary.LittleEndian.Uint32(in[28:32])^x7)
|
||||
binary.LittleEndian.PutUint32(out[32:36], binary.LittleEndian.Uint32(in[32:36])^x8)
|
||||
binary.LittleEndian.PutUint32(out[36:40], binary.LittleEndian.Uint32(in[36:40])^x9)
|
||||
binary.LittleEndian.PutUint32(out[40:44], binary.LittleEndian.Uint32(in[40:44])^x10)
|
||||
binary.LittleEndian.PutUint32(out[44:48], binary.LittleEndian.Uint32(in[44:48])^x11)
|
||||
binary.LittleEndian.PutUint32(out[48:52], binary.LittleEndian.Uint32(in[48:52])^x12)
|
||||
binary.LittleEndian.PutUint32(out[52:56], binary.LittleEndian.Uint32(in[52:56])^x13)
|
||||
binary.LittleEndian.PutUint32(out[56:60], binary.LittleEndian.Uint32(in[56:60])^x14)
|
||||
binary.LittleEndian.PutUint32(out[60:64], binary.LittleEndian.Uint32(in[60:64])^x15)
|
||||
in = in[BlockSize:]
|
||||
} else {
|
||||
binary.LittleEndian.PutUint32(out[0:4], x0)
|
||||
binary.LittleEndian.PutUint32(out[4:8], x1)
|
||||
binary.LittleEndian.PutUint32(out[8:12], x2)
|
||||
binary.LittleEndian.PutUint32(out[12:16], x3)
|
||||
binary.LittleEndian.PutUint32(out[16:20], x4)
|
||||
binary.LittleEndian.PutUint32(out[20:24], x5)
|
||||
binary.LittleEndian.PutUint32(out[24:28], x6)
|
||||
binary.LittleEndian.PutUint32(out[28:32], x7)
|
||||
binary.LittleEndian.PutUint32(out[32:36], x8)
|
||||
binary.LittleEndian.PutUint32(out[36:40], x9)
|
||||
binary.LittleEndian.PutUint32(out[40:44], x10)
|
||||
binary.LittleEndian.PutUint32(out[44:48], x11)
|
||||
binary.LittleEndian.PutUint32(out[48:52], x12)
|
||||
binary.LittleEndian.PutUint32(out[52:56], x13)
|
||||
binary.LittleEndian.PutUint32(out[56:60], x14)
|
||||
binary.LittleEndian.PutUint32(out[60:64], x15)
|
||||
}
|
||||
out = out[BlockSize:]
|
||||
}
|
||||
|
||||
// Stoping at 2^70 bytes per nonce is the user's responsibility.
|
||||
ctr := uint64(x[13])<<32 | uint64(x[12])
|
||||
ctr++
|
||||
x[12] = uint32(ctr)
|
||||
x[13] = uint32(ctr >> 32)
|
||||
}
|
||||
}
|
||||
|
||||
func hChaChaRef(x *[stateSize]uint32, out *[32]byte) {
|
||||
x0, x1, x2, x3 := sigma0, sigma1, sigma2, sigma3
|
||||
x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15 := x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], x[8], x[9], x[10], x[11]
|
||||
|
||||
for i := chachaRounds; i > 0; i -= 2 {
|
||||
// quarterround(x, 0, 4, 8, 12)
|
||||
x0 += x4
|
||||
x12 ^= x0
|
||||
x12 = (x12 << 16) | (x12 >> 16)
|
||||
x8 += x12
|
||||
x4 ^= x8
|
||||
x4 = (x4 << 12) | (x4 >> 20)
|
||||
x0 += x4
|
||||
x12 ^= x0
|
||||
x12 = (x12 << 8) | (x12 >> 24)
|
||||
x8 += x12
|
||||
x4 ^= x8
|
||||
x4 = (x4 << 7) | (x4 >> 25)
|
||||
|
||||
// quarterround(x, 1, 5, 9, 13)
|
||||
x1 += x5
|
||||
x13 ^= x1
|
||||
x13 = (x13 << 16) | (x13 >> 16)
|
||||
x9 += x13
|
||||
x5 ^= x9
|
||||
x5 = (x5 << 12) | (x5 >> 20)
|
||||
x1 += x5
|
||||
x13 ^= x1
|
||||
x13 = (x13 << 8) | (x13 >> 24)
|
||||
x9 += x13
|
||||
x5 ^= x9
|
||||
x5 = (x5 << 7) | (x5 >> 25)
|
||||
|
||||
// quarterround(x, 2, 6, 10, 14)
|
||||
x2 += x6
|
||||
x14 ^= x2
|
||||
x14 = (x14 << 16) | (x14 >> 16)
|
||||
x10 += x14
|
||||
x6 ^= x10
|
||||
x6 = (x6 << 12) | (x6 >> 20)
|
||||
x2 += x6
|
||||
x14 ^= x2
|
||||
x14 = (x14 << 8) | (x14 >> 24)
|
||||
x10 += x14
|
||||
x6 ^= x10
|
||||
x6 = (x6 << 7) | (x6 >> 25)
|
||||
|
||||
// quarterround(x, 3, 7, 11, 15)
|
||||
x3 += x7
|
||||
x15 ^= x3
|
||||
x15 = (x15 << 16) | (x15 >> 16)
|
||||
x11 += x15
|
||||
x7 ^= x11
|
||||
x7 = (x7 << 12) | (x7 >> 20)
|
||||
x3 += x7
|
||||
x15 ^= x3
|
||||
x15 = (x15 << 8) | (x15 >> 24)
|
||||
x11 += x15
|
||||
x7 ^= x11
|
||||
x7 = (x7 << 7) | (x7 >> 25)
|
||||
|
||||
// quarterround(x, 0, 5, 10, 15)
|
||||
x0 += x5
|
||||
x15 ^= x0
|
||||
x15 = (x15 << 16) | (x15 >> 16)
|
||||
x10 += x15
|
||||
x5 ^= x10
|
||||
x5 = (x5 << 12) | (x5 >> 20)
|
||||
x0 += x5
|
||||
x15 ^= x0
|
||||
x15 = (x15 << 8) | (x15 >> 24)
|
||||
x10 += x15
|
||||
x5 ^= x10
|
||||
x5 = (x5 << 7) | (x5 >> 25)
|
||||
|
||||
// quarterround(x, 1, 6, 11, 12)
|
||||
x1 += x6
|
||||
x12 ^= x1
|
||||
x12 = (x12 << 16) | (x12 >> 16)
|
||||
x11 += x12
|
||||
x6 ^= x11
|
||||
x6 = (x6 << 12) | (x6 >> 20)
|
||||
x1 += x6
|
||||
x12 ^= x1
|
||||
x12 = (x12 << 8) | (x12 >> 24)
|
||||
x11 += x12
|
||||
x6 ^= x11
|
||||
x6 = (x6 << 7) | (x6 >> 25)
|
||||
|
||||
// quarterround(x, 2, 7, 8, 13)
|
||||
x2 += x7
|
||||
x13 ^= x2
|
||||
x13 = (x13 << 16) | (x13 >> 16)
|
||||
x8 += x13
|
||||
x7 ^= x8
|
||||
x7 = (x7 << 12) | (x7 >> 20)
|
||||
x2 += x7
|
||||
x13 ^= x2
|
||||
x13 = (x13 << 8) | (x13 >> 24)
|
||||
x8 += x13
|
||||
x7 ^= x8
|
||||
x7 = (x7 << 7) | (x7 >> 25)
|
||||
|
||||
// quarterround(x, 3, 4, 9, 14)
|
||||
x3 += x4
|
||||
x14 ^= x3
|
||||
x14 = (x14 << 16) | (x14 >> 16)
|
||||
x9 += x14
|
||||
x4 ^= x9
|
||||
x4 = (x4 << 12) | (x4 >> 20)
|
||||
x3 += x4
|
||||
x14 ^= x3
|
||||
x14 = (x14 << 8) | (x14 >> 24)
|
||||
x9 += x14
|
||||
x4 ^= x9
|
||||
x4 = (x4 << 7) | (x4 >> 25)
|
||||
}
|
||||
|
||||
// HChaCha returns x0...x3 | x12...x15, which corresponds to the
|
||||
// indexes of the ChaCha constant and the indexes of the IV.
|
||||
if useUnsafe {
|
||||
outArr := (*[16]uint32)(unsafe.Pointer(&out[0]))
|
||||
outArr[0] = x0
|
||||
outArr[1] = x1
|
||||
outArr[2] = x2
|
||||
outArr[3] = x3
|
||||
outArr[4] = x12
|
||||
outArr[5] = x13
|
||||
outArr[6] = x14
|
||||
outArr[7] = x15
|
||||
} else {
|
||||
binary.LittleEndian.PutUint32(out[0:4], x0)
|
||||
binary.LittleEndian.PutUint32(out[4:8], x1)
|
||||
binary.LittleEndian.PutUint32(out[8:12], x2)
|
||||
binary.LittleEndian.PutUint32(out[12:16], x3)
|
||||
binary.LittleEndian.PutUint32(out[16:20], x12)
|
||||
binary.LittleEndian.PutUint32(out[20:24], x13)
|
||||
binary.LittleEndian.PutUint32(out[24:28], x14)
|
||||
binary.LittleEndian.PutUint32(out[28:32], x15)
|
||||
}
|
||||
return
|
||||
}
|
||||
523
vendor/github.com/wg/ecies/vendor/schwanenlied.me/yawning/chacha20/chacha20_test.go
generated
vendored
Normal file
523
vendor/github.com/wg/ecies/vendor/schwanenlied.me/yawning/chacha20/chacha20_test.go
generated
vendored
Normal file
@@ -0,0 +1,523 @@
|
||||
// chacha20_test.go - ChaCha stream cipher implementation tests.
|
||||
//
|
||||
// To the extent possible under law, Yawning Angel waived all copyright
|
||||
// and related or neighboring rights to chacha20, using the Creative
|
||||
// Commons "CC0" public domain dedication. See LICENSE or
|
||||
// <http://creativecommons.org/publicdomain/zero/1.0/> for full details.
|
||||
|
||||
package chacha20
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// Test vectors taken from:
|
||||
// https://tools.ietf.org/html/draft-strombergson-chacha-test-vectors-01
|
||||
var draftTestVectors = []struct {
|
||||
name string
|
||||
key []byte
|
||||
iv []byte
|
||||
stream []byte
|
||||
seekOffset uint64
|
||||
}{
|
||||
{
|
||||
name: "IETF Draft: TC1: All zero key and IV.",
|
||||
key: []byte{
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
},
|
||||
iv: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
stream: []byte{
|
||||
0x76, 0xb8, 0xe0, 0xad, 0xa0, 0xf1, 0x3d, 0x90,
|
||||
0x40, 0x5d, 0x6a, 0xe5, 0x53, 0x86, 0xbd, 0x28,
|
||||
0xbd, 0xd2, 0x19, 0xb8, 0xa0, 0x8d, 0xed, 0x1a,
|
||||
0xa8, 0x36, 0xef, 0xcc, 0x8b, 0x77, 0x0d, 0xc7,
|
||||
0xda, 0x41, 0x59, 0x7c, 0x51, 0x57, 0x48, 0x8d,
|
||||
0x77, 0x24, 0xe0, 0x3f, 0xb8, 0xd8, 0x4a, 0x37,
|
||||
0x6a, 0x43, 0xb8, 0xf4, 0x15, 0x18, 0xa1, 0x1c,
|
||||
0xc3, 0x87, 0xb6, 0x69, 0xb2, 0xee, 0x65, 0x86,
|
||||
0x9f, 0x07, 0xe7, 0xbe, 0x55, 0x51, 0x38, 0x7a,
|
||||
0x98, 0xba, 0x97, 0x7c, 0x73, 0x2d, 0x08, 0x0d,
|
||||
0xcb, 0x0f, 0x29, 0xa0, 0x48, 0xe3, 0x65, 0x69,
|
||||
0x12, 0xc6, 0x53, 0x3e, 0x32, 0xee, 0x7a, 0xed,
|
||||
0x29, 0xb7, 0x21, 0x76, 0x9c, 0xe6, 0x4e, 0x43,
|
||||
0xd5, 0x71, 0x33, 0xb0, 0x74, 0xd8, 0x39, 0xd5,
|
||||
0x31, 0xed, 0x1f, 0x28, 0x51, 0x0a, 0xfb, 0x45,
|
||||
0xac, 0xe1, 0x0a, 0x1f, 0x4b, 0x79, 0x4d, 0x6f,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "IETF Draft: TC2: Single bit in key set. All zero IV.",
|
||||
key: []byte{
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
},
|
||||
iv: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
stream: []byte{
|
||||
0xc5, 0xd3, 0x0a, 0x7c, 0xe1, 0xec, 0x11, 0x93,
|
||||
0x78, 0xc8, 0x4f, 0x48, 0x7d, 0x77, 0x5a, 0x85,
|
||||
0x42, 0xf1, 0x3e, 0xce, 0x23, 0x8a, 0x94, 0x55,
|
||||
0xe8, 0x22, 0x9e, 0x88, 0x8d, 0xe8, 0x5b, 0xbd,
|
||||
0x29, 0xeb, 0x63, 0xd0, 0xa1, 0x7a, 0x5b, 0x99,
|
||||
0x9b, 0x52, 0xda, 0x22, 0xbe, 0x40, 0x23, 0xeb,
|
||||
0x07, 0x62, 0x0a, 0x54, 0xf6, 0xfa, 0x6a, 0xd8,
|
||||
0x73, 0x7b, 0x71, 0xeb, 0x04, 0x64, 0xda, 0xc0,
|
||||
0x10, 0xf6, 0x56, 0xe6, 0xd1, 0xfd, 0x55, 0x05,
|
||||
0x3e, 0x50, 0xc4, 0x87, 0x5c, 0x99, 0x30, 0xa3,
|
||||
0x3f, 0x6d, 0x02, 0x63, 0xbd, 0x14, 0xdf, 0xd6,
|
||||
0xab, 0x8c, 0x70, 0x52, 0x1c, 0x19, 0x33, 0x8b,
|
||||
0x23, 0x08, 0xb9, 0x5c, 0xf8, 0xd0, 0xbb, 0x7d,
|
||||
0x20, 0x2d, 0x21, 0x02, 0x78, 0x0e, 0xa3, 0x52,
|
||||
0x8f, 0x1c, 0xb4, 0x85, 0x60, 0xf7, 0x6b, 0x20,
|
||||
0xf3, 0x82, 0xb9, 0x42, 0x50, 0x0f, 0xce, 0xac,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "IETF Draft: TC3: Single bit in IV set. All zero key.",
|
||||
key: []byte{
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
},
|
||||
iv: []byte{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
stream: []byte{
|
||||
0xef, 0x3f, 0xdf, 0xd6, 0xc6, 0x15, 0x78, 0xfb,
|
||||
0xf5, 0xcf, 0x35, 0xbd, 0x3d, 0xd3, 0x3b, 0x80,
|
||||
0x09, 0x63, 0x16, 0x34, 0xd2, 0x1e, 0x42, 0xac,
|
||||
0x33, 0x96, 0x0b, 0xd1, 0x38, 0xe5, 0x0d, 0x32,
|
||||
0x11, 0x1e, 0x4c, 0xaf, 0x23, 0x7e, 0xe5, 0x3c,
|
||||
0xa8, 0xad, 0x64, 0x26, 0x19, 0x4a, 0x88, 0x54,
|
||||
0x5d, 0xdc, 0x49, 0x7a, 0x0b, 0x46, 0x6e, 0x7d,
|
||||
0x6b, 0xbd, 0xb0, 0x04, 0x1b, 0x2f, 0x58, 0x6b,
|
||||
0x53, 0x05, 0xe5, 0xe4, 0x4a, 0xff, 0x19, 0xb2,
|
||||
0x35, 0x93, 0x61, 0x44, 0x67, 0x5e, 0xfb, 0xe4,
|
||||
0x40, 0x9e, 0xb7, 0xe8, 0xe5, 0xf1, 0x43, 0x0f,
|
||||
0x5f, 0x58, 0x36, 0xae, 0xb4, 0x9b, 0xb5, 0x32,
|
||||
0x8b, 0x01, 0x7c, 0x4b, 0x9d, 0xc1, 0x1f, 0x8a,
|
||||
0x03, 0x86, 0x3f, 0xa8, 0x03, 0xdc, 0x71, 0xd5,
|
||||
0x72, 0x6b, 0x2b, 0x6b, 0x31, 0xaa, 0x32, 0x70,
|
||||
0x8a, 0xfe, 0x5a, 0xf1, 0xd6, 0xb6, 0x90, 0x58,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "IETF Draft: TC4: All bits in key and IV are set.",
|
||||
key: []byte{
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
},
|
||||
iv: []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
|
||||
stream: []byte{
|
||||
0xd9, 0xbf, 0x3f, 0x6b, 0xce, 0x6e, 0xd0, 0xb5,
|
||||
0x42, 0x54, 0x55, 0x77, 0x67, 0xfb, 0x57, 0x44,
|
||||
0x3d, 0xd4, 0x77, 0x89, 0x11, 0xb6, 0x06, 0x05,
|
||||
0x5c, 0x39, 0xcc, 0x25, 0xe6, 0x74, 0xb8, 0x36,
|
||||
0x3f, 0xea, 0xbc, 0x57, 0xfd, 0xe5, 0x4f, 0x79,
|
||||
0x0c, 0x52, 0xc8, 0xae, 0x43, 0x24, 0x0b, 0x79,
|
||||
0xd4, 0x90, 0x42, 0xb7, 0x77, 0xbf, 0xd6, 0xcb,
|
||||
0x80, 0xe9, 0x31, 0x27, 0x0b, 0x7f, 0x50, 0xeb,
|
||||
0x5b, 0xac, 0x2a, 0xcd, 0x86, 0xa8, 0x36, 0xc5,
|
||||
0xdc, 0x98, 0xc1, 0x16, 0xc1, 0x21, 0x7e, 0xc3,
|
||||
0x1d, 0x3a, 0x63, 0xa9, 0x45, 0x13, 0x19, 0xf0,
|
||||
0x97, 0xf3, 0xb4, 0xd6, 0xda, 0xb0, 0x77, 0x87,
|
||||
0x19, 0x47, 0x7d, 0x24, 0xd2, 0x4b, 0x40, 0x3a,
|
||||
0x12, 0x24, 0x1d, 0x7c, 0xca, 0x06, 0x4f, 0x79,
|
||||
0x0f, 0x1d, 0x51, 0xcc, 0xaf, 0xf6, 0xb1, 0x66,
|
||||
0x7d, 0x4b, 0xbc, 0xa1, 0x95, 0x8c, 0x43, 0x06,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "IETF Draft: TC5: Every even bit set in key and IV.",
|
||||
key: []byte{
|
||||
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
|
||||
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
|
||||
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
|
||||
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
|
||||
},
|
||||
iv: []byte{0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55},
|
||||
stream: []byte{
|
||||
0xbe, 0xa9, 0x41, 0x1a, 0xa4, 0x53, 0xc5, 0x43,
|
||||
0x4a, 0x5a, 0xe8, 0xc9, 0x28, 0x62, 0xf5, 0x64,
|
||||
0x39, 0x68, 0x55, 0xa9, 0xea, 0x6e, 0x22, 0xd6,
|
||||
0xd3, 0xb5, 0x0a, 0xe1, 0xb3, 0x66, 0x33, 0x11,
|
||||
0xa4, 0xa3, 0x60, 0x6c, 0x67, 0x1d, 0x60, 0x5c,
|
||||
0xe1, 0x6c, 0x3a, 0xec, 0xe8, 0xe6, 0x1e, 0xa1,
|
||||
0x45, 0xc5, 0x97, 0x75, 0x01, 0x7b, 0xee, 0x2f,
|
||||
0xa6, 0xf8, 0x8a, 0xfc, 0x75, 0x80, 0x69, 0xf7,
|
||||
0xe0, 0xb8, 0xf6, 0x76, 0xe6, 0x44, 0x21, 0x6f,
|
||||
0x4d, 0x2a, 0x34, 0x22, 0xd7, 0xfa, 0x36, 0xc6,
|
||||
0xc4, 0x93, 0x1a, 0xca, 0x95, 0x0e, 0x9d, 0xa4,
|
||||
0x27, 0x88, 0xe6, 0xd0, 0xb6, 0xd1, 0xcd, 0x83,
|
||||
0x8e, 0xf6, 0x52, 0xe9, 0x7b, 0x14, 0x5b, 0x14,
|
||||
0x87, 0x1e, 0xae, 0x6c, 0x68, 0x04, 0xc7, 0x00,
|
||||
0x4d, 0xb5, 0xac, 0x2f, 0xce, 0x4c, 0x68, 0xc7,
|
||||
0x26, 0xd0, 0x04, 0xb1, 0x0f, 0xca, 0xba, 0x86,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "IETF Draft: TC6: Every odd bit set in key and IV.",
|
||||
key: []byte{
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
},
|
||||
iv: []byte{0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa},
|
||||
stream: []byte{
|
||||
0x9a, 0xa2, 0xa9, 0xf6, 0x56, 0xef, 0xde, 0x5a,
|
||||
0xa7, 0x59, 0x1c, 0x5f, 0xed, 0x4b, 0x35, 0xae,
|
||||
0xa2, 0x89, 0x5d, 0xec, 0x7c, 0xb4, 0x54, 0x3b,
|
||||
0x9e, 0x9f, 0x21, 0xf5, 0xe7, 0xbc, 0xbc, 0xf3,
|
||||
0xc4, 0x3c, 0x74, 0x8a, 0x97, 0x08, 0x88, 0xf8,
|
||||
0x24, 0x83, 0x93, 0xa0, 0x9d, 0x43, 0xe0, 0xb7,
|
||||
0xe1, 0x64, 0xbc, 0x4d, 0x0b, 0x0f, 0xb2, 0x40,
|
||||
0xa2, 0xd7, 0x21, 0x15, 0xc4, 0x80, 0x89, 0x06,
|
||||
0x72, 0x18, 0x44, 0x89, 0x44, 0x05, 0x45, 0xd0,
|
||||
0x21, 0xd9, 0x7e, 0xf6, 0xb6, 0x93, 0xdf, 0xe5,
|
||||
0xb2, 0xc1, 0x32, 0xd4, 0x7e, 0x6f, 0x04, 0x1c,
|
||||
0x90, 0x63, 0x65, 0x1f, 0x96, 0xb6, 0x23, 0xe6,
|
||||
0x2a, 0x11, 0x99, 0x9a, 0x23, 0xb6, 0xf7, 0xc4,
|
||||
0x61, 0xb2, 0x15, 0x30, 0x26, 0xad, 0x5e, 0x86,
|
||||
0x6a, 0x2e, 0x59, 0x7e, 0xd0, 0x7b, 0x84, 0x01,
|
||||
0xde, 0xc6, 0x3a, 0x09, 0x34, 0xc6, 0xb2, 0xa9,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "IETF Draft: TC7: Sequence patterns in key and IV.",
|
||||
key: []byte{
|
||||
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
|
||||
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
|
||||
0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88,
|
||||
0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0x00,
|
||||
},
|
||||
iv: []byte{0x0f, 0x1e, 0x2d, 0x3c, 0x4b, 0x5a, 0x69, 0x78},
|
||||
stream: []byte{
|
||||
0x9f, 0xad, 0xf4, 0x09, 0xc0, 0x08, 0x11, 0xd0,
|
||||
0x04, 0x31, 0xd6, 0x7e, 0xfb, 0xd8, 0x8f, 0xba,
|
||||
0x59, 0x21, 0x8d, 0x5d, 0x67, 0x08, 0xb1, 0xd6,
|
||||
0x85, 0x86, 0x3f, 0xab, 0xbb, 0x0e, 0x96, 0x1e,
|
||||
0xea, 0x48, 0x0f, 0xd6, 0xfb, 0x53, 0x2b, 0xfd,
|
||||
0x49, 0x4b, 0x21, 0x51, 0x01, 0x50, 0x57, 0x42,
|
||||
0x3a, 0xb6, 0x0a, 0x63, 0xfe, 0x4f, 0x55, 0xf7,
|
||||
0xa2, 0x12, 0xe2, 0x16, 0x7c, 0xca, 0xb9, 0x31,
|
||||
0xfb, 0xfd, 0x29, 0xcf, 0x7b, 0xc1, 0xd2, 0x79,
|
||||
0xed, 0xdf, 0x25, 0xdd, 0x31, 0x6b, 0xb8, 0x84,
|
||||
0x3d, 0x6e, 0xde, 0xe0, 0xbd, 0x1e, 0xf1, 0x21,
|
||||
0xd1, 0x2f, 0xa1, 0x7c, 0xbc, 0x2c, 0x57, 0x4c,
|
||||
0xcc, 0xab, 0x5e, 0x27, 0x51, 0x67, 0xb0, 0x8b,
|
||||
0xd6, 0x86, 0xf8, 0xa0, 0x9d, 0xf8, 0x7e, 0xc3,
|
||||
0xff, 0xb3, 0x53, 0x61, 0xb9, 0x4e, 0xbf, 0xa1,
|
||||
0x3f, 0xec, 0x0e, 0x48, 0x89, 0xd1, 0x8d, 0xa5,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "IETF Draft: TC8: key: 'All your base are belong to us!, IV: 'IETF2013'",
|
||||
key: []byte{
|
||||
0xc4, 0x6e, 0xc1, 0xb1, 0x8c, 0xe8, 0xa8, 0x78,
|
||||
0x72, 0x5a, 0x37, 0xe7, 0x80, 0xdf, 0xb7, 0x35,
|
||||
0x1f, 0x68, 0xed, 0x2e, 0x19, 0x4c, 0x79, 0xfb,
|
||||
0xc6, 0xae, 0xbe, 0xe1, 0xa6, 0x67, 0x97, 0x5d,
|
||||
},
|
||||
iv: []byte{0x1a, 0xda, 0x31, 0xd5, 0xcf, 0x68, 0x82, 0x21},
|
||||
stream: []byte{
|
||||
0xf6, 0x3a, 0x89, 0xb7, 0x5c, 0x22, 0x71, 0xf9,
|
||||
0x36, 0x88, 0x16, 0x54, 0x2b, 0xa5, 0x2f, 0x06,
|
||||
0xed, 0x49, 0x24, 0x17, 0x92, 0x30, 0x2b, 0x00,
|
||||
0xb5, 0xe8, 0xf8, 0x0a, 0xe9, 0xa4, 0x73, 0xaf,
|
||||
0xc2, 0x5b, 0x21, 0x8f, 0x51, 0x9a, 0xf0, 0xfd,
|
||||
0xd4, 0x06, 0x36, 0x2e, 0x8d, 0x69, 0xde, 0x7f,
|
||||
0x54, 0xc6, 0x04, 0xa6, 0xe0, 0x0f, 0x35, 0x3f,
|
||||
0x11, 0x0f, 0x77, 0x1b, 0xdc, 0xa8, 0xab, 0x92,
|
||||
0xe5, 0xfb, 0xc3, 0x4e, 0x60, 0xa1, 0xd9, 0xa9,
|
||||
0xdb, 0x17, 0x34, 0x5b, 0x0a, 0x40, 0x27, 0x36,
|
||||
0x85, 0x3b, 0xf9, 0x10, 0xb0, 0x60, 0xbd, 0xf1,
|
||||
0xf8, 0x97, 0xb6, 0x29, 0x0f, 0x01, 0xd1, 0x38,
|
||||
0xae, 0x2c, 0x4c, 0x90, 0x22, 0x5b, 0xa9, 0xea,
|
||||
0x14, 0xd5, 0x18, 0xf5, 0x59, 0x29, 0xde, 0xa0,
|
||||
0x98, 0xca, 0x7a, 0x6c, 0xcf, 0xe6, 0x12, 0x27,
|
||||
0x05, 0x3c, 0x84, 0xe4, 0x9a, 0x4a, 0x33, 0x32,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "XChaCha20 Test",
|
||||
key: []byte{
|
||||
0x1b, 0x27, 0x55, 0x64, 0x73, 0xe9, 0x85, 0xd4,
|
||||
0x62, 0xcd, 0x51, 0x19, 0x7a, 0x9a, 0x46, 0xc7,
|
||||
0x60, 0x09, 0x54, 0x9e, 0xac, 0x64, 0x74, 0xf2,
|
||||
0x06, 0xc4, 0xee, 0x08, 0x44, 0xf6, 0x83, 0x89,
|
||||
},
|
||||
iv: []byte{
|
||||
0x69, 0x69, 0x6e, 0xe9, 0x55, 0xb6, 0x2b, 0x73,
|
||||
0xcd, 0x62, 0xbd, 0xa8, 0x75, 0xfc, 0x73, 0xd6,
|
||||
0x82, 0x19, 0xe0, 0x03, 0x6b, 0x7a, 0x0b, 0x37,
|
||||
},
|
||||
stream: []byte{
|
||||
0x4f, 0xeb, 0xf2, 0xfe, 0x4b, 0x35, 0x9c, 0x50,
|
||||
0x8d, 0xc5, 0xe8, 0xb5, 0x98, 0x0c, 0x88, 0xe3,
|
||||
0x89, 0x46, 0xd8, 0xf1, 0x8f, 0x31, 0x34, 0x65,
|
||||
0xc8, 0x62, 0xa0, 0x87, 0x82, 0x64, 0x82, 0x48,
|
||||
0x01, 0x8d, 0xac, 0xdc, 0xb9, 0x04, 0x17, 0x88,
|
||||
0x53, 0xa4, 0x6d, 0xca, 0x3a, 0x0e, 0xaa, 0xee,
|
||||
0x74, 0x7c, 0xba, 0x97, 0x43, 0x4e, 0xaf, 0xfa,
|
||||
0xd5, 0x8f, 0xea, 0x82, 0x22, 0x04, 0x7e, 0x0d,
|
||||
0xe6, 0xc3, 0xa6, 0x77, 0x51, 0x06, 0xe0, 0x33,
|
||||
0x1a, 0xd7, 0x14, 0xd2, 0xf2, 0x7a, 0x55, 0x64,
|
||||
0x13, 0x40, 0xa1, 0xf1, 0xdd, 0x9f, 0x94, 0x53,
|
||||
0x2e, 0x68, 0xcb, 0x24, 0x1c, 0xbd, 0xd1, 0x50,
|
||||
0x97, 0x0d, 0x14, 0xe0, 0x5c, 0x5b, 0x17, 0x31,
|
||||
0x93, 0xfb, 0x14, 0xf5, 0x1c, 0x41, 0xf3, 0x93,
|
||||
0x83, 0x5b, 0xf7, 0xf4, 0x16, 0xa7, 0xe0, 0xbb,
|
||||
0xa8, 0x1f, 0xfb, 0x8b, 0x13, 0xaf, 0x0e, 0x21,
|
||||
0x69, 0x1d, 0x7e, 0xce, 0xc9, 0x3b, 0x75, 0xe6,
|
||||
0xe4, 0x18, 0x3a,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "RFC 7539 Test Vector (96 bit nonce)",
|
||||
key: []byte{
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
||||
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
|
||||
},
|
||||
iv: []byte{
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
},
|
||||
stream: []byte{
|
||||
0x22, 0x4f, 0x51, 0xf3, 0x40, 0x1b, 0xd9, 0xe1,
|
||||
0x2f, 0xde, 0x27, 0x6f, 0xb8, 0x63, 0x1d, 0xed,
|
||||
0x8c, 0x13, 0x1f, 0x82, 0x3d, 0x2c, 0x06, 0xe2,
|
||||
0x7e, 0x4f, 0xca, 0xec, 0x9e, 0xf3, 0xcf, 0x78,
|
||||
0x8a, 0x3b, 0x0a, 0xa3, 0x72, 0x60, 0x0a, 0x92,
|
||||
0xb5, 0x79, 0x74, 0xcd, 0xed, 0x2b, 0x93, 0x34,
|
||||
0x79, 0x4c, 0xba, 0x40, 0xc6, 0x3e, 0x34, 0xcd,
|
||||
0xea, 0x21, 0x2c, 0x4c, 0xf0, 0x7d, 0x41, 0xb7,
|
||||
0x69, 0xa6, 0x74, 0x9f, 0x3f, 0x63, 0x0f, 0x41,
|
||||
0x22, 0xca, 0xfe, 0x28, 0xec, 0x4d, 0xc4, 0x7e,
|
||||
0x26, 0xd4, 0x34, 0x6d, 0x70, 0xb9, 0x8c, 0x73,
|
||||
0xf3, 0xe9, 0xc5, 0x3a, 0xc4, 0x0c, 0x59, 0x45,
|
||||
0x39, 0x8b, 0x6e, 0xda, 0x1a, 0x83, 0x2c, 0x89,
|
||||
0xc1, 0x67, 0xea, 0xcd, 0x90, 0x1d, 0x7e, 0x2b,
|
||||
0xf3, 0x63,
|
||||
},
|
||||
seekOffset: 1,
|
||||
},
|
||||
}
|
||||
|
||||
func TestChaCha20(t *testing.T) {
|
||||
for _, v := range draftTestVectors {
|
||||
c, err := NewCipher(v.key, v.iv)
|
||||
if err != nil {
|
||||
t.Errorf("[%s]: New(k, iv) returned: %s", v.name, err)
|
||||
continue
|
||||
}
|
||||
if v.seekOffset != 0 {
|
||||
if err = c.Seek(v.seekOffset); err != nil {
|
||||
t.Errorf("[%s]: Seek(seekOffset) returned: %s", v.name, err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
out := make([]byte, len(v.stream))
|
||||
c.XORKeyStream(out, out)
|
||||
if !bytes.Equal(out, v.stream) {
|
||||
t.Errorf("[%s]: out != stream (%x != %x)", v.name, out, v.stream)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestChaCha20Vectorized(t *testing.T) {
|
||||
if !usingVectors {
|
||||
t.Skip("vectorized ChaCha20 support not enabled")
|
||||
}
|
||||
|
||||
// Save the batch blocks processing routine so we can mess with it, and
|
||||
// restore it when we're done.
|
||||
oldBlocksFn := blocksFn
|
||||
defer func() {
|
||||
blocksFn = oldBlocksFn
|
||||
}()
|
||||
|
||||
const testSz = 1024 * 16
|
||||
|
||||
// Generate a random key, nonce and input.
|
||||
var key [KeySize]byte
|
||||
var nonce [NonceSize]byte
|
||||
var input [testSz]byte
|
||||
var vecOut [testSz]byte
|
||||
var refOut [testSz]byte
|
||||
rand.Read(key[:])
|
||||
rand.Read(nonce[:])
|
||||
rand.Read(input[:])
|
||||
|
||||
for i := 0; i < testSz; i++ {
|
||||
// Encrypt with the vectorized implementation.
|
||||
c, err := NewCipher(key[:], nonce[:])
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
c.XORKeyStream(vecOut[:], input[:i])
|
||||
|
||||
c, err = NewCipher(key[:], nonce[:])
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
blocksFn = blocksRef
|
||||
c.XORKeyStream(refOut[:], input[:i])
|
||||
if !bytes.Equal(refOut[:i], vecOut[:i]) {
|
||||
for j, v := range refOut {
|
||||
if vecOut[j] != v {
|
||||
t.Errorf("[%d] mismatch at offset: %d %x != %x", i, j, vecOut[j], v)
|
||||
break
|
||||
}
|
||||
}
|
||||
t.Errorf("ref: %s", hex.Dump(refOut[:i]))
|
||||
t.Errorf("vec: %s", hex.Dump(vecOut[:i]))
|
||||
t.Errorf("refOut != vecOut")
|
||||
break
|
||||
}
|
||||
blocksFn = oldBlocksFn
|
||||
}
|
||||
}
|
||||
|
||||
func TestChaCha20VectorizedIncremental(t *testing.T) {
|
||||
if !usingVectors {
|
||||
t.Skip("vectorized ChaCha20 support not enabled")
|
||||
}
|
||||
|
||||
// Save the batch blocks processing routine so we can mess with it, and
|
||||
// restore it when we're done.
|
||||
oldBlocksFn := blocksFn
|
||||
defer func() {
|
||||
blocksFn = oldBlocksFn
|
||||
}()
|
||||
|
||||
const (
|
||||
maxBlocks = 256
|
||||
testSz = (maxBlocks * (maxBlocks + 1) / 2) * BlockSize
|
||||
)
|
||||
|
||||
// Generate a random key, nonce and input.
|
||||
var key [KeySize]byte
|
||||
var nonce [NonceSize]byte
|
||||
var input [testSz]byte
|
||||
var vecOut [testSz]byte
|
||||
var refOut [testSz]byte
|
||||
rand.Read(key[:])
|
||||
rand.Read(nonce[:])
|
||||
rand.Read(input[:])
|
||||
|
||||
// Using the vectorized version, encrypt an ever increasing number of
|
||||
// blocks at a time.
|
||||
c, err := NewCipher(key[:], nonce[:])
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
off := 0
|
||||
for nrBlocks := 0; nrBlocks <= maxBlocks; nrBlocks++ {
|
||||
cnt := nrBlocks * BlockSize
|
||||
c.XORKeyStream(vecOut[off:off+cnt], input[off:off+cnt])
|
||||
off += cnt
|
||||
}
|
||||
|
||||
// Encrypt an equivalent amount of data with a one shot call to the
|
||||
// reference implementation.
|
||||
c, err = NewCipher(key[:], nonce[:])
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
blocksFn = blocksRef
|
||||
c.XORKeyStream(refOut[:], input[:])
|
||||
|
||||
// And compare the output.
|
||||
if !bytes.Equal(refOut[:], vecOut[:]) {
|
||||
for j, v := range refOut {
|
||||
if vecOut[j] != v {
|
||||
t.Errorf("incremental mismatch at offset: %d %x != %x", j, vecOut[j], v)
|
||||
break
|
||||
}
|
||||
}
|
||||
// t.Errorf("ref: %s", hex.Dump(refOut[:]))
|
||||
// t.Errorf("vec: %s", hex.Dump(vecOut[:]))
|
||||
t.Errorf("refOut != vecOut")
|
||||
}
|
||||
}
|
||||
|
||||
func doBenchN(b *testing.B, n int) {
|
||||
var key [KeySize]byte
|
||||
var nonce [NonceSize]byte
|
||||
s := make([]byte, n)
|
||||
c, err := NewCipher(key[:], nonce[:])
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
b.SetBytes(int64(n))
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
c.XORKeyStream(s, s)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkChaCha20_16(b *testing.B) {
|
||||
doBenchN(b, 16)
|
||||
}
|
||||
|
||||
func BenchmarkChaCha20_64(b *testing.B) {
|
||||
doBenchN(b, 64)
|
||||
}
|
||||
|
||||
func BenchmarkChaCha20_128(b *testing.B) {
|
||||
doBenchN(b, 128)
|
||||
}
|
||||
|
||||
func BenchmarkChaCha20_192(b *testing.B) {
|
||||
doBenchN(b, 192)
|
||||
}
|
||||
|
||||
func BenchmarkChaCha20_256(b *testing.B) {
|
||||
doBenchN(b, 256)
|
||||
}
|
||||
|
||||
func BenchmarkChaCha20_384(b *testing.B) {
|
||||
doBenchN(b, 384)
|
||||
}
|
||||
|
||||
func BenchmarkChaCha20_512(b *testing.B) {
|
||||
doBenchN(b, 512)
|
||||
}
|
||||
|
||||
func BenchmarkChaCha20_1k(b *testing.B) {
|
||||
doBenchN(b, 1024)
|
||||
}
|
||||
|
||||
func BenchmarkChaCha20_64k(b *testing.B) {
|
||||
doBenchN(b, 65536)
|
||||
}
|
||||
|
||||
func BenchmarkCTRAES256_64k(b *testing.B) {
|
||||
const sz = 64 * 1024
|
||||
var key [32]byte
|
||||
var iv [16]byte
|
||||
s := make([]byte, sz)
|
||||
blk, err := aes.NewCipher(key[:])
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
c := cipher.NewCTR(blk, iv[:])
|
||||
b.SetBytes(sz)
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
c.XORKeyStream(s, s)
|
||||
}
|
||||
}
|
||||
17
vendor/github.com/wg/ecies/vendor/schwanenlied.me/yawning/poly1305/README.md
generated
vendored
Normal file
17
vendor/github.com/wg/ecies/vendor/schwanenlied.me/yawning/poly1305/README.md
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
### poly1305: Go Poly1305
|
||||
#### Yawning Angel (yawning at schwanenlied dot me)
|
||||
|
||||
Poly1305 implements the Poly1305 MAC algorithm, exposing a saner interface than
|
||||
the one provided by golang.org/x/crypto/poly1305. In particular it exposes a
|
||||
object that implements a hash.Hash interface.
|
||||
|
||||
The implementation is based on the Public Domain poly1305-donna by Andrew
|
||||
Moon.
|
||||
|
||||
| Implementation | 64 byte | 1024 byte |
|
||||
| -------------------- | ------------ | ----------- |
|
||||
| go.crypto (ref) | 94.51 MB/s | 187.67 MB/s |
|
||||
| go.crypto (amd64) | 540.68 MB/s | 909.97 MB/s |
|
||||
| go poly1305-donna-32 | 425.40 MB/s | 715.23 MB/s |
|
||||
|
||||
Note: All numbers on a i5-4250U, and to be taken with a huge grain of salt.
|
||||
207
vendor/github.com/wg/ecies/vendor/schwanenlied.me/yawning/poly1305/poly1305.go
generated
vendored
Normal file
207
vendor/github.com/wg/ecies/vendor/schwanenlied.me/yawning/poly1305/poly1305.go
generated
vendored
Normal file
@@ -0,0 +1,207 @@
|
||||
//
|
||||
// poly1305.go: Poly1305 MAC.
|
||||
//
|
||||
// To the extent possible under law, Yawning Angel waived all copyright
|
||||
// and related or neighboring rights to poly1305, using the creative
|
||||
// commons "CC0" public domain dedication. See LICENSE or
|
||||
// <http://creativecommons.org/publicdomain/zero/1.0/> for full details.
|
||||
|
||||
// Package poly1305 is a Poly1305 MAC implementation. It is different from the
|
||||
// golang.org/x/crypto implementation in that it exports a hash.Hash interface
|
||||
// to support incremental updates.
|
||||
//
|
||||
// The implementation is based on Andrew Moon's poly1305-donna.
|
||||
package poly1305
|
||||
|
||||
import (
|
||||
"crypto/subtle"
|
||||
"errors"
|
||||
"hash"
|
||||
"runtime"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
// KeySize is the Poly1305 key size in bytes.
|
||||
KeySize = 32
|
||||
|
||||
// Size is the Poly1305 MAC size in bytes.
|
||||
Size = 16
|
||||
|
||||
// BlockSize is the Poly1305 block size in bytes.
|
||||
BlockSize = 16
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrInvalidKeySize is the error returned when an invalid sized key is
|
||||
// encountered.
|
||||
ErrInvalidKeySize = errors.New("poly1305: invalid key size")
|
||||
|
||||
// ErrInvalidMacSize is the error returned when an invalid sized MAC is
|
||||
// encountered.
|
||||
ErrInvalidMacSize = errors.New("poly1305: invalid mac size")
|
||||
|
||||
isLittleEndian = false
|
||||
)
|
||||
|
||||
type implInterface interface {
|
||||
init(key []byte)
|
||||
clear()
|
||||
blocks(m []byte, bytes int, isFinal bool)
|
||||
finish(mac *[Size]byte)
|
||||
}
|
||||
|
||||
// Poly1305 is an instance of the Poly1305 MAC algorithm.
|
||||
type Poly1305 struct {
|
||||
impl implState
|
||||
leftover int
|
||||
buffer [BlockSize]byte
|
||||
}
|
||||
|
||||
// Write adds more data to the running hash. It never returns an error.
|
||||
func (st *Poly1305) Write(p []byte) (n int, err error) {
|
||||
//
|
||||
// poly1305-donna.c:poly1305_update()
|
||||
//
|
||||
|
||||
m := p
|
||||
bytes := len(m)
|
||||
|
||||
// handle leftover
|
||||
if st.leftover > 0 {
|
||||
want := BlockSize - st.leftover
|
||||
if want > bytes {
|
||||
want = bytes
|
||||
}
|
||||
for i := 0; i < want; i++ {
|
||||
st.buffer[st.leftover+i] = m[i]
|
||||
}
|
||||
bytes -= want
|
||||
m = m[want:]
|
||||
st.leftover += want
|
||||
if st.leftover < BlockSize {
|
||||
return len(p), nil
|
||||
}
|
||||
st.impl.blocks(st.buffer[:], BlockSize, false)
|
||||
st.leftover = 0
|
||||
}
|
||||
|
||||
// process full blocks
|
||||
if bytes >= BlockSize {
|
||||
want := bytes & (^(BlockSize - 1))
|
||||
st.impl.blocks(m, want, false)
|
||||
m = m[want:]
|
||||
bytes -= want
|
||||
}
|
||||
|
||||
// store leftover
|
||||
if bytes > 0 {
|
||||
for i := 0; i < bytes; i++ {
|
||||
st.buffer[st.leftover+i] = m[i]
|
||||
}
|
||||
st.leftover += bytes
|
||||
}
|
||||
|
||||
return len(p), nil
|
||||
}
|
||||
|
||||
// Sum appends the current hash to b and returns the resulting slice. It does
|
||||
// not change the underlying hash state.
|
||||
func (st *Poly1305) Sum(b []byte) []byte {
|
||||
var mac [Size]byte
|
||||
tmp := *st
|
||||
tmp.finish(&mac)
|
||||
return append(b, mac[:]...)
|
||||
}
|
||||
|
||||
// Reset clears the internal hash state and panic()s, because calling this is a
|
||||
// sign that the user is doing something unadvisable.
|
||||
func (st *Poly1305) Reset() {
|
||||
st.Clear() // Obliterate the state before panic().
|
||||
|
||||
// Poly1305 keys are one time use only.
|
||||
panic("poly1305: Reset() is not supported")
|
||||
}
|
||||
|
||||
// Size returns the number of bytes Sum will return.
|
||||
func (st *Poly1305) Size() int {
|
||||
return Size
|
||||
}
|
||||
|
||||
// BlockSize returns the hash's underlying block size.
|
||||
func (st *Poly1305) BlockSize() int {
|
||||
return BlockSize
|
||||
}
|
||||
|
||||
// Init (re-)initializes the hash instance with a given key.
|
||||
func (st *Poly1305) Init(key []byte) {
|
||||
if len(key) != KeySize {
|
||||
panic(ErrInvalidKeySize)
|
||||
}
|
||||
|
||||
st.impl.init(key)
|
||||
st.leftover = 0
|
||||
}
|
||||
|
||||
// Clear purges the sensitive material in hash's internal state.
|
||||
func (st *Poly1305) Clear() {
|
||||
st.impl.clear()
|
||||
}
|
||||
|
||||
func (st *Poly1305) finish(mac *[Size]byte) {
|
||||
// process the remaining block
|
||||
if st.leftover > 0 {
|
||||
st.buffer[st.leftover] = 1
|
||||
for i := st.leftover + 1; i < BlockSize; i++ {
|
||||
st.buffer[i] = 0
|
||||
}
|
||||
st.impl.blocks(st.buffer[:], BlockSize, true)
|
||||
}
|
||||
|
||||
st.impl.finish(mac)
|
||||
st.impl.clear()
|
||||
}
|
||||
|
||||
// New returns a new Poly1305 instance keyed with the supplied key.
|
||||
func New(key []byte) (*Poly1305, error) {
|
||||
if len(key) != KeySize {
|
||||
return nil, ErrInvalidKeySize
|
||||
}
|
||||
|
||||
h := &Poly1305{}
|
||||
h.Init(key)
|
||||
return h, nil
|
||||
}
|
||||
|
||||
// Sum does exactly what golang.org/x/crypto/poly1305.Sum() does.
|
||||
func Sum(mac *[Size]byte, m []byte, key *[KeySize]byte) {
|
||||
var h Poly1305
|
||||
h.Init(key[:])
|
||||
h.Write(m)
|
||||
h.finish(mac)
|
||||
}
|
||||
|
||||
// Verify does exactly what golang.org/x/crypto/poly1305.Verify does.
|
||||
func Verify(mac *[Size]byte, m []byte, key *[KeySize]byte) bool {
|
||||
var m2 [Size]byte
|
||||
Sum(&m2, m, key)
|
||||
return subtle.ConstantTimeCompare(mac[:], m2[:]) == 1
|
||||
}
|
||||
|
||||
func init() {
|
||||
// Use the UTF-32 (UCS-4) Byte Order Mark to detect host byte order,
|
||||
// which enables the further use of 'unsafe' for added performance.
|
||||
const bomLE = 0x0000feff
|
||||
bom := [4]byte{0xff, 0xfe, 0x00, 0x00}
|
||||
|
||||
// ARM doesn't get the spiffy fast code since it's picky wrt alignment
|
||||
// and I doubt Go does the right thing.
|
||||
if runtime.GOARCH != "arm" {
|
||||
bomHost := *(*uint32)(unsafe.Pointer(&bom[0]))
|
||||
if bomHost == 0x0000feff { // Little endian, use unsafe.
|
||||
isLittleEndian = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var _ hash.Hash = (*Poly1305)(nil)
|
||||
236
vendor/github.com/wg/ecies/vendor/schwanenlied.me/yawning/poly1305/poly1305_32.go
generated
vendored
Normal file
236
vendor/github.com/wg/ecies/vendor/schwanenlied.me/yawning/poly1305/poly1305_32.go
generated
vendored
Normal file
@@ -0,0 +1,236 @@
|
||||
//
|
||||
// poly1305_32.go: 32->64 bit multiplies, 64 bit additions
|
||||
//
|
||||
// To the extent possible under law, Yawning Angel waived all copyright
|
||||
// and related or neighboring rights to poly1305, using the creative
|
||||
// commons "CC0" public domain dedication. See LICENSE or
|
||||
// <http://creativecommons.org/publicdomain/zero/1.0/> for full details.
|
||||
|
||||
package poly1305
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type implState struct {
|
||||
r [5]uint32
|
||||
h [5]uint32
|
||||
pad [4]uint32
|
||||
}
|
||||
|
||||
func (impl *implState) init(key []byte) {
|
||||
//
|
||||
// poly1305-donna-32.h:poly1305_init()
|
||||
//
|
||||
|
||||
// r &= 0xffffffc0ffffffc0ffffffc0fffffff
|
||||
if isLittleEndian {
|
||||
impl.r[0] = *(*uint32)(unsafe.Pointer(&key[0])) & 0x3ffffff
|
||||
impl.r[1] = (*(*uint32)(unsafe.Pointer(&key[3])) >> 2) & 0x3ffff03
|
||||
impl.r[2] = (*(*uint32)(unsafe.Pointer(&key[6])) >> 4) & 0x3ffc0ff
|
||||
impl.r[3] = (*(*uint32)(unsafe.Pointer(&key[9])) >> 6) & 0x3f03fff
|
||||
impl.r[4] = (*(*uint32)(unsafe.Pointer(&key[12])) >> 8) & 0x00fffff
|
||||
} else {
|
||||
impl.r[0] = binary.LittleEndian.Uint32(key[0:]) & 0x3ffffff
|
||||
impl.r[1] = (binary.LittleEndian.Uint32(key[3:]) >> 2) & 0x3ffff03
|
||||
impl.r[2] = (binary.LittleEndian.Uint32(key[6:]) >> 4) & 0x3ffc0ff
|
||||
impl.r[3] = (binary.LittleEndian.Uint32(key[9:]) >> 6) & 0x3f03fff
|
||||
impl.r[4] = (binary.LittleEndian.Uint32(key[12:]) >> 8) & 0x00fffff
|
||||
}
|
||||
|
||||
// h = 0
|
||||
for i := range impl.h {
|
||||
impl.h[i] = 0
|
||||
}
|
||||
|
||||
// save pad for later
|
||||
impl.pad[0] = binary.LittleEndian.Uint32(key[16:])
|
||||
impl.pad[1] = binary.LittleEndian.Uint32(key[20:])
|
||||
impl.pad[2] = binary.LittleEndian.Uint32(key[24:])
|
||||
impl.pad[3] = binary.LittleEndian.Uint32(key[28:])
|
||||
}
|
||||
|
||||
func (impl *implState) clear() {
|
||||
for i := range impl.h {
|
||||
impl.h[i] = 0
|
||||
}
|
||||
for i := range impl.r {
|
||||
impl.r[i] = 0
|
||||
}
|
||||
for i := range impl.pad {
|
||||
impl.pad[i] = 0
|
||||
}
|
||||
}
|
||||
|
||||
func (impl *implState) blocks(m []byte, bytes int, isFinal bool) {
|
||||
//
|
||||
// poly1305-donna-32.h:poly1305_blocks()
|
||||
//
|
||||
|
||||
var hibit uint32
|
||||
var d0, d1, d2, d3, d4 uint64
|
||||
var c uint32
|
||||
if !isFinal {
|
||||
hibit = 1 << 24 // 1 << 128
|
||||
}
|
||||
r0, r1, r2, r3, r4 := impl.r[0], impl.r[1], impl.r[2], impl.r[3], impl.r[4]
|
||||
s1, s2, s3, s4 := r1*5, r2*5, r3*5, r4*5
|
||||
h0, h1, h2, h3, h4 := impl.h[0], impl.h[1], impl.h[2], impl.h[3], impl.h[4]
|
||||
|
||||
for bytes >= BlockSize {
|
||||
// h += m[i]
|
||||
if isLittleEndian {
|
||||
h0 += *(*uint32)(unsafe.Pointer(&m[0])) & 0x3ffffff
|
||||
h1 += (*(*uint32)(unsafe.Pointer(&m[3])) >> 2) & 0x3ffffff
|
||||
h2 += (*(*uint32)(unsafe.Pointer(&m[6])) >> 4) & 0x3ffffff
|
||||
h3 += (*(*uint32)(unsafe.Pointer(&m[9])) >> 6) & 0x3ffffff
|
||||
h4 += (*(*uint32)(unsafe.Pointer(&m[12])) >> 8) | hibit
|
||||
} else {
|
||||
h0 += binary.LittleEndian.Uint32(m[0:]) & 0x3ffffff
|
||||
h1 += (binary.LittleEndian.Uint32(m[3:]) >> 2) & 0x3ffffff
|
||||
h2 += (binary.LittleEndian.Uint32(m[6:]) >> 4) & 0x3ffffff
|
||||
h3 += (binary.LittleEndian.Uint32(m[9:]) >> 6) & 0x3ffffff
|
||||
h4 += (binary.LittleEndian.Uint32(m[12:]) >> 8) | hibit
|
||||
}
|
||||
|
||||
// h *= r
|
||||
d0 = (uint64(h0) * uint64(r0)) + (uint64(h1) * uint64(s4)) + (uint64(h2) * uint64(s3)) + (uint64(h3) * uint64(s2)) + (uint64(h4) * uint64(s1))
|
||||
d1 = (uint64(h0) * uint64(r1)) + (uint64(h1) * uint64(r0)) + (uint64(h2) * uint64(s4)) + (uint64(h3) * uint64(s3)) + (uint64(h4) * uint64(s2))
|
||||
d2 = (uint64(h0) * uint64(r2)) + (uint64(h1) * uint64(r1)) + (uint64(h2) * uint64(r0)) + (uint64(h3) * uint64(s4)) + (uint64(h4) * uint64(s3))
|
||||
d3 = (uint64(h0) * uint64(r3)) + (uint64(h1) * uint64(r2)) + (uint64(h2) * uint64(r1)) + (uint64(h3) * uint64(r0)) + (uint64(h4) * uint64(s4))
|
||||
d4 = (uint64(h0) * uint64(r4)) + (uint64(h1) * uint64(r3)) + (uint64(h2) * uint64(r2)) + (uint64(h3) * uint64(r1)) + (uint64(h4) * uint64(r0))
|
||||
|
||||
// (partial) h %= p
|
||||
c = uint32(d0 >> 26)
|
||||
h0 = uint32(d0) & 0x3ffffff
|
||||
|
||||
d1 += uint64(c)
|
||||
c = uint32(d1 >> 26)
|
||||
h1 = uint32(d1) & 0x3ffffff
|
||||
|
||||
d2 += uint64(c)
|
||||
c = uint32(d2 >> 26)
|
||||
h2 = uint32(d2) & 0x3ffffff
|
||||
|
||||
d3 += uint64(c)
|
||||
c = uint32(d3 >> 26)
|
||||
h3 = uint32(d3) & 0x3ffffff
|
||||
|
||||
d4 += uint64(c)
|
||||
c = uint32(d4 >> 26)
|
||||
h4 = uint32(d4) & 0x3ffffff
|
||||
|
||||
h0 += c * 5
|
||||
c = h0 >> 26
|
||||
h0 = h0 & 0x3ffffff
|
||||
|
||||
h1 += c
|
||||
|
||||
m = m[BlockSize:]
|
||||
bytes -= BlockSize
|
||||
}
|
||||
|
||||
impl.h[0], impl.h[1], impl.h[2], impl.h[3], impl.h[4] = h0, h1, h2, h3, h4
|
||||
}
|
||||
|
||||
func (impl *implState) finish(mac *[Size]byte) {
|
||||
//
|
||||
// poly1305-donna-32.h:poly1305_finish()
|
||||
//
|
||||
|
||||
var c uint32
|
||||
var g0, g1, g2, g3, g4 uint32
|
||||
var f uint64
|
||||
var mask uint32
|
||||
|
||||
// fully carry h
|
||||
h0, h1, h2, h3, h4 := impl.h[0], impl.h[1], impl.h[2], impl.h[3], impl.h[4]
|
||||
c = h1 >> 26
|
||||
h1 &= 0x3ffffff
|
||||
|
||||
h2 += c
|
||||
c = h2 >> 26
|
||||
h2 &= 0x3ffffff
|
||||
|
||||
h3 += c
|
||||
c = h3 >> 26
|
||||
h3 &= 0x3ffffff
|
||||
|
||||
h4 += c
|
||||
c = h4 >> 26
|
||||
h4 &= 0x3ffffff
|
||||
|
||||
h0 += c * 5
|
||||
c = h0 >> 26
|
||||
h0 &= 0x3ffffff
|
||||
|
||||
h1 += c
|
||||
|
||||
// compute h + -p
|
||||
g0 = h0 + 5
|
||||
c = g0 >> 26
|
||||
g0 &= 0x3ffffff
|
||||
|
||||
g1 = h1 + c
|
||||
c = g1 >> 26
|
||||
g1 &= 0x3ffffff
|
||||
|
||||
g2 = h2 + c
|
||||
c = g2 >> 26
|
||||
g2 &= 0x3ffffff
|
||||
|
||||
g3 = h3 + c
|
||||
c = g3 >> 26
|
||||
g3 &= 0x3ffffff
|
||||
|
||||
g4 = h4 + c - (1 << 26)
|
||||
|
||||
// select h if h < p, or h + -p if h >= p
|
||||
mask = (g4 >> ((4 * 8) - 1)) - 1
|
||||
g0 &= mask
|
||||
g1 &= mask
|
||||
g2 &= mask
|
||||
g3 &= mask
|
||||
g4 &= mask
|
||||
mask = ^mask
|
||||
h0 = (h0 & mask) | g0
|
||||
h1 = (h1 & mask) | g1
|
||||
h2 = (h2 & mask) | g2
|
||||
h3 = (h3 & mask) | g3
|
||||
h4 = (h4 & mask) | g4
|
||||
|
||||
// h = h % (2^128)
|
||||
h0 = ((h0) | (h1 << 26)) & 0xffffffff
|
||||
h1 = ((h1 >> 6) | (h2 << 20)) & 0xffffffff
|
||||
h2 = ((h2 >> 12) | (h3 << 14)) & 0xffffffff
|
||||
h3 = ((h3 >> 18) | (h4 << 8)) & 0xffffffff
|
||||
|
||||
// mac = (h + pad) % (2^128)
|
||||
f = uint64(h0) + uint64(impl.pad[0])
|
||||
h0 = uint32(f)
|
||||
|
||||
f = uint64(h1) + uint64(impl.pad[1]) + (f >> 32)
|
||||
h1 = uint32(f)
|
||||
|
||||
f = uint64(h2) + uint64(impl.pad[2]) + (f >> 32)
|
||||
h2 = uint32(f)
|
||||
|
||||
f = uint64(h3) + uint64(impl.pad[3]) + (f >> 32)
|
||||
h3 = uint32(f)
|
||||
|
||||
if isLittleEndian {
|
||||
macArr := (*[4]uint32)(unsafe.Pointer(&mac[0]))
|
||||
macArr[0] = h0
|
||||
macArr[1] = h1
|
||||
macArr[2] = h2
|
||||
macArr[3] = h3
|
||||
} else {
|
||||
binary.LittleEndian.PutUint32(mac[0:], h0)
|
||||
binary.LittleEndian.PutUint32(mac[4:], h1)
|
||||
binary.LittleEndian.PutUint32(mac[8:], h2)
|
||||
binary.LittleEndian.PutUint32(mac[12:], h3)
|
||||
}
|
||||
}
|
||||
|
||||
var _ implInterface = (*implState)(nil)
|
||||
585
vendor/github.com/wg/ecies/vendor/schwanenlied.me/yawning/poly1305/poly1305_test.go
generated
vendored
Normal file
585
vendor/github.com/wg/ecies/vendor/schwanenlied.me/yawning/poly1305/poly1305_test.go
generated
vendored
Normal file
@@ -0,0 +1,585 @@
|
||||
//
|
||||
// poly1305.go: Poly1305 MAC known answer tests.
|
||||
//
|
||||
// To the extent possible under law, Yawning Angel waived all copyright
|
||||
// and related or neighboring rights to poly1305, using the creative
|
||||
// commons "CC0" public domain dedication. See LICENSE or
|
||||
// <http://creativecommons.org/publicdomain/zero/1.0/> for full details.
|
||||
|
||||
package poly1305
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// Shamelessly stolen from poly1305-donna.c:poly1305_power_on_self_test()
|
||||
|
||||
func TestNaCl(t *testing.T) {
|
||||
var naclKey = []byte{
|
||||
0xee, 0xa6, 0xa7, 0x25, 0x1c, 0x1e, 0x72, 0x91,
|
||||
0x6d, 0x11, 0xc2, 0xcb, 0x21, 0x4d, 0x3c, 0x25,
|
||||
0x25, 0x39, 0x12, 0x1d, 0x8e, 0x23, 0x4e, 0x65,
|
||||
0x2d, 0x65, 0x1f, 0xa4, 0xc8, 0xcf, 0xf8, 0x80,
|
||||
}
|
||||
|
||||
var naclMsg = []byte{
|
||||
0x8e, 0x99, 0x3b, 0x9f, 0x48, 0x68, 0x12, 0x73,
|
||||
0xc2, 0x96, 0x50, 0xba, 0x32, 0xfc, 0x76, 0xce,
|
||||
0x48, 0x33, 0x2e, 0xa7, 0x16, 0x4d, 0x96, 0xa4,
|
||||
0x47, 0x6f, 0xb8, 0xc5, 0x31, 0xa1, 0x18, 0x6a,
|
||||
0xc0, 0xdf, 0xc1, 0x7c, 0x98, 0xdc, 0xe8, 0x7b,
|
||||
0x4d, 0xa7, 0xf0, 0x11, 0xec, 0x48, 0xc9, 0x72,
|
||||
0x71, 0xd2, 0xc2, 0x0f, 0x9b, 0x92, 0x8f, 0xe2,
|
||||
0x27, 0x0d, 0x6f, 0xb8, 0x63, 0xd5, 0x17, 0x38,
|
||||
0xb4, 0x8e, 0xee, 0xe3, 0x14, 0xa7, 0xcc, 0x8a,
|
||||
0xb9, 0x32, 0x16, 0x45, 0x48, 0xe5, 0x26, 0xae,
|
||||
0x90, 0x22, 0x43, 0x68, 0x51, 0x7a, 0xcf, 0xea,
|
||||
0xbd, 0x6b, 0xb3, 0x73, 0x2b, 0xc0, 0xe9, 0xda,
|
||||
0x99, 0x83, 0x2b, 0x61, 0xca, 0x01, 0xb6, 0xde,
|
||||
0x56, 0x24, 0x4a, 0x9e, 0x88, 0xd5, 0xf9, 0xb3,
|
||||
0x79, 0x73, 0xf6, 0x22, 0xa4, 0x3d, 0x14, 0xa6,
|
||||
0x59, 0x9b, 0x1f, 0x65, 0x4c, 0xb4, 0x5a, 0x74,
|
||||
0xe3, 0x55, 0xa5,
|
||||
}
|
||||
|
||||
var naclMac = []byte{
|
||||
0xf3, 0xff, 0xc7, 0x70, 0x3f, 0x94, 0x00, 0xe5,
|
||||
0x2a, 0x7d, 0xfb, 0x4b, 0x3d, 0x33, 0x05, 0xd9,
|
||||
}
|
||||
|
||||
// Oneshot
|
||||
h, err := New(naclKey[:])
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
n, err := h.Write(naclMsg[:])
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
} else if n != len(naclMsg) {
|
||||
t.Fatalf("h.Write() returned unexpected length: %d", n)
|
||||
}
|
||||
|
||||
mac := h.Sum(nil)
|
||||
if !bytes.Equal(mac, naclMac[:]) {
|
||||
t.Fatalf("mac != naclMac")
|
||||
}
|
||||
|
||||
// Incremental
|
||||
h, err = New(naclKey[:])
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
for i, s := range []struct{ off, sz int }{
|
||||
{0, 32},
|
||||
{32, 64},
|
||||
{96, 16},
|
||||
{112, 8},
|
||||
{120, 4},
|
||||
{124, 2},
|
||||
{126, 1},
|
||||
{127, 1},
|
||||
{128, 1},
|
||||
{129, 1},
|
||||
{130, 1},
|
||||
} {
|
||||
n, err := h.Write(naclMsg[s.off : s.off+s.sz])
|
||||
if err != nil {
|
||||
t.Fatalf("[%d]: h.Write(): %s", i, err)
|
||||
} else if n != s.sz {
|
||||
t.Fatalf("[%d]: h.Write(): %d (expected: %d)", i, n, s.sz)
|
||||
}
|
||||
}
|
||||
|
||||
mac = h.Sum(nil)
|
||||
if !bytes.Equal(mac, naclMac[:]) {
|
||||
t.Fatalf("mac != naclMac")
|
||||
}
|
||||
}
|
||||
|
||||
func TestWrap(t *testing.T) {
|
||||
// generates a final value of (2^130 - 2) == 3
|
||||
wrapKey := [KeySize]byte{
|
||||
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
}
|
||||
|
||||
wrapMsg := []byte{
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
}
|
||||
|
||||
wrapMac := [Size]byte{
|
||||
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
}
|
||||
|
||||
var mac [Size]byte
|
||||
Sum(&mac, wrapMsg, &wrapKey)
|
||||
if !bytes.Equal(mac[:], wrapMac[:]) {
|
||||
t.Fatalf("mac != wrapMac")
|
||||
}
|
||||
}
|
||||
|
||||
func TestTotal(t *testing.T) {
|
||||
// mac of the macs of messages of length 0 to 256, where the key and messages
|
||||
// have all their values set to the length
|
||||
totalKey := []byte{
|
||||
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
}
|
||||
|
||||
totalMac := []byte{
|
||||
0x64, 0xaf, 0xe2, 0xe8, 0xd6, 0xad, 0x7b, 0xbd,
|
||||
0xd2, 0x87, 0xf9, 0x7c, 0x44, 0x62, 0x3d, 0x39,
|
||||
}
|
||||
|
||||
var allKey [KeySize]byte
|
||||
allMsg := make([]byte, 256)
|
||||
|
||||
totalCtx, err := New(totalKey[:])
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
for i := 0; i < 256; i++ {
|
||||
// set key and message to 'i,i,i..'
|
||||
for j := range allKey {
|
||||
allKey[j] = byte(i)
|
||||
}
|
||||
for j := 0; j < i; j++ {
|
||||
allMsg[j] = byte(i)
|
||||
}
|
||||
|
||||
var mac [Size]byte
|
||||
Sum(&mac, allMsg[:i], &allKey)
|
||||
n, err := totalCtx.Write(mac[:])
|
||||
if err != nil {
|
||||
t.Fatalf("[%d]: h.Write(): %s", i, err)
|
||||
} else if n != len(mac) {
|
||||
t.Fatalf("[%d]: h.Write(): %d (expected: %d)", i, n, len(mac))
|
||||
}
|
||||
}
|
||||
mac := totalCtx.Sum(nil)
|
||||
if !bytes.Equal(mac, totalMac[:]) {
|
||||
t.Fatalf("mac != totalMac")
|
||||
}
|
||||
}
|
||||
|
||||
func TestIETFDraft(t *testing.T) {
|
||||
// Test vectors taken from:
|
||||
// https://www.ietf.org/id/draft-irtf-cfrg-chacha20-poly1305-07.txt
|
||||
|
||||
vectors := []struct {
|
||||
key [KeySize]byte
|
||||
m []byte
|
||||
tag [Size]byte
|
||||
}{
|
||||
// Test Vector #1
|
||||
{
|
||||
[KeySize]byte{},
|
||||
[]byte{
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
},
|
||||
[Size]byte{},
|
||||
},
|
||||
|
||||
// Test Vector #2
|
||||
{
|
||||
[KeySize]byte{
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x36, 0xe5, 0xf6, 0xb5, 0xc5, 0xe0, 0x60, 0x70,
|
||||
0xf0, 0xef, 0xca, 0x96, 0x22, 0x7a, 0x86, 0x3e,
|
||||
},
|
||||
[]byte{
|
||||
0x41, 0x6e, 0x79, 0x20, 0x73, 0x75, 0x62, 0x6d,
|
||||
0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x74,
|
||||
0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x49, 0x45,
|
||||
0x54, 0x46, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x6e,
|
||||
0x64, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74,
|
||||
0x68, 0x65, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x72,
|
||||
0x69, 0x62, 0x75, 0x74, 0x6f, 0x72, 0x20, 0x66,
|
||||
0x6f, 0x72, 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69,
|
||||
0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61,
|
||||
0x73, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x6f, 0x72,
|
||||
0x20, 0x70, 0x61, 0x72, 0x74, 0x20, 0x6f, 0x66,
|
||||
0x20, 0x61, 0x6e, 0x20, 0x49, 0x45, 0x54, 0x46,
|
||||
0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65,
|
||||
0x74, 0x2d, 0x44, 0x72, 0x61, 0x66, 0x74, 0x20,
|
||||
0x6f, 0x72, 0x20, 0x52, 0x46, 0x43, 0x20, 0x61,
|
||||
0x6e, 0x64, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x73,
|
||||
0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74,
|
||||
0x20, 0x6d, 0x61, 0x64, 0x65, 0x20, 0x77, 0x69,
|
||||
0x74, 0x68, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65,
|
||||
0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74,
|
||||
0x20, 0x6f, 0x66, 0x20, 0x61, 0x6e, 0x20, 0x49,
|
||||
0x45, 0x54, 0x46, 0x20, 0x61, 0x63, 0x74, 0x69,
|
||||
0x76, 0x69, 0x74, 0x79, 0x20, 0x69, 0x73, 0x20,
|
||||
0x63, 0x6f, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x72,
|
||||
0x65, 0x64, 0x20, 0x61, 0x6e, 0x20, 0x22, 0x49,
|
||||
0x45, 0x54, 0x46, 0x20, 0x43, 0x6f, 0x6e, 0x74,
|
||||
0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e,
|
||||
0x22, 0x2e, 0x20, 0x53, 0x75, 0x63, 0x68, 0x20,
|
||||
0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e,
|
||||
0x74, 0x73, 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75,
|
||||
0x64, 0x65, 0x20, 0x6f, 0x72, 0x61, 0x6c, 0x20,
|
||||
0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e,
|
||||
0x74, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x49, 0x45,
|
||||
0x54, 0x46, 0x20, 0x73, 0x65, 0x73, 0x73, 0x69,
|
||||
0x6f, 0x6e, 0x73, 0x2c, 0x20, 0x61, 0x73, 0x20,
|
||||
0x77, 0x65, 0x6c, 0x6c, 0x20, 0x61, 0x73, 0x20,
|
||||
0x77, 0x72, 0x69, 0x74, 0x74, 0x65, 0x6e, 0x20,
|
||||
0x61, 0x6e, 0x64, 0x20, 0x65, 0x6c, 0x65, 0x63,
|
||||
0x74, 0x72, 0x6f, 0x6e, 0x69, 0x63, 0x20, 0x63,
|
||||
0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x63, 0x61,
|
||||
0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6d, 0x61,
|
||||
0x64, 0x65, 0x20, 0x61, 0x74, 0x20, 0x61, 0x6e,
|
||||
0x79, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20, 0x6f,
|
||||
0x72, 0x20, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x2c,
|
||||
0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x61,
|
||||
0x72, 0x65, 0x20, 0x61, 0x64, 0x64, 0x72, 0x65,
|
||||
0x73, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f,
|
||||
},
|
||||
[Size]byte{
|
||||
0x36, 0xe5, 0xf6, 0xb5, 0xc5, 0xe0, 0x60, 0x70,
|
||||
0xf0, 0xef, 0xca, 0x96, 0x22, 0x7a, 0x86, 0x3e,
|
||||
},
|
||||
},
|
||||
|
||||
// Test Vector #3
|
||||
{
|
||||
[KeySize]byte{
|
||||
0x36, 0xe5, 0xf6, 0xb5, 0xc5, 0xe0, 0x60, 0x70,
|
||||
0xf0, 0xef, 0xca, 0x96, 0x22, 0x7a, 0x86, 0x3e,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
},
|
||||
[]byte{
|
||||
0x41, 0x6e, 0x79, 0x20, 0x73, 0x75, 0x62, 0x6d,
|
||||
0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x74,
|
||||
0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x49, 0x45,
|
||||
0x54, 0x46, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x6e,
|
||||
0x64, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74,
|
||||
0x68, 0x65, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x72,
|
||||
0x69, 0x62, 0x75, 0x74, 0x6f, 0x72, 0x20, 0x66,
|
||||
0x6f, 0x72, 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69,
|
||||
0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61,
|
||||
0x73, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x6f, 0x72,
|
||||
0x20, 0x70, 0x61, 0x72, 0x74, 0x20, 0x6f, 0x66,
|
||||
0x20, 0x61, 0x6e, 0x20, 0x49, 0x45, 0x54, 0x46,
|
||||
0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65,
|
||||
0x74, 0x2d, 0x44, 0x72, 0x61, 0x66, 0x74, 0x20,
|
||||
0x6f, 0x72, 0x20, 0x52, 0x46, 0x43, 0x20, 0x61,
|
||||
0x6e, 0x64, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x73,
|
||||
0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74,
|
||||
0x20, 0x6d, 0x61, 0x64, 0x65, 0x20, 0x77, 0x69,
|
||||
0x74, 0x68, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65,
|
||||
0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74,
|
||||
0x20, 0x6f, 0x66, 0x20, 0x61, 0x6e, 0x20, 0x49,
|
||||
0x45, 0x54, 0x46, 0x20, 0x61, 0x63, 0x74, 0x69,
|
||||
0x76, 0x69, 0x74, 0x79, 0x20, 0x69, 0x73, 0x20,
|
||||
0x63, 0x6f, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x72,
|
||||
0x65, 0x64, 0x20, 0x61, 0x6e, 0x20, 0x22, 0x49,
|
||||
0x45, 0x54, 0x46, 0x20, 0x43, 0x6f, 0x6e, 0x74,
|
||||
0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e,
|
||||
0x22, 0x2e, 0x20, 0x53, 0x75, 0x63, 0x68, 0x20,
|
||||
0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e,
|
||||
0x74, 0x73, 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75,
|
||||
0x64, 0x65, 0x20, 0x6f, 0x72, 0x61, 0x6c, 0x20,
|
||||
0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e,
|
||||
0x74, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x49, 0x45,
|
||||
0x54, 0x46, 0x20, 0x73, 0x65, 0x73, 0x73, 0x69,
|
||||
0x6f, 0x6e, 0x73, 0x2c, 0x20, 0x61, 0x73, 0x20,
|
||||
0x77, 0x65, 0x6c, 0x6c, 0x20, 0x61, 0x73, 0x20,
|
||||
0x77, 0x72, 0x69, 0x74, 0x74, 0x65, 0x6e, 0x20,
|
||||
0x61, 0x6e, 0x64, 0x20, 0x65, 0x6c, 0x65, 0x63,
|
||||
0x74, 0x72, 0x6f, 0x6e, 0x69, 0x63, 0x20, 0x63,
|
||||
0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x63, 0x61,
|
||||
0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6d, 0x61,
|
||||
0x64, 0x65, 0x20, 0x61, 0x74, 0x20, 0x61, 0x6e,
|
||||
0x79, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20, 0x6f,
|
||||
0x72, 0x20, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x2c,
|
||||
0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x61,
|
||||
0x72, 0x65, 0x20, 0x61, 0x64, 0x64, 0x72, 0x65,
|
||||
0x73, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f,
|
||||
},
|
||||
[Size]byte{
|
||||
0xf3, 0x47, 0x7e, 0x7c, 0xd9, 0x54, 0x17, 0xaf,
|
||||
0x89, 0xa6, 0xb8, 0x79, 0x4c, 0x31, 0x0c, 0xf0,
|
||||
},
|
||||
},
|
||||
|
||||
// Test Vector #4
|
||||
{
|
||||
[KeySize]byte{
|
||||
0x1c, 0x92, 0x40, 0xa5, 0xeb, 0x55, 0xd3, 0x8a,
|
||||
0xf3, 0x33, 0x88, 0x86, 0x04, 0xf6, 0xb5, 0xf0,
|
||||
0x47, 0x39, 0x17, 0xc1, 0x40, 0x2b, 0x80, 0x09,
|
||||
0x9d, 0xca, 0x5c, 0xbc, 0x20, 0x70, 0x75, 0xc0,
|
||||
},
|
||||
[]byte{
|
||||
0x27, 0x54, 0x77, 0x61, 0x73, 0x20, 0x62, 0x72,
|
||||
0x69, 0x6c, 0x6c, 0x69, 0x67, 0x2c, 0x20, 0x61,
|
||||
0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73,
|
||||
0x6c, 0x69, 0x74, 0x68, 0x79, 0x20, 0x74, 0x6f,
|
||||
0x76, 0x65, 0x73, 0x0a, 0x44, 0x69, 0x64, 0x20,
|
||||
0x67, 0x79, 0x72, 0x65, 0x20, 0x61, 0x6e, 0x64,
|
||||
0x20, 0x67, 0x69, 0x6d, 0x62, 0x6c, 0x65, 0x20,
|
||||
0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x77,
|
||||
0x61, 0x62, 0x65, 0x3a, 0x0a, 0x41, 0x6c, 0x6c,
|
||||
0x20, 0x6d, 0x69, 0x6d, 0x73, 0x79, 0x20, 0x77,
|
||||
0x65, 0x72, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20,
|
||||
0x62, 0x6f, 0x72, 0x6f, 0x67, 0x6f, 0x76, 0x65,
|
||||
0x73, 0x2c, 0x0a, 0x41, 0x6e, 0x64, 0x20, 0x74,
|
||||
0x68, 0x65, 0x20, 0x6d, 0x6f, 0x6d, 0x65, 0x20,
|
||||
0x72, 0x61, 0x74, 0x68, 0x73, 0x20, 0x6f, 0x75,
|
||||
0x74, 0x67, 0x72, 0x61, 0x62, 0x65, 0x2e,
|
||||
},
|
||||
[Size]byte{
|
||||
0x45, 0x41, 0x66, 0x9a, 0x7e, 0xaa, 0xee, 0x61,
|
||||
0xe7, 0x08, 0xdc, 0x7c, 0xbc, 0xc5, 0xeb, 0x62,
|
||||
},
|
||||
},
|
||||
|
||||
// Test Vector #5
|
||||
//
|
||||
// If one uses 130-bit partial reduction, does the code handle the case
|
||||
// where partially reduced final result is not fully reduced?
|
||||
{
|
||||
[KeySize]byte{
|
||||
// R
|
||||
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
// S
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
},
|
||||
[]byte{
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
},
|
||||
[Size]byte{
|
||||
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
},
|
||||
},
|
||||
|
||||
// Test Vector #6
|
||||
//
|
||||
// What happens if addition of s overflows modulo 2^128?
|
||||
{
|
||||
[KeySize]byte{
|
||||
// R
|
||||
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
// S
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
},
|
||||
[]byte{
|
||||
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
},
|
||||
[Size]byte{
|
||||
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
},
|
||||
},
|
||||
|
||||
// Test Vector #7
|
||||
//
|
||||
// What happens if data limb is all ones and there is carry from lower
|
||||
// limb?
|
||||
{
|
||||
[KeySize]byte{
|
||||
// R
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
// S
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
},
|
||||
[]byte{
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
},
|
||||
[Size]byte{
|
||||
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
},
|
||||
},
|
||||
|
||||
// Test Vector #8
|
||||
//
|
||||
// What happens if final result from polynomial part is exactly
|
||||
// 2^130-5?
|
||||
{
|
||||
[KeySize]byte{
|
||||
// R
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
// S
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
},
|
||||
[]byte{
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFB, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
|
||||
0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
},
|
||||
[Size]byte{
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
},
|
||||
},
|
||||
|
||||
// Test Vector #9
|
||||
//
|
||||
// What happens if final result from polynomial part is exactly
|
||||
// 2^130-6?
|
||||
{
|
||||
[KeySize]byte{
|
||||
// R
|
||||
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
// S
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
},
|
||||
[]byte{
|
||||
0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
},
|
||||
[Size]byte{
|
||||
0xFA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
},
|
||||
},
|
||||
|
||||
// Test Vector #10
|
||||
//
|
||||
// What happens if 5*H+L-type reduction produces 131-bit intermediate
|
||||
// result?
|
||||
{
|
||||
[KeySize]byte{
|
||||
// R
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
// S
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
},
|
||||
[]byte{
|
||||
0xE3, 0x35, 0x94, 0xD7, 0x50, 0x5E, 0x43, 0xB9,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x33, 0x94, 0xD7, 0x50, 0x5E, 0x43, 0x79, 0xCD,
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
},
|
||||
[Size]byte{
|
||||
0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
},
|
||||
},
|
||||
|
||||
// Test Vector #11
|
||||
//
|
||||
// What happens if 5*H+L-type reduction produces 131-bit final result?
|
||||
{
|
||||
[KeySize]byte{
|
||||
// R
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
// S
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
},
|
||||
[]byte{
|
||||
0xE3, 0x35, 0x94, 0xD7, 0x50, 0x5E, 0x43, 0xB9,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x33, 0x94, 0xD7, 0x50, 0x5E, 0x43, 0x79, 0xCD,
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
},
|
||||
[Size]byte{
|
||||
0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for i, vec := range vectors {
|
||||
var mac [Size]byte
|
||||
Sum(&mac, vec.m, &vec.key)
|
||||
if !bytes.Equal(mac[:], vec.tag[:]) {
|
||||
t.Errorf("[%d]: mac != vec.tag", i)
|
||||
}
|
||||
if !Verify(&vec.tag, vec.m, &vec.key) {
|
||||
t.Errorf("[%d]: Verify(tag, m, key) returned false", i)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestIETFDraftForceByteswap(t *testing.T) {
|
||||
if !isLittleEndian {
|
||||
t.Skipf("not little endian, slow path already taken")
|
||||
} else {
|
||||
isLittleEndian = false
|
||||
TestIETFDraft(t)
|
||||
isLittleEndian = true
|
||||
}
|
||||
}
|
||||
|
||||
// Swiped from golang.org/x/crypto/poly1305/poly1305_test.go.
|
||||
|
||||
func Benchmark64(b *testing.B) {
|
||||
b.StopTimer()
|
||||
var mac [Size]byte
|
||||
var key [KeySize]byte
|
||||
m := make([]byte, 64)
|
||||
b.SetBytes(int64(len(m)))
|
||||
b.StartTimer()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
Sum(&mac, m, &key)
|
||||
}
|
||||
}
|
||||
|
||||
func Benchmark1k(b *testing.B) {
|
||||
b.StopTimer()
|
||||
var mac [Size]byte
|
||||
var key [KeySize]byte
|
||||
m := make([]byte, 1024)
|
||||
b.SetBytes(int64(len(m)))
|
||||
b.StartTimer()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
Sum(&mac, m, &key)
|
||||
}
|
||||
}
|
||||
23
vendor/github.com/wg/ecies/vendor/schwanenlied.me/yawning/x448/LICENSE.txt
generated
vendored
Normal file
23
vendor/github.com/wg/ecies/vendor/schwanenlied.me/yawning/x448/LICENSE.txt
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2011 Stanford University.
|
||||
Copyright (c) 2014-2015 Cryptography Research, Inc.
|
||||
Copyright (c) 2015 Yawning Angel.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
13
vendor/github.com/wg/ecies/vendor/schwanenlied.me/yawning/x448/README.md
generated
vendored
Normal file
13
vendor/github.com/wg/ecies/vendor/schwanenlied.me/yawning/x448/README.md
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
### x448 - curve448 ECDH
|
||||
#### Yawning Angel (yawning at schwanenlied dot me)
|
||||
|
||||
A straight forward port of Michael Hamburg's x448 code to Go lang.
|
||||
|
||||
See: https://www.rfc-editor.org/rfc/rfc7748.txt
|
||||
|
||||
If you're familiar with how to use golang.org/x/crypto/curve25519, you will be
|
||||
right at home with using x448, since the functions are the same. Generate a
|
||||
random secret key, ScalarBaseMult() to get the public key, etc etc etc.
|
||||
|
||||
Both routines return 0 on success, -1 on failure which MUST be checked, and
|
||||
the handshake aborted on failure.
|
||||
115
vendor/github.com/wg/ecies/vendor/schwanenlied.me/yawning/x448/x448.go
generated
vendored
Normal file
115
vendor/github.com/wg/ecies/vendor/schwanenlied.me/yawning/x448/x448.go
generated
vendored
Normal file
@@ -0,0 +1,115 @@
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2011 Stanford University.
|
||||
// Copyright (c) 2014-2015 Cryptography Research, Inc.
|
||||
// Copyright (c) 2015 Yawning Angel.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
// Package x448 provides an implementation of scalar multiplication on the
|
||||
// elliptic curve known as curve448.
|
||||
//
|
||||
// See https://tools.ietf.org/html/draft-irtf-cfrg-curves-11
|
||||
package x448 // import "git.schwanenlied.me/yawning/x448.git"
|
||||
|
||||
const (
|
||||
x448Bytes = 56
|
||||
edwardsD = -39081
|
||||
)
|
||||
|
||||
var basePoint = [56]byte{
|
||||
5, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
}
|
||||
|
||||
func ScalarMult(out, scalar, base *[56]byte) int {
|
||||
var x1, x2, z2, x3, z3, t1, t2 gf
|
||||
x1.deser(base)
|
||||
x2.cpy(&one)
|
||||
z2.cpy(&zero)
|
||||
x3.cpy(&x1)
|
||||
z3.cpy(&one)
|
||||
|
||||
var swap limbUint
|
||||
|
||||
for t := int(448 - 1); t >= 0; t-- {
|
||||
sb := scalar[t/8]
|
||||
|
||||
// Scalar conditioning.
|
||||
if t/8 == 0 {
|
||||
sb &= 0xFC
|
||||
} else if t/8 == x448Bytes-1 {
|
||||
sb |= 0x80
|
||||
}
|
||||
|
||||
kT := (limbUint)((sb >> ((uint)(t) % 8)) & 1)
|
||||
kT = -kT // Set to all 0s or all 1s
|
||||
|
||||
swap ^= kT
|
||||
x2.condSwap(&x3, swap)
|
||||
z2.condSwap(&z3, swap)
|
||||
swap = kT
|
||||
|
||||
t1.add(&x2, &z2) // A = x2 + z2
|
||||
t2.sub(&x2, &z2) // B = x2 - z2
|
||||
z2.sub(&x3, &z3) // D = x3 - z3
|
||||
x2.mul(&t1, &z2) // DA
|
||||
z2.add(&z3, &x3) // C = x3 + z3
|
||||
x3.mul(&t2, &z2) // CB
|
||||
z3.sub(&x2, &x3) // DA-CB
|
||||
z2.sqr(&z3) // (DA-CB)^2
|
||||
z3.mul(&x1, &z2) // z3 = x1(DA-CB)^2
|
||||
z2.add(&x2, &x3) // (DA+CB)
|
||||
x3.sqr(&z2) // x3 = (DA+CB)^2
|
||||
|
||||
z2.sqr(&t1) // AA = A^2
|
||||
t1.sqr(&t2) // BB = B^2
|
||||
x2.mul(&z2, &t1) // x2 = AA*BB
|
||||
t2.sub(&z2, &t1) // E = AA-BB
|
||||
|
||||
t1.mlw(&t2, -edwardsD) // E*-d = a24*E
|
||||
t1.add(&t1, &z2) // AA + a24*E
|
||||
z2.mul(&t2, &t1) // z2 = E(AA+a24*E)
|
||||
}
|
||||
|
||||
// Finish
|
||||
x2.condSwap(&x3, swap)
|
||||
z2.condSwap(&x3, swap)
|
||||
z2.inv(&z2)
|
||||
x1.mul(&x2, &z2)
|
||||
x1.ser(out)
|
||||
|
||||
// As with X25519, both sides MUST check, without leaking extra
|
||||
// information about the value of K, whether the resulting shared K is
|
||||
// the all-zero value and abort if so.
|
||||
var nz limbSint
|
||||
for _, v := range out {
|
||||
nz |= (limbSint)(v)
|
||||
}
|
||||
nz = (nz - 1) >> 8 // 0 = succ, -1 = fail
|
||||
|
||||
// return value: 0 = succ, -1 = fail
|
||||
return (int)(nz)
|
||||
}
|
||||
|
||||
func ScalarBaseMult(out, scalar *[56]byte) int {
|
||||
return ScalarMult(out, scalar, &basePoint)
|
||||
}
|
||||
779
vendor/github.com/wg/ecies/vendor/schwanenlied.me/yawning/x448/x448_ref.go
generated
vendored
Normal file
779
vendor/github.com/wg/ecies/vendor/schwanenlied.me/yawning/x448/x448_ref.go
generated
vendored
Normal file
@@ -0,0 +1,779 @@
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2011 Stanford University.
|
||||
// Copyright (c) 2014-2015 Cryptography Research, Inc.
|
||||
// Copyright (c) 2015 Yawning Angel.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
package x448
|
||||
|
||||
// This should really use 64 bit limbs, but Go is fucking retarded and doesn't
|
||||
// have __(u)int128_t, so the 32 bit code it is, at a hefty performance
|
||||
// penalty. Fuck my life, I'm going to have to bust out PeachPy to get this
|
||||
// to go fast aren't I.
|
||||
|
||||
const (
|
||||
wBits = 32
|
||||
lBits = (wBits * 7 / 8)
|
||||
x448Limbs = (448 / lBits)
|
||||
lMask = (1 << lBits) - 1
|
||||
)
|
||||
|
||||
type limbUint uint32
|
||||
type limbSint int32
|
||||
|
||||
type gf struct {
|
||||
limb [x448Limbs]uint32
|
||||
}
|
||||
|
||||
var zero = gf{[x448Limbs]uint32{0}}
|
||||
var one = gf{[x448Limbs]uint32{1}}
|
||||
var p = gf{[x448Limbs]uint32{
|
||||
lMask, lMask, lMask, lMask, lMask, lMask, lMask, lMask,
|
||||
lMask - 1, lMask, lMask, lMask, lMask, lMask, lMask, lMask,
|
||||
}}
|
||||
|
||||
// cpy copies x = y.
|
||||
func (x *gf) cpy(y *gf) {
|
||||
// for i, v := range y.limb {
|
||||
// x.limb[i] = v
|
||||
// }
|
||||
|
||||
copy(x.limb[:], y.limb[:])
|
||||
}
|
||||
|
||||
// mul multiplies c = a * b. (PERF)
|
||||
func (c *gf) mul(a, b *gf) {
|
||||
var aa gf
|
||||
aa.cpy(a)
|
||||
|
||||
//
|
||||
// This is *by far* the most CPU intesive routine in the code.
|
||||
//
|
||||
|
||||
// var accum [x448Limbs]uint64
|
||||
// for i, bv := range b.limb {
|
||||
// for j, aav := range aa.limb {
|
||||
// accum[(i+j)%x448Limbs] += (uint64)(bv) * (uint64)(aav)
|
||||
// }
|
||||
// aa.limb[(x448Limbs-1-i)^(x448Limbs/2)] += aa.limb[x448Limbs-1-i]
|
||||
// }
|
||||
|
||||
// So fucking stupid that this is actually a fairly massive gain.
|
||||
var accum0, accum1, accum2, accum3, accum4, accum5, accum6, accum7, accum8, accum9, accum10, accum11, accum12, accum13, accum14, accum15 uint64
|
||||
var bv uint64
|
||||
|
||||
bv = (uint64)(b.limb[0])
|
||||
accum0 += bv * (uint64)(aa.limb[0])
|
||||
accum1 += bv * (uint64)(aa.limb[1])
|
||||
accum2 += bv * (uint64)(aa.limb[2])
|
||||
accum3 += bv * (uint64)(aa.limb[3])
|
||||
accum4 += bv * (uint64)(aa.limb[4])
|
||||
accum5 += bv * (uint64)(aa.limb[5])
|
||||
accum6 += bv * (uint64)(aa.limb[6])
|
||||
accum7 += bv * (uint64)(aa.limb[7])
|
||||
accum8 += bv * (uint64)(aa.limb[8])
|
||||
accum9 += bv * (uint64)(aa.limb[9])
|
||||
accum10 += bv * (uint64)(aa.limb[10])
|
||||
accum11 += bv * (uint64)(aa.limb[11])
|
||||
accum12 += bv * (uint64)(aa.limb[12])
|
||||
accum13 += bv * (uint64)(aa.limb[13])
|
||||
accum14 += bv * (uint64)(aa.limb[14])
|
||||
accum15 += bv * (uint64)(aa.limb[15])
|
||||
aa.limb[(x448Limbs-1-0)^(x448Limbs/2)] += aa.limb[x448Limbs-1-0]
|
||||
|
||||
bv = (uint64)(b.limb[1])
|
||||
accum1 += bv * (uint64)(aa.limb[0])
|
||||
accum2 += bv * (uint64)(aa.limb[1])
|
||||
accum3 += bv * (uint64)(aa.limb[2])
|
||||
accum4 += bv * (uint64)(aa.limb[3])
|
||||
accum5 += bv * (uint64)(aa.limb[4])
|
||||
accum6 += bv * (uint64)(aa.limb[5])
|
||||
accum7 += bv * (uint64)(aa.limb[6])
|
||||
accum8 += bv * (uint64)(aa.limb[7])
|
||||
accum9 += bv * (uint64)(aa.limb[8])
|
||||
accum10 += bv * (uint64)(aa.limb[9])
|
||||
accum11 += bv * (uint64)(aa.limb[10])
|
||||
accum12 += bv * (uint64)(aa.limb[11])
|
||||
accum13 += bv * (uint64)(aa.limb[12])
|
||||
accum14 += bv * (uint64)(aa.limb[13])
|
||||
accum15 += bv * (uint64)(aa.limb[14])
|
||||
accum0 += bv * (uint64)(aa.limb[15])
|
||||
aa.limb[(x448Limbs-1-1)^(x448Limbs/2)] += aa.limb[x448Limbs-1-1]
|
||||
|
||||
bv = (uint64)(b.limb[2])
|
||||
accum2 += bv * (uint64)(aa.limb[0])
|
||||
accum3 += bv * (uint64)(aa.limb[1])
|
||||
accum4 += bv * (uint64)(aa.limb[2])
|
||||
accum5 += bv * (uint64)(aa.limb[3])
|
||||
accum6 += bv * (uint64)(aa.limb[4])
|
||||
accum7 += bv * (uint64)(aa.limb[5])
|
||||
accum8 += bv * (uint64)(aa.limb[6])
|
||||
accum9 += bv * (uint64)(aa.limb[7])
|
||||
accum10 += bv * (uint64)(aa.limb[8])
|
||||
accum11 += bv * (uint64)(aa.limb[9])
|
||||
accum12 += bv * (uint64)(aa.limb[10])
|
||||
accum13 += bv * (uint64)(aa.limb[11])
|
||||
accum14 += bv * (uint64)(aa.limb[12])
|
||||
accum15 += bv * (uint64)(aa.limb[13])
|
||||
accum0 += bv * (uint64)(aa.limb[14])
|
||||
accum1 += bv * (uint64)(aa.limb[15])
|
||||
aa.limb[(x448Limbs-1-2)^(x448Limbs/2)] += aa.limb[x448Limbs-1-2]
|
||||
|
||||
bv = (uint64)(b.limb[3])
|
||||
accum3 += bv * (uint64)(aa.limb[0])
|
||||
accum4 += bv * (uint64)(aa.limb[1])
|
||||
accum5 += bv * (uint64)(aa.limb[2])
|
||||
accum6 += bv * (uint64)(aa.limb[3])
|
||||
accum7 += bv * (uint64)(aa.limb[4])
|
||||
accum8 += bv * (uint64)(aa.limb[5])
|
||||
accum9 += bv * (uint64)(aa.limb[6])
|
||||
accum10 += bv * (uint64)(aa.limb[7])
|
||||
accum11 += bv * (uint64)(aa.limb[8])
|
||||
accum12 += bv * (uint64)(aa.limb[9])
|
||||
accum13 += bv * (uint64)(aa.limb[10])
|
||||
accum14 += bv * (uint64)(aa.limb[11])
|
||||
accum15 += bv * (uint64)(aa.limb[12])
|
||||
accum0 += bv * (uint64)(aa.limb[13])
|
||||
accum1 += bv * (uint64)(aa.limb[14])
|
||||
accum2 += bv * (uint64)(aa.limb[15])
|
||||
aa.limb[(x448Limbs-1-3)^(x448Limbs/2)] += aa.limb[x448Limbs-1-3]
|
||||
|
||||
bv = (uint64)(b.limb[4])
|
||||
accum4 += bv * (uint64)(aa.limb[0])
|
||||
accum5 += bv * (uint64)(aa.limb[1])
|
||||
accum6 += bv * (uint64)(aa.limb[2])
|
||||
accum7 += bv * (uint64)(aa.limb[3])
|
||||
accum8 += bv * (uint64)(aa.limb[4])
|
||||
accum9 += bv * (uint64)(aa.limb[5])
|
||||
accum10 += bv * (uint64)(aa.limb[6])
|
||||
accum11 += bv * (uint64)(aa.limb[7])
|
||||
accum12 += bv * (uint64)(aa.limb[8])
|
||||
accum13 += bv * (uint64)(aa.limb[9])
|
||||
accum14 += bv * (uint64)(aa.limb[10])
|
||||
accum15 += bv * (uint64)(aa.limb[11])
|
||||
accum0 += bv * (uint64)(aa.limb[12])
|
||||
accum1 += bv * (uint64)(aa.limb[13])
|
||||
accum2 += bv * (uint64)(aa.limb[14])
|
||||
accum3 += bv * (uint64)(aa.limb[15])
|
||||
aa.limb[(x448Limbs-1-4)^(x448Limbs/2)] += aa.limb[x448Limbs-1-4]
|
||||
|
||||
bv = (uint64)(b.limb[5])
|
||||
accum5 += bv * (uint64)(aa.limb[0])
|
||||
accum6 += bv * (uint64)(aa.limb[1])
|
||||
accum7 += bv * (uint64)(aa.limb[2])
|
||||
accum8 += bv * (uint64)(aa.limb[3])
|
||||
accum9 += bv * (uint64)(aa.limb[4])
|
||||
accum10 += bv * (uint64)(aa.limb[5])
|
||||
accum11 += bv * (uint64)(aa.limb[6])
|
||||
accum12 += bv * (uint64)(aa.limb[7])
|
||||
accum13 += bv * (uint64)(aa.limb[8])
|
||||
accum14 += bv * (uint64)(aa.limb[9])
|
||||
accum15 += bv * (uint64)(aa.limb[10])
|
||||
accum0 += bv * (uint64)(aa.limb[11])
|
||||
accum1 += bv * (uint64)(aa.limb[12])
|
||||
accum2 += bv * (uint64)(aa.limb[13])
|
||||
accum3 += bv * (uint64)(aa.limb[14])
|
||||
accum4 += bv * (uint64)(aa.limb[15])
|
||||
aa.limb[(x448Limbs-1-5)^(x448Limbs/2)] += aa.limb[x448Limbs-1-5]
|
||||
|
||||
bv = (uint64)(b.limb[6])
|
||||
accum6 += bv * (uint64)(aa.limb[0])
|
||||
accum7 += bv * (uint64)(aa.limb[1])
|
||||
accum8 += bv * (uint64)(aa.limb[2])
|
||||
accum9 += bv * (uint64)(aa.limb[3])
|
||||
accum10 += bv * (uint64)(aa.limb[4])
|
||||
accum11 += bv * (uint64)(aa.limb[5])
|
||||
accum12 += bv * (uint64)(aa.limb[6])
|
||||
accum13 += bv * (uint64)(aa.limb[7])
|
||||
accum14 += bv * (uint64)(aa.limb[8])
|
||||
accum15 += bv * (uint64)(aa.limb[9])
|
||||
accum0 += bv * (uint64)(aa.limb[10])
|
||||
accum1 += bv * (uint64)(aa.limb[11])
|
||||
accum2 += bv * (uint64)(aa.limb[12])
|
||||
accum3 += bv * (uint64)(aa.limb[13])
|
||||
accum4 += bv * (uint64)(aa.limb[14])
|
||||
accum5 += bv * (uint64)(aa.limb[15])
|
||||
aa.limb[(x448Limbs-1-6)^(x448Limbs/2)] += aa.limb[x448Limbs-1-6]
|
||||
|
||||
bv = (uint64)(b.limb[7])
|
||||
accum7 += bv * (uint64)(aa.limb[0])
|
||||
accum8 += bv * (uint64)(aa.limb[1])
|
||||
accum9 += bv * (uint64)(aa.limb[2])
|
||||
accum10 += bv * (uint64)(aa.limb[3])
|
||||
accum11 += bv * (uint64)(aa.limb[4])
|
||||
accum12 += bv * (uint64)(aa.limb[5])
|
||||
accum13 += bv * (uint64)(aa.limb[6])
|
||||
accum14 += bv * (uint64)(aa.limb[7])
|
||||
accum15 += bv * (uint64)(aa.limb[8])
|
||||
accum0 += bv * (uint64)(aa.limb[9])
|
||||
accum1 += bv * (uint64)(aa.limb[10])
|
||||
accum2 += bv * (uint64)(aa.limb[11])
|
||||
accum3 += bv * (uint64)(aa.limb[12])
|
||||
accum4 += bv * (uint64)(aa.limb[13])
|
||||
accum5 += bv * (uint64)(aa.limb[14])
|
||||
accum6 += bv * (uint64)(aa.limb[15])
|
||||
aa.limb[(x448Limbs-1-7)^(x448Limbs/2)] += aa.limb[x448Limbs-1-7]
|
||||
|
||||
bv = (uint64)(b.limb[8])
|
||||
accum8 += bv * (uint64)(aa.limb[0])
|
||||
accum9 += bv * (uint64)(aa.limb[1])
|
||||
accum10 += bv * (uint64)(aa.limb[2])
|
||||
accum11 += bv * (uint64)(aa.limb[3])
|
||||
accum12 += bv * (uint64)(aa.limb[4])
|
||||
accum13 += bv * (uint64)(aa.limb[5])
|
||||
accum14 += bv * (uint64)(aa.limb[6])
|
||||
accum15 += bv * (uint64)(aa.limb[7])
|
||||
accum0 += bv * (uint64)(aa.limb[8])
|
||||
accum1 += bv * (uint64)(aa.limb[9])
|
||||
accum2 += bv * (uint64)(aa.limb[10])
|
||||
accum3 += bv * (uint64)(aa.limb[11])
|
||||
accum4 += bv * (uint64)(aa.limb[12])
|
||||
accum5 += bv * (uint64)(aa.limb[13])
|
||||
accum6 += bv * (uint64)(aa.limb[14])
|
||||
accum7 += bv * (uint64)(aa.limb[15])
|
||||
aa.limb[(x448Limbs-1-8)^(x448Limbs/2)] += aa.limb[x448Limbs-1-8]
|
||||
|
||||
bv = (uint64)(b.limb[9])
|
||||
accum9 += bv * (uint64)(aa.limb[0])
|
||||
accum10 += bv * (uint64)(aa.limb[1])
|
||||
accum11 += bv * (uint64)(aa.limb[2])
|
||||
accum12 += bv * (uint64)(aa.limb[3])
|
||||
accum13 += bv * (uint64)(aa.limb[4])
|
||||
accum14 += bv * (uint64)(aa.limb[5])
|
||||
accum15 += bv * (uint64)(aa.limb[6])
|
||||
accum0 += bv * (uint64)(aa.limb[7])
|
||||
accum1 += bv * (uint64)(aa.limb[8])
|
||||
accum2 += bv * (uint64)(aa.limb[9])
|
||||
accum3 += bv * (uint64)(aa.limb[10])
|
||||
accum4 += bv * (uint64)(aa.limb[11])
|
||||
accum5 += bv * (uint64)(aa.limb[12])
|
||||
accum6 += bv * (uint64)(aa.limb[13])
|
||||
accum7 += bv * (uint64)(aa.limb[14])
|
||||
accum8 += bv * (uint64)(aa.limb[15])
|
||||
aa.limb[(x448Limbs-1-9)^(x448Limbs/2)] += aa.limb[x448Limbs-1-9]
|
||||
|
||||
bv = (uint64)(b.limb[10])
|
||||
accum10 += bv * (uint64)(aa.limb[0])
|
||||
accum11 += bv * (uint64)(aa.limb[1])
|
||||
accum12 += bv * (uint64)(aa.limb[2])
|
||||
accum13 += bv * (uint64)(aa.limb[3])
|
||||
accum14 += bv * (uint64)(aa.limb[4])
|
||||
accum15 += bv * (uint64)(aa.limb[5])
|
||||
accum0 += bv * (uint64)(aa.limb[6])
|
||||
accum1 += bv * (uint64)(aa.limb[7])
|
||||
accum2 += bv * (uint64)(aa.limb[8])
|
||||
accum3 += bv * (uint64)(aa.limb[9])
|
||||
accum4 += bv * (uint64)(aa.limb[10])
|
||||
accum5 += bv * (uint64)(aa.limb[11])
|
||||
accum6 += bv * (uint64)(aa.limb[12])
|
||||
accum7 += bv * (uint64)(aa.limb[13])
|
||||
accum8 += bv * (uint64)(aa.limb[14])
|
||||
accum9 += bv * (uint64)(aa.limb[15])
|
||||
aa.limb[(x448Limbs-1-10)^(x448Limbs/2)] += aa.limb[x448Limbs-1-10]
|
||||
|
||||
bv = (uint64)(b.limb[11])
|
||||
accum11 += bv * (uint64)(aa.limb[0])
|
||||
accum12 += bv * (uint64)(aa.limb[1])
|
||||
accum13 += bv * (uint64)(aa.limb[2])
|
||||
accum14 += bv * (uint64)(aa.limb[3])
|
||||
accum15 += bv * (uint64)(aa.limb[4])
|
||||
accum0 += bv * (uint64)(aa.limb[5])
|
||||
accum1 += bv * (uint64)(aa.limb[6])
|
||||
accum2 += bv * (uint64)(aa.limb[7])
|
||||
accum3 += bv * (uint64)(aa.limb[8])
|
||||
accum4 += bv * (uint64)(aa.limb[9])
|
||||
accum5 += bv * (uint64)(aa.limb[10])
|
||||
accum6 += bv * (uint64)(aa.limb[11])
|
||||
accum7 += bv * (uint64)(aa.limb[12])
|
||||
accum8 += bv * (uint64)(aa.limb[13])
|
||||
accum9 += bv * (uint64)(aa.limb[14])
|
||||
accum10 += bv * (uint64)(aa.limb[15])
|
||||
aa.limb[(x448Limbs-1-11)^(x448Limbs/2)] += aa.limb[x448Limbs-1-11]
|
||||
|
||||
bv = (uint64)(b.limb[12])
|
||||
accum12 += bv * (uint64)(aa.limb[0])
|
||||
accum13 += bv * (uint64)(aa.limb[1])
|
||||
accum14 += bv * (uint64)(aa.limb[2])
|
||||
accum15 += bv * (uint64)(aa.limb[3])
|
||||
accum0 += bv * (uint64)(aa.limb[4])
|
||||
accum1 += bv * (uint64)(aa.limb[5])
|
||||
accum2 += bv * (uint64)(aa.limb[6])
|
||||
accum3 += bv * (uint64)(aa.limb[7])
|
||||
accum4 += bv * (uint64)(aa.limb[8])
|
||||
accum5 += bv * (uint64)(aa.limb[9])
|
||||
accum6 += bv * (uint64)(aa.limb[10])
|
||||
accum7 += bv * (uint64)(aa.limb[11])
|
||||
accum8 += bv * (uint64)(aa.limb[12])
|
||||
accum9 += bv * (uint64)(aa.limb[13])
|
||||
accum10 += bv * (uint64)(aa.limb[14])
|
||||
accum11 += bv * (uint64)(aa.limb[15])
|
||||
aa.limb[(x448Limbs-1-12)^(x448Limbs/2)] += aa.limb[x448Limbs-1-12]
|
||||
|
||||
bv = (uint64)(b.limb[13])
|
||||
accum13 += bv * (uint64)(aa.limb[0])
|
||||
accum14 += bv * (uint64)(aa.limb[1])
|
||||
accum15 += bv * (uint64)(aa.limb[2])
|
||||
accum0 += bv * (uint64)(aa.limb[3])
|
||||
accum1 += bv * (uint64)(aa.limb[4])
|
||||
accum2 += bv * (uint64)(aa.limb[5])
|
||||
accum3 += bv * (uint64)(aa.limb[6])
|
||||
accum4 += bv * (uint64)(aa.limb[7])
|
||||
accum5 += bv * (uint64)(aa.limb[8])
|
||||
accum6 += bv * (uint64)(aa.limb[9])
|
||||
accum7 += bv * (uint64)(aa.limb[10])
|
||||
accum8 += bv * (uint64)(aa.limb[11])
|
||||
accum9 += bv * (uint64)(aa.limb[12])
|
||||
accum10 += bv * (uint64)(aa.limb[13])
|
||||
accum11 += bv * (uint64)(aa.limb[14])
|
||||
accum12 += bv * (uint64)(aa.limb[15])
|
||||
aa.limb[(x448Limbs-1-13)^(x448Limbs/2)] += aa.limb[x448Limbs-1-13]
|
||||
|
||||
bv = (uint64)(b.limb[14])
|
||||
accum14 += bv * (uint64)(aa.limb[0])
|
||||
accum15 += bv * (uint64)(aa.limb[1])
|
||||
accum0 += bv * (uint64)(aa.limb[2])
|
||||
accum1 += bv * (uint64)(aa.limb[3])
|
||||
accum2 += bv * (uint64)(aa.limb[4])
|
||||
accum3 += bv * (uint64)(aa.limb[5])
|
||||
accum4 += bv * (uint64)(aa.limb[6])
|
||||
accum5 += bv * (uint64)(aa.limb[7])
|
||||
accum6 += bv * (uint64)(aa.limb[8])
|
||||
accum7 += bv * (uint64)(aa.limb[9])
|
||||
accum8 += bv * (uint64)(aa.limb[10])
|
||||
accum9 += bv * (uint64)(aa.limb[11])
|
||||
accum10 += bv * (uint64)(aa.limb[12])
|
||||
accum11 += bv * (uint64)(aa.limb[13])
|
||||
accum12 += bv * (uint64)(aa.limb[14])
|
||||
accum13 += bv * (uint64)(aa.limb[15])
|
||||
aa.limb[(x448Limbs-1-14)^(x448Limbs/2)] += aa.limb[x448Limbs-1-14]
|
||||
|
||||
bv = (uint64)(b.limb[15])
|
||||
accum15 += bv * (uint64)(aa.limb[0])
|
||||
accum0 += bv * (uint64)(aa.limb[1])
|
||||
accum1 += bv * (uint64)(aa.limb[2])
|
||||
accum2 += bv * (uint64)(aa.limb[3])
|
||||
accum3 += bv * (uint64)(aa.limb[4])
|
||||
accum4 += bv * (uint64)(aa.limb[5])
|
||||
accum5 += bv * (uint64)(aa.limb[6])
|
||||
accum6 += bv * (uint64)(aa.limb[7])
|
||||
accum7 += bv * (uint64)(aa.limb[8])
|
||||
accum8 += bv * (uint64)(aa.limb[9])
|
||||
accum9 += bv * (uint64)(aa.limb[10])
|
||||
accum10 += bv * (uint64)(aa.limb[11])
|
||||
accum11 += bv * (uint64)(aa.limb[12])
|
||||
accum12 += bv * (uint64)(aa.limb[13])
|
||||
accum13 += bv * (uint64)(aa.limb[14])
|
||||
accum14 += bv * (uint64)(aa.limb[15])
|
||||
aa.limb[(x448Limbs-1-15)^(x448Limbs/2)] += aa.limb[x448Limbs-1-15]
|
||||
|
||||
// accum[x448Limbs-1] += accum[x448Limbs-2] >> lBits
|
||||
// accum[x448Limbs-2] &= lMask
|
||||
// accum[x448Limbs/2] += accum[x448Limbs-1] >> lBits
|
||||
accum15 += accum14 >> lBits
|
||||
accum14 &= lMask
|
||||
accum8 += accum15 >> lBits
|
||||
|
||||
// for j := uint(0); j < x448Limbs; j++ {
|
||||
// accum[j] += accum[(j-1)%x448Limbs] >> lBits
|
||||
// accum[(j-1)%x448Limbs] &= lMask
|
||||
// }
|
||||
accum0 += accum15 >> lBits
|
||||
accum15 &= lMask
|
||||
accum1 += accum0 >> lBits
|
||||
accum0 &= lMask
|
||||
accum2 += accum1 >> lBits
|
||||
accum1 &= lMask
|
||||
accum3 += accum2 >> lBits
|
||||
accum2 &= lMask
|
||||
accum4 += accum3 >> lBits
|
||||
accum3 &= lMask
|
||||
accum5 += accum4 >> lBits
|
||||
accum4 &= lMask
|
||||
accum6 += accum5 >> lBits
|
||||
accum5 &= lMask
|
||||
accum7 += accum6 >> lBits
|
||||
accum6 &= lMask
|
||||
accum8 += accum7 >> lBits
|
||||
accum7 &= lMask
|
||||
accum9 += accum8 >> lBits
|
||||
accum8 &= lMask
|
||||
accum10 += accum9 >> lBits
|
||||
accum9 &= lMask
|
||||
accum11 += accum10 >> lBits
|
||||
accum10 &= lMask
|
||||
accum12 += accum11 >> lBits
|
||||
accum11 &= lMask
|
||||
accum13 += accum12 >> lBits
|
||||
accum12 &= lMask
|
||||
accum14 += accum13 >> lBits
|
||||
accum13 &= lMask
|
||||
accum15 += accum14 >> lBits
|
||||
accum14 &= lMask
|
||||
|
||||
// for j, accv := range accum {
|
||||
// c.limb[j] = (uint32)(accv)
|
||||
// }
|
||||
c.limb[0] = (uint32)(accum0)
|
||||
c.limb[1] = (uint32)(accum1)
|
||||
c.limb[2] = (uint32)(accum2)
|
||||
c.limb[3] = (uint32)(accum3)
|
||||
c.limb[4] = (uint32)(accum4)
|
||||
c.limb[5] = (uint32)(accum5)
|
||||
c.limb[6] = (uint32)(accum6)
|
||||
c.limb[7] = (uint32)(accum7)
|
||||
c.limb[8] = (uint32)(accum8)
|
||||
c.limb[9] = (uint32)(accum9)
|
||||
c.limb[10] = (uint32)(accum10)
|
||||
c.limb[11] = (uint32)(accum11)
|
||||
c.limb[12] = (uint32)(accum12)
|
||||
c.limb[13] = (uint32)(accum13)
|
||||
c.limb[14] = (uint32)(accum14)
|
||||
c.limb[15] = (uint32)(accum15)
|
||||
}
|
||||
|
||||
// sqr squares (c = x * x). Just calls multiply. (PERF)
|
||||
func (c *gf) sqr(x *gf) {
|
||||
c.mul(x, x)
|
||||
}
|
||||
|
||||
// isqrt inverse square roots (y = 1/sqrt(x)), using an addition chain.
|
||||
func (y *gf) isqrt(x *gf) {
|
||||
var a, b, c gf
|
||||
c.sqr(x)
|
||||
|
||||
// XXX/Yawning, could unroll, but this is called only once.
|
||||
|
||||
// STEP(b,x,1);
|
||||
b.mul(x, &c)
|
||||
c.cpy(&b)
|
||||
for i := 0; i < 1; i++ {
|
||||
c.sqr(&c)
|
||||
}
|
||||
|
||||
// STEP(b,x,3);
|
||||
b.mul(x, &c)
|
||||
c.cpy(&b)
|
||||
for i := 0; i < 3; i++ {
|
||||
c.sqr(&c)
|
||||
}
|
||||
|
||||
//STEP(a,b,3);
|
||||
a.mul(&b, &c)
|
||||
c.cpy(&a)
|
||||
for i := 0; i < 3; i++ {
|
||||
c.sqr(&c)
|
||||
}
|
||||
|
||||
// STEP(a,b,9);
|
||||
a.mul(&b, &c)
|
||||
c.cpy(&a)
|
||||
for i := 0; i < 9; i++ {
|
||||
c.sqr(&c)
|
||||
}
|
||||
|
||||
// STEP(b,a,1);
|
||||
b.mul(&a, &c)
|
||||
c.cpy(&b)
|
||||
for i := 0; i < 1; i++ {
|
||||
c.sqr(&c)
|
||||
}
|
||||
|
||||
// STEP(a,x,18);
|
||||
a.mul(x, &c)
|
||||
c.cpy(&a)
|
||||
for i := 0; i < 18; i++ {
|
||||
c.sqr(&c)
|
||||
}
|
||||
|
||||
// STEP(a,b,37);
|
||||
a.mul(&b, &c)
|
||||
c.cpy(&a)
|
||||
for i := 0; i < 37; i++ {
|
||||
c.sqr(&c)
|
||||
}
|
||||
|
||||
// STEP(b,a,37);
|
||||
b.mul(&a, &c)
|
||||
c.cpy(&b)
|
||||
for i := 0; i < 37; i++ {
|
||||
c.sqr(&c)
|
||||
}
|
||||
|
||||
// STEP(b,a,111);
|
||||
b.mul(&a, &c)
|
||||
c.cpy(&b)
|
||||
for i := 0; i < 111; i++ {
|
||||
c.sqr(&c)
|
||||
}
|
||||
|
||||
// STEP(a,b,1);
|
||||
a.mul(&b, &c)
|
||||
c.cpy(&a)
|
||||
for i := 0; i < 1; i++ {
|
||||
c.sqr(&c)
|
||||
}
|
||||
|
||||
// STEP(b,x,223);
|
||||
b.mul(x, &c)
|
||||
c.cpy(&b)
|
||||
for i := 0; i < 223; i++ {
|
||||
c.sqr(&c)
|
||||
}
|
||||
|
||||
y.mul(&a, &c)
|
||||
}
|
||||
|
||||
// inv inverses (y = 1/x).
|
||||
func (y *gf) inv(x *gf) {
|
||||
var z, w gf
|
||||
z.sqr(x) // x^2
|
||||
w.isqrt(&z) // +- 1/sqrt(x^2) = +- 1/x
|
||||
z.sqr(&w) // 1/x^2
|
||||
w.mul(x, &z) // 1/x
|
||||
y.cpy(&w)
|
||||
}
|
||||
|
||||
// reduce weakly reduces mod p
|
||||
func (x *gf) reduce() {
|
||||
x.limb[x448Limbs/2] += x.limb[x448Limbs-1] >> lBits
|
||||
|
||||
// for j := uint(0); j < x448Limbs; j++ {
|
||||
// x.limb[j] += x.limb[(j-1)%x448Limbs] >> lBits
|
||||
// x.limb[(j-1)%x448Limbs] &= lMask
|
||||
// }
|
||||
x.limb[0] += x.limb[15] >> lBits
|
||||
x.limb[15] &= lMask
|
||||
x.limb[1] += x.limb[0] >> lBits
|
||||
x.limb[0] &= lMask
|
||||
x.limb[2] += x.limb[1] >> lBits
|
||||
x.limb[1] &= lMask
|
||||
x.limb[3] += x.limb[2] >> lBits
|
||||
x.limb[2] &= lMask
|
||||
x.limb[4] += x.limb[3] >> lBits
|
||||
x.limb[3] &= lMask
|
||||
x.limb[5] += x.limb[4] >> lBits
|
||||
x.limb[4] &= lMask
|
||||
x.limb[6] += x.limb[5] >> lBits
|
||||
x.limb[5] &= lMask
|
||||
x.limb[7] += x.limb[6] >> lBits
|
||||
x.limb[6] &= lMask
|
||||
x.limb[8] += x.limb[7] >> lBits
|
||||
x.limb[7] &= lMask
|
||||
x.limb[9] += x.limb[8] >> lBits
|
||||
x.limb[8] &= lMask
|
||||
x.limb[10] += x.limb[9] >> lBits
|
||||
x.limb[9] &= lMask
|
||||
x.limb[11] += x.limb[10] >> lBits
|
||||
x.limb[10] &= lMask
|
||||
x.limb[12] += x.limb[11] >> lBits
|
||||
x.limb[11] &= lMask
|
||||
x.limb[13] += x.limb[12] >> lBits
|
||||
x.limb[12] &= lMask
|
||||
x.limb[14] += x.limb[13] >> lBits
|
||||
x.limb[13] &= lMask
|
||||
x.limb[15] += x.limb[14] >> lBits
|
||||
x.limb[14] &= lMask
|
||||
}
|
||||
|
||||
// add adds mod p. Conservatively always weak-reduces. (PERF)
|
||||
func (x *gf) add(y, z *gf) {
|
||||
// for i, yv := range y.limb {
|
||||
// x.limb[i] = yv + z.limb[i]
|
||||
// }
|
||||
x.limb[0] = y.limb[0] + z.limb[0]
|
||||
x.limb[1] = y.limb[1] + z.limb[1]
|
||||
x.limb[2] = y.limb[2] + z.limb[2]
|
||||
x.limb[3] = y.limb[3] + z.limb[3]
|
||||
x.limb[4] = y.limb[4] + z.limb[4]
|
||||
x.limb[5] = y.limb[5] + z.limb[5]
|
||||
x.limb[6] = y.limb[6] + z.limb[6]
|
||||
x.limb[7] = y.limb[7] + z.limb[7]
|
||||
x.limb[8] = y.limb[8] + z.limb[8]
|
||||
x.limb[9] = y.limb[9] + z.limb[9]
|
||||
x.limb[10] = y.limb[10] + z.limb[10]
|
||||
x.limb[11] = y.limb[11] + z.limb[11]
|
||||
x.limb[12] = y.limb[12] + z.limb[12]
|
||||
x.limb[13] = y.limb[13] + z.limb[13]
|
||||
x.limb[14] = y.limb[14] + z.limb[14]
|
||||
x.limb[15] = y.limb[15] + z.limb[15]
|
||||
|
||||
x.reduce()
|
||||
}
|
||||
|
||||
// sub subtracts mod p. Conservatively always weak-reduces. (PERF)
|
||||
func (x *gf) sub(y, z *gf) {
|
||||
// for i, yv := range y.limb {
|
||||
// x.limb[i] = yv - z.limb[i] + 2*p.limb[i]
|
||||
// }
|
||||
x.limb[0] = y.limb[0] - z.limb[0] + 2*lMask
|
||||
x.limb[1] = y.limb[1] - z.limb[1] + 2*lMask
|
||||
x.limb[2] = y.limb[2] - z.limb[2] + 2*lMask
|
||||
x.limb[3] = y.limb[3] - z.limb[3] + 2*lMask
|
||||
x.limb[4] = y.limb[4] - z.limb[4] + 2*lMask
|
||||
x.limb[5] = y.limb[5] - z.limb[5] + 2*lMask
|
||||
x.limb[6] = y.limb[6] - z.limb[6] + 2*lMask
|
||||
x.limb[7] = y.limb[7] - z.limb[7] + 2*lMask
|
||||
x.limb[8] = y.limb[8] - z.limb[8] + 2*(lMask-1)
|
||||
x.limb[9] = y.limb[9] - z.limb[9] + 2*lMask
|
||||
x.limb[10] = y.limb[10] - z.limb[10] + 2*lMask
|
||||
x.limb[11] = y.limb[11] - z.limb[11] + 2*lMask
|
||||
x.limb[12] = y.limb[12] - z.limb[12] + 2*lMask
|
||||
x.limb[13] = y.limb[13] - z.limb[13] + 2*lMask
|
||||
x.limb[14] = y.limb[14] - z.limb[14] + 2*lMask
|
||||
x.limb[15] = y.limb[15] - z.limb[15] + 2*lMask
|
||||
|
||||
x.reduce()
|
||||
}
|
||||
|
||||
// condSwap swaps x and y in constant time.
|
||||
func (x *gf) condSwap(y *gf, swap limbUint) {
|
||||
// for i, xv := range x.limb {
|
||||
// s := (xv ^ y.limb[i]) & (uint32)(swap) // Sort of dumb, oh well.
|
||||
// x.limb[i] ^= s
|
||||
// y.limb[i] ^= s
|
||||
// }
|
||||
|
||||
var s uint32
|
||||
|
||||
s = (x.limb[0] ^ y.limb[0]) & (uint32)(swap)
|
||||
x.limb[0] ^= s
|
||||
y.limb[0] ^= s
|
||||
s = (x.limb[1] ^ y.limb[1]) & (uint32)(swap)
|
||||
x.limb[1] ^= s
|
||||
y.limb[1] ^= s
|
||||
s = (x.limb[2] ^ y.limb[2]) & (uint32)(swap)
|
||||
x.limb[2] ^= s
|
||||
y.limb[2] ^= s
|
||||
s = (x.limb[3] ^ y.limb[3]) & (uint32)(swap)
|
||||
x.limb[3] ^= s
|
||||
y.limb[3] ^= s
|
||||
s = (x.limb[4] ^ y.limb[4]) & (uint32)(swap)
|
||||
x.limb[4] ^= s
|
||||
y.limb[4] ^= s
|
||||
s = (x.limb[5] ^ y.limb[5]) & (uint32)(swap)
|
||||
x.limb[5] ^= s
|
||||
y.limb[5] ^= s
|
||||
s = (x.limb[6] ^ y.limb[6]) & (uint32)(swap)
|
||||
x.limb[6] ^= s
|
||||
y.limb[6] ^= s
|
||||
s = (x.limb[7] ^ y.limb[7]) & (uint32)(swap)
|
||||
x.limb[7] ^= s
|
||||
y.limb[7] ^= s
|
||||
s = (x.limb[8] ^ y.limb[8]) & (uint32)(swap)
|
||||
x.limb[8] ^= s
|
||||
y.limb[8] ^= s
|
||||
s = (x.limb[9] ^ y.limb[9]) & (uint32)(swap)
|
||||
x.limb[9] ^= s
|
||||
y.limb[9] ^= s
|
||||
s = (x.limb[10] ^ y.limb[10]) & (uint32)(swap)
|
||||
x.limb[10] ^= s
|
||||
y.limb[10] ^= s
|
||||
s = (x.limb[11] ^ y.limb[11]) & (uint32)(swap)
|
||||
x.limb[11] ^= s
|
||||
y.limb[11] ^= s
|
||||
s = (x.limb[12] ^ y.limb[12]) & (uint32)(swap)
|
||||
x.limb[12] ^= s
|
||||
y.limb[12] ^= s
|
||||
s = (x.limb[13] ^ y.limb[13]) & (uint32)(swap)
|
||||
x.limb[13] ^= s
|
||||
y.limb[13] ^= s
|
||||
s = (x.limb[14] ^ y.limb[14]) & (uint32)(swap)
|
||||
x.limb[14] ^= s
|
||||
y.limb[14] ^= s
|
||||
s = (x.limb[15] ^ y.limb[15]) & (uint32)(swap)
|
||||
x.limb[15] ^= s
|
||||
y.limb[15] ^= s
|
||||
}
|
||||
|
||||
// mlw multiplies by a signed int. NOT CONSTANT TIME wrt the sign of the int,
|
||||
// but that's ok because it's only ever called with w = -edwardsD. Just uses
|
||||
// a full multiply. (PERF)
|
||||
func (a *gf) mlw(b *gf, w int) {
|
||||
if w > 0 {
|
||||
ww := gf{[x448Limbs]uint32{(uint32)(w)}}
|
||||
a.mul(b, &ww)
|
||||
} else {
|
||||
// This branch is *NEVER* taken with the current code.
|
||||
panic("mul called with negative w")
|
||||
ww := gf{[x448Limbs]uint32{(uint32)(-w)}}
|
||||
a.mul(b, &ww)
|
||||
a.sub(&zero, a)
|
||||
}
|
||||
}
|
||||
|
||||
// canon canonicalizes.
|
||||
func (a *gf) canon() {
|
||||
a.reduce()
|
||||
|
||||
// Subtract p with borrow.
|
||||
var carry int64
|
||||
for i, v := range a.limb {
|
||||
carry = carry + (int64)(v) - (int64)(p.limb[i])
|
||||
a.limb[i] = (uint32)(carry & lMask)
|
||||
carry >>= lBits
|
||||
}
|
||||
|
||||
addback := carry
|
||||
carry = 0
|
||||
|
||||
// Add it back.
|
||||
for i, v := range a.limb {
|
||||
carry = carry + (int64)(v) + (int64)(p.limb[i]&(uint32)(addback))
|
||||
a.limb[i] = uint32(carry & lMask)
|
||||
carry >>= lBits
|
||||
}
|
||||
}
|
||||
|
||||
// deser deserializes into the limb representation.
|
||||
func (s *gf) deser(ser *[x448Bytes]byte) {
|
||||
var buf uint64
|
||||
bits := uint(0)
|
||||
k := 0
|
||||
|
||||
for i, v := range ser {
|
||||
buf |= (uint64)(v) << bits
|
||||
for bits += 8; (bits >= lBits || i == x448Bytes-1) && k < x448Limbs; bits, buf = bits-lBits, buf>>lBits {
|
||||
s.limb[k] = (uint32)(buf & lMask)
|
||||
k++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ser serializes into byte representation.
|
||||
func (a *gf) ser(ser *[x448Bytes]byte) {
|
||||
a.canon()
|
||||
k := 0
|
||||
bits := uint(0)
|
||||
var buf uint64
|
||||
for i, v := range a.limb {
|
||||
buf |= (uint64)(v) << bits
|
||||
for bits += lBits; (bits >= 8 || i == x448Limbs-1) && k < x448Bytes; bits, buf = bits-8, buf>>8 {
|
||||
ser[k] = (byte)(buf)
|
||||
k++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func init() {
|
||||
if x448Limbs != 16 {
|
||||
panic("x448Limbs != 16, unrolled loops likely broken")
|
||||
}
|
||||
}
|
||||
265
vendor/github.com/wg/ecies/vendor/schwanenlied.me/yawning/x448/x448_test.go
generated
vendored
Normal file
265
vendor/github.com/wg/ecies/vendor/schwanenlied.me/yawning/x448/x448_test.go
generated
vendored
Normal file
@@ -0,0 +1,265 @@
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2011 Stanford University.
|
||||
// Copyright (c) 2014-2015 Cryptography Research, Inc.
|
||||
// Copyright (c) 2015 Yawning Angel.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
package x448
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// Cowardly refuse to run the full slow test vector case unless this is set
|
||||
// at compile time, because the timeout for the test harness needs to be
|
||||
// adjusted at runtime.
|
||||
var reallyRunSlowTest = false
|
||||
|
||||
func TestX448(t *testing.T) {
|
||||
type KATVectors struct {
|
||||
scalar [x448Bytes]byte
|
||||
base [x448Bytes]byte
|
||||
answer [x448Bytes]byte
|
||||
}
|
||||
|
||||
vectors := []KATVectors{
|
||||
{
|
||||
[x448Bytes]byte{
|
||||
0x3d, 0x26, 0x2f, 0xdd, 0xf9, 0xec, 0x8e, 0x88,
|
||||
0x49, 0x52, 0x66, 0xfe, 0xa1, 0x9a, 0x34, 0xd2,
|
||||
0x88, 0x82, 0xac, 0xef, 0x04, 0x51, 0x04, 0xd0,
|
||||
0xd1, 0xaa, 0xe1, 0x21, 0x70, 0x0a, 0x77, 0x9c,
|
||||
0x98, 0x4c, 0x24, 0xf8, 0xcd, 0xd7, 0x8f, 0xbf,
|
||||
0xf4, 0x49, 0x43, 0xeb, 0xa3, 0x68, 0xf5, 0x4b,
|
||||
0x29, 0x25, 0x9a, 0x4f, 0x1c, 0x60, 0x0a, 0xd3,
|
||||
},
|
||||
[x448Bytes]byte{
|
||||
0x06, 0xfc, 0xe6, 0x40, 0xfa, 0x34, 0x87, 0xbf,
|
||||
0xda, 0x5f, 0x6c, 0xf2, 0xd5, 0x26, 0x3f, 0x8a,
|
||||
0xad, 0x88, 0x33, 0x4c, 0xbd, 0x07, 0x43, 0x7f,
|
||||
0x02, 0x0f, 0x08, 0xf9, 0x81, 0x4d, 0xc0, 0x31,
|
||||
0xdd, 0xbd, 0xc3, 0x8c, 0x19, 0xc6, 0xda, 0x25,
|
||||
0x83, 0xfa, 0x54, 0x29, 0xdb, 0x94, 0xad, 0xa1,
|
||||
0x8a, 0xa7, 0xa7, 0xfb, 0x4e, 0xf8, 0xa0, 0x86,
|
||||
},
|
||||
[x448Bytes]byte{
|
||||
0xce, 0x3e, 0x4f, 0xf9, 0x5a, 0x60, 0xdc, 0x66,
|
||||
0x97, 0xda, 0x1d, 0xb1, 0xd8, 0x5e, 0x6a, 0xfb,
|
||||
0xdf, 0x79, 0xb5, 0x0a, 0x24, 0x12, 0xd7, 0x54,
|
||||
0x6d, 0x5f, 0x23, 0x9f, 0xe1, 0x4f, 0xba, 0xad,
|
||||
0xeb, 0x44, 0x5f, 0xc6, 0x6a, 0x01, 0xb0, 0x77,
|
||||
0x9d, 0x98, 0x22, 0x39, 0x61, 0x11, 0x1e, 0x21,
|
||||
0x76, 0x62, 0x82, 0xf7, 0x3d, 0xd9, 0x6b, 0x6f,
|
||||
},
|
||||
},
|
||||
{
|
||||
[x448Bytes]byte{
|
||||
0x20, 0x3d, 0x49, 0x44, 0x28, 0xb8, 0x39, 0x93,
|
||||
0x52, 0x66, 0x5d, 0xdc, 0xa4, 0x2f, 0x9d, 0xe8,
|
||||
0xfe, 0xf6, 0x00, 0x90, 0x8e, 0x0d, 0x46, 0x1c,
|
||||
0xb0, 0x21, 0xf8, 0xc5, 0x38, 0x34, 0x5d, 0xd7,
|
||||
0x7c, 0x3e, 0x48, 0x06, 0xe2, 0x5f, 0x46, 0xd3,
|
||||
0x31, 0x5c, 0x44, 0xe0, 0xa5, 0xb4, 0x37, 0x12,
|
||||
0x82, 0xdd, 0x2c, 0x8d, 0x5b, 0xe3, 0x09, 0x5f,
|
||||
},
|
||||
[x448Bytes]byte{
|
||||
0x0f, 0xbc, 0xc2, 0xf9, 0x93, 0xcd, 0x56, 0xd3,
|
||||
0x30, 0x5b, 0x0b, 0x7d, 0x9e, 0x55, 0xd4, 0xc1,
|
||||
0xa8, 0xfb, 0x5d, 0xbb, 0x52, 0xf8, 0xe9, 0xa1,
|
||||
0xe9, 0xb6, 0x20, 0x1b, 0x16, 0x5d, 0x01, 0x58,
|
||||
0x94, 0xe5, 0x6c, 0x4d, 0x35, 0x70, 0xbe, 0xe5,
|
||||
0x2f, 0xe2, 0x05, 0xe2, 0x8a, 0x78, 0xb9, 0x1c,
|
||||
0xdf, 0xbd, 0xe7, 0x1c, 0xe8, 0xd1, 0x57, 0xdb,
|
||||
},
|
||||
[x448Bytes]byte{
|
||||
0x88, 0x4a, 0x02, 0x57, 0x62, 0x39, 0xff, 0x7a,
|
||||
0x2f, 0x2f, 0x63, 0xb2, 0xdb, 0x6a, 0x9f, 0xf3,
|
||||
0x70, 0x47, 0xac, 0x13, 0x56, 0x8e, 0x1e, 0x30,
|
||||
0xfe, 0x63, 0xc4, 0xa7, 0xad, 0x1b, 0x3e, 0xe3,
|
||||
0xa5, 0x70, 0x0d, 0xf3, 0x43, 0x21, 0xd6, 0x20,
|
||||
0x77, 0xe6, 0x36, 0x33, 0xc5, 0x75, 0xc1, 0xc9,
|
||||
0x54, 0x51, 0x4e, 0x99, 0xda, 0x7c, 0x17, 0x9d,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
var out [x448Bytes]byte
|
||||
for i, vec := range vectors {
|
||||
ret := ScalarMult(&out, &vec.scalar, &vec.base)
|
||||
if ret != 0 {
|
||||
t.Errorf("KAT[%d]: ScalarMultiply failed", i)
|
||||
}
|
||||
if !bytes.Equal(out[:], vec.answer[:]) {
|
||||
t.Errorf("KAT[%d]: Mismatch", i)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestX448IETFDraft(t *testing.T) {
|
||||
// Run the other test vectors from 5.2 of the IETF draft.
|
||||
|
||||
// WARNING: The full version of the test will easily take longer than the
|
||||
// default 10 min test timeout, even on a moderately powerful box.
|
||||
//
|
||||
// Unless reallyRunSlowTest is set in the source code, it will cowardly
|
||||
// refuse to run the full 1 million iterations, and the `go test`
|
||||
// timeout will need to be increased (`go test -timeout 30m`).
|
||||
|
||||
var k, u, out [x448Bytes] byte
|
||||
copy(k[:], basePoint[:])
|
||||
copy(u[:], basePoint[:])
|
||||
|
||||
for i := 0; i < 1000000; i++ {
|
||||
ret := ScalarMult(&out, &k, &u)
|
||||
if ret != 0 {
|
||||
t.Fatalf("Iterated[%d]: ScalarMultiply failed", i)
|
||||
}
|
||||
switch (i+1) {
|
||||
case 1:
|
||||
known, _ := hex.DecodeString("3f482c8a9f19b01e6c46ee9711d9dc14fd4bf67af30765c2ae2b846a4d23a8cd0db897086239492caf350b51f833868b9bc2b3bca9cf4113")
|
||||
if !bytes.Equal(out[:], known) {
|
||||
t.Fatalf("Iterated[%d]: Mismatch", i)
|
||||
}
|
||||
case 1000:
|
||||
known, _ := hex.DecodeString("aa3b4749d55b9daf1e5b00288826c467274ce3ebbdd5c17b975e09d4af6c67cf10d087202db88286e2b79fceea3ec353ef54faa26e219f38")
|
||||
if !bytes.Equal(out[:], known) {
|
||||
t.Fatalf("Iterated[%d]: Mismatch", i)
|
||||
}
|
||||
if testing.Short() || !reallyRunSlowTest {
|
||||
t.Skipf("Short test requested, skipping remaining, was correct at 1k")
|
||||
}
|
||||
}
|
||||
copy(u[:], k[:])
|
||||
copy(k[:], out[:])
|
||||
}
|
||||
known, _ := hex.DecodeString("077f453681caca3693198420bbe515cae0002472519b3e67661a7e89cab94695c8f4bcd66e61b9b9c946da8d524de3d69bd9d9d66b997e37")
|
||||
if !bytes.Equal(k[:], known) {
|
||||
t.Fatal("Final value mismatch")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCurve448(t *testing.T) {
|
||||
alicePriv := [x448Bytes]byte{
|
||||
0x9a, 0x8f, 0x49, 0x25, 0xd1, 0x51, 0x9f, 0x57,
|
||||
0x75, 0xcf, 0x46, 0xb0, 0x4b, 0x58, 0x00, 0xd4,
|
||||
0xee, 0x9e, 0xe8, 0xba, 0xe8, 0xbc, 0x55, 0x65,
|
||||
0xd4, 0x98, 0xc2, 0x8d, 0xd9, 0xc9, 0xba, 0xf5,
|
||||
0x74, 0xa9, 0x41, 0x97, 0x44, 0x89, 0x73, 0x91,
|
||||
0x00, 0x63, 0x82, 0xa6, 0xf1, 0x27, 0xab, 0x1d,
|
||||
0x9a, 0xc2, 0xd8, 0xc0, 0xa5, 0x98, 0x72, 0x6b,
|
||||
}
|
||||
|
||||
alicePub := [x448Bytes]byte{
|
||||
0x9b, 0x08, 0xf7, 0xcc, 0x31, 0xb7, 0xe3, 0xe6,
|
||||
0x7d, 0x22, 0xd5, 0xae, 0xa1, 0x21, 0x07, 0x4a,
|
||||
0x27, 0x3b, 0xd2, 0xb8, 0x3d, 0xe0, 0x9c, 0x63,
|
||||
0xfa, 0xa7, 0x3d, 0x2c, 0x22, 0xc5, 0xd9, 0xbb,
|
||||
0xc8, 0x36, 0x64, 0x72, 0x41, 0xd9, 0x53, 0xd4,
|
||||
0x0c, 0x5b, 0x12, 0xda, 0x88, 0x12, 0x0d, 0x53,
|
||||
0x17, 0x7f, 0x80, 0xe5, 0x32, 0xc4, 0x1f, 0xa0,
|
||||
}
|
||||
|
||||
bobPriv := [x448Bytes]byte{
|
||||
0x1c, 0x30, 0x6a, 0x7a, 0xc2, 0xa0, 0xe2, 0xe0,
|
||||
0x99, 0x0b, 0x29, 0x44, 0x70, 0xcb, 0xa3, 0x39,
|
||||
0xe6, 0x45, 0x37, 0x72, 0xb0, 0x75, 0x81, 0x1d,
|
||||
0x8f, 0xad, 0x0d, 0x1d, 0x69, 0x27, 0xc1, 0x20,
|
||||
0xbb, 0x5e, 0xe8, 0x97, 0x2b, 0x0d, 0x3e, 0x21,
|
||||
0x37, 0x4c, 0x9c, 0x92, 0x1b, 0x09, 0xd1, 0xb0,
|
||||
0x36, 0x6f, 0x10, 0xb6, 0x51, 0x73, 0x99, 0x2d,
|
||||
}
|
||||
|
||||
bobPub := [x448Bytes]byte{
|
||||
0x3e, 0xb7, 0xa8, 0x29, 0xb0, 0xcd, 0x20, 0xf5,
|
||||
0xbc, 0xfc, 0x0b, 0x59, 0x9b, 0x6f, 0xec, 0xcf,
|
||||
0x6d, 0xa4, 0x62, 0x71, 0x07, 0xbd, 0xb0, 0xd4,
|
||||
0xf3, 0x45, 0xb4, 0x30, 0x27, 0xd8, 0xb9, 0x72,
|
||||
0xfc, 0x3e, 0x34, 0xfb, 0x42, 0x32, 0xa1, 0x3c,
|
||||
0xa7, 0x06, 0xdc, 0xb5, 0x7a, 0xec, 0x3d, 0xae,
|
||||
0x07, 0xbd, 0xc1, 0xc6, 0x7b, 0xf3, 0x36, 0x09,
|
||||
}
|
||||
|
||||
aliceBob := [x448Bytes]byte{
|
||||
0x07, 0xff, 0xf4, 0x18, 0x1a, 0xc6, 0xcc, 0x95,
|
||||
0xec, 0x1c, 0x16, 0xa9, 0x4a, 0x0f, 0x74, 0xd1,
|
||||
0x2d, 0xa2, 0x32, 0xce, 0x40, 0xa7, 0x75, 0x52,
|
||||
0x28, 0x1d, 0x28, 0x2b, 0xb6, 0x0c, 0x0b, 0x56,
|
||||
0xfd, 0x24, 0x64, 0xc3, 0x35, 0x54, 0x39, 0x36,
|
||||
0x52, 0x1c, 0x24, 0x40, 0x30, 0x85, 0xd5, 0x9a,
|
||||
0x44, 0x9a, 0x50, 0x37, 0x51, 0x4a, 0x87, 0x9d,
|
||||
}
|
||||
|
||||
var out [x448Bytes]byte
|
||||
ret := ScalarBaseMult(&out, &alicePriv)
|
||||
if ret != 0 {
|
||||
t.Error("Alice: ScalarBaseMult failed")
|
||||
}
|
||||
if !bytes.Equal(out[:], alicePub[:]) {
|
||||
t.Error("Alice: ScalarBaseMult Mismatch")
|
||||
}
|
||||
ret = ScalarBaseMult(&out, &bobPriv)
|
||||
if ret != 0 {
|
||||
t.Error("Bob: ScalarBaseMult failed")
|
||||
}
|
||||
if !bytes.Equal(out[:], bobPub[:]) {
|
||||
t.Error("Bob: ScalarBaseMult Mismatch")
|
||||
}
|
||||
ret = ScalarMult(&out, &bobPriv, &alicePub)
|
||||
if ret != 0 {
|
||||
t.Error("Bob: ScalarMult failed")
|
||||
}
|
||||
if !bytes.Equal(out[:], aliceBob[:]) {
|
||||
t.Error("Bob: ScalarMult Mismatch")
|
||||
}
|
||||
ret = ScalarMult(&out, &alicePriv, &bobPub)
|
||||
if ret != 0 {
|
||||
t.Error("Alice: ScalarMult failed")
|
||||
}
|
||||
if !bytes.Equal(out[:], aliceBob[:]) {
|
||||
t.Error("Alice: ScalarMult Mismatch")
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkECDH(b *testing.B) {
|
||||
var sa, sb, pa, pb, ab, ba [x448Bytes]byte
|
||||
ret := 0
|
||||
|
||||
rand.Read(sa[:])
|
||||
rand.Read(sb[:])
|
||||
b.ResetTimer()
|
||||
b.StopTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
ret |= ScalarBaseMult(&pa, &sa)
|
||||
ret |= ScalarBaseMult(&pb, &sb)
|
||||
b.StartTimer()
|
||||
ret |= ScalarMult(&ab, &sa, &pb)
|
||||
b.StopTimer()
|
||||
ret |= ScalarMult(&ba, &sb, &pa)
|
||||
if !bytes.Equal(ab[:], ba[:]) {
|
||||
b.Fatal("Alice/Bob: Mismatch")
|
||||
}
|
||||
copy(sa[:], pa[:])
|
||||
copy(sb[:], pb[:])
|
||||
}
|
||||
}
|
||||
75
vendor/github.com/wg/ecies/xchacha20poly1305/xchacha20poly1305.go
generated
vendored
Normal file
75
vendor/github.com/wg/ecies/xchacha20poly1305/xchacha20poly1305.go
generated
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
// Copyright (C) 2016 - Will Glozer. All rights reserved.
|
||||
|
||||
// Package xchacha20poly1305 implements an AEAD construction
|
||||
// similar to NaCl's xsalsa20poly1305 secretbox, but using
|
||||
// XChaCha20 instead of XSalsa20.
|
||||
package xchacha20poly1305
|
||||
|
||||
import (
|
||||
"schwanenlied.me/yawning/chacha20"
|
||||
"schwanenlied.me/yawning/poly1305"
|
||||
)
|
||||
|
||||
const (
|
||||
KeySize = chacha20.KeySize
|
||||
NonceSize = chacha20.XNonceSize
|
||||
TagSize = poly1305.Size
|
||||
)
|
||||
|
||||
type XChaCha20Poly1305 struct {
|
||||
chacha20.Cipher
|
||||
poly1305.Poly1305
|
||||
}
|
||||
|
||||
func New(key *[KeySize]byte, nonce *[NonceSize]byte) *XChaCha20Poly1305 {
|
||||
x := &XChaCha20Poly1305{}
|
||||
x.Init(key[:], nonce[:])
|
||||
return x
|
||||
}
|
||||
|
||||
func (x *XChaCha20Poly1305) Init(key, nonce []byte) error {
|
||||
err := x.ReKey(key, nonce)
|
||||
if err == nil {
|
||||
x.initPoly1305()
|
||||
x.Seek(1)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (x *XChaCha20Poly1305) Auth(src []byte) {
|
||||
if len(src) > 0 {
|
||||
x.Poly1305.Write(src)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *XChaCha20Poly1305) Decrypt(dst, src []byte) {
|
||||
x.Poly1305.Write(src)
|
||||
x.XORKeyStream(dst, src)
|
||||
}
|
||||
|
||||
func (x *XChaCha20Poly1305) Encrypt(dst, src []byte) {
|
||||
n := len(src)
|
||||
x.XORKeyStream(dst, src)
|
||||
x.Poly1305.Write(dst[:n])
|
||||
}
|
||||
|
||||
func (x *XChaCha20Poly1305) Tag(b []byte) []byte {
|
||||
return x.Poly1305.Sum(b)
|
||||
}
|
||||
|
||||
func (x *XChaCha20Poly1305) Reset() {
|
||||
x.Cipher.Reset()
|
||||
}
|
||||
|
||||
func (x *XChaCha20Poly1305) TagSize() int {
|
||||
return TagSize
|
||||
}
|
||||
|
||||
func (x *XChaCha20Poly1305) initPoly1305() {
|
||||
var key [poly1305.KeySize]byte
|
||||
x.KeyStream(key[:])
|
||||
x.Poly1305.Init(key[:])
|
||||
for i := range key {
|
||||
key[i] = 0
|
||||
}
|
||||
}
|
||||
65
vendor/github.com/wg/ecies/xchacha20poly1305/xchacha20poly1305_test.go
generated
vendored
Normal file
65
vendor/github.com/wg/ecies/xchacha20poly1305/xchacha20poly1305_test.go
generated
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
// Copyright (C) 2016 - Will Glozer. All rights reserved.
|
||||
|
||||
package xchacha20poly1305
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// plaintext & key from RFC 7539 with the 12-byte nonce repeated twice and
|
||||
// expected ciphertext derived from the SUPERCOP chacha20 reference impl.
|
||||
func TestXChaCha20(t *testing.T) {
|
||||
plaintext := []byte{
|
||||
0x4c, 0x61, 0x64, 0x69, 0x65, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x47, 0x65, 0x6e, 0x74, 0x6c,
|
||||
0x65, 0x6d, 0x65, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x61, 0x73,
|
||||
0x73, 0x20, 0x6f, 0x66, 0x20, 0x27, 0x39, 0x39, 0x3a, 0x20, 0x49, 0x66, 0x20, 0x49, 0x20, 0x63,
|
||||
0x6f, 0x75, 0x6c, 0x64, 0x20, 0x6f, 0x66, 0x66, 0x65, 0x72, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x6f,
|
||||
0x6e, 0x6c, 0x79, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x74, 0x69, 0x70, 0x20, 0x66, 0x6f, 0x72, 0x20,
|
||||
0x74, 0x68, 0x65, 0x20, 0x66, 0x75, 0x74, 0x75, 0x72, 0x65, 0x2c, 0x20, 0x73, 0x75, 0x6e, 0x73,
|
||||
0x63, 0x72, 0x65, 0x65, 0x6e, 0x20, 0x77, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x62, 0x65, 0x20, 0x69,
|
||||
0x74, 0x2e,
|
||||
}
|
||||
|
||||
key := []byte{
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
|
||||
}
|
||||
|
||||
nonce := []byte{
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x00,
|
||||
}
|
||||
|
||||
ciphertext := []byte{
|
||||
0x15, 0x62, 0x3c, 0xe5, 0x14, 0x3a, 0xd8, 0xc8, 0x46, 0x79, 0x0b, 0xc3, 0x8c, 0x5e, 0x81, 0x50,
|
||||
0x85, 0x1c, 0xd4, 0xa5, 0x30, 0xf5, 0xfa, 0xb8, 0x02, 0xe6, 0x1e, 0x87, 0x52, 0x91, 0x57, 0x9f,
|
||||
0x40, 0x0b, 0x2c, 0x57, 0x79, 0x95, 0xdf, 0x0c, 0xbc, 0xd9, 0x71, 0x30, 0x30, 0xad, 0x64, 0xee,
|
||||
0x93, 0x7d, 0xd2, 0xfa, 0x5c, 0x48, 0xff, 0xda, 0x7c, 0x91, 0xd1, 0x5b, 0xc3, 0x41, 0x3e, 0x33,
|
||||
0x55, 0x1d, 0x10, 0x97, 0x73, 0x0e, 0x40, 0x51, 0x4a, 0x1f, 0xf9, 0x04, 0xee, 0xb0, 0xe6, 0xd2,
|
||||
0x2a, 0x42, 0x79, 0xc0, 0xee, 0xe1, 0xb4, 0x92, 0x9c, 0x5a, 0xe4, 0x24, 0x21, 0xe0, 0x0f, 0x3e,
|
||||
0x3b, 0xa3, 0x0c, 0x7b, 0x7a, 0xa3, 0xfa, 0x0f, 0x9d, 0x7b, 0x69, 0xc4, 0x7f, 0xdf, 0x6d, 0xe5,
|
||||
0x35, 0xa3,
|
||||
}
|
||||
|
||||
tag := []byte{
|
||||
0x80, 0xdf, 0x98, 0xf1, 0xff, 0x1d, 0xc9, 0xc8, 0xdd, 0x08, 0xeb, 0xf8, 0x45, 0x1c, 0x8b, 0xd2,
|
||||
}
|
||||
|
||||
c := XChaCha20Poly1305{}
|
||||
|
||||
err := c.Init(key, nonce)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
c.Encrypt(plaintext, plaintext)
|
||||
|
||||
if !bytes.Equal(plaintext, ciphertext) {
|
||||
t.Fatal("encrypted plaintext != expected ciphertext")
|
||||
}
|
||||
|
||||
if !bytes.Equal(c.Tag(nil), tag) {
|
||||
t.Fatal("actual tag != expected tag")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user