From 0920a3ef12a58c466534854449a10e6cfa5c6834 Mon Sep 17 00:00:00 2001
From: Aleksa Sarai <asarai@suse.de>
Date: Fri, 29 Apr 2022 12:44:21 +1000
Subject: [PATCH 6/6] bsc1193930: vendor: update golang.org/x/crypto

This is necessary to fix several security issues that Docker hasn't
backported to their CE branch:

 * CVE-2022-27191
 * CVE-2021-43565

SUSE-Bugs: bsc#1193930 bsc#1197284
Signed-off-by: Aleksa Sarai <asarai@suse.de>
---
 vendor.conf                                   |    2 +-
 vendor/golang.org/x/crypto/README.md          |    2 +
 vendor/golang.org/x/crypto/acme/acme.go       |  805 +++++
 .../x/crypto/acme/autocert/autocert.go        | 1193 ++++++++
 .../x/crypto/acme/autocert/cache.go           |  136 +
 .../acme/autocert/internal/acmetest/ca.go     |  762 +++++
 .../x/crypto/acme/autocert/listener.go        |  155 +
 .../x/crypto/acme/autocert/renewal.go         |  156 +
 vendor/golang.org/x/crypto/acme/http.go       |  325 ++
 .../crypto/acme/internal/acmeprobe/prober.go  |  433 +++
 vendor/golang.org/x/crypto/acme/jws.go        |  232 ++
 vendor/golang.org/x/crypto/acme/rfc8555.go    |  438 +++
 vendor/golang.org/x/crypto/acme/types.go      |  614 ++++
 .../golang.org/x/crypto/acme/version_go112.go |   28 +
 vendor/golang.org/x/crypto/argon2/argon2.go   |  285 ++
 vendor/golang.org/x/crypto/argon2/blake2b.go  |   53 +
 .../x/crypto/argon2/blamka_amd64.go           |   61 +
 .../golang.org/x/crypto/argon2/blamka_amd64.s |  244 ++
 .../x/crypto/argon2/blamka_generic.go         |  163 +
 .../golang.org/x/crypto/argon2/blamka_ref.go  |   16 +
 vendor/golang.org/x/crypto/bcrypt/base64.go   |   35 +
 vendor/golang.org/x/crypto/bcrypt/bcrypt.go   |  295 ++
 vendor/golang.org/x/crypto/blake2b/blake2b.go |  291 ++
 .../x/crypto/blake2b/blake2bAVX2_amd64.go     |   38 +
 .../x/crypto/blake2b/blake2bAVX2_amd64.s      |  745 +++++
 .../x/crypto/blake2b/blake2b_amd64.go         |   25 +
 .../x/crypto/blake2b/blake2b_amd64.s          |  279 ++
 .../x/crypto/blake2b/blake2b_generic.go       |  182 ++
 .../x/crypto/blake2b/blake2b_ref.go           |   12 +
 vendor/golang.org/x/crypto/blake2b/blake2x.go |  177 ++
 .../golang.org/x/crypto/blake2b/register.go   |   33 +
 vendor/golang.org/x/crypto/blake2s/blake2s.go |  246 ++
 .../x/crypto/blake2s/blake2s_386.go           |   33 +
 .../golang.org/x/crypto/blake2s/blake2s_386.s |  430 +++
 .../x/crypto/blake2s/blake2s_amd64.go         |   38 +
 .../x/crypto/blake2s/blake2s_amd64.s          |  433 +++
 .../x/crypto/blake2s/blake2s_generic.go       |  178 ++
 .../x/crypto/blake2s/blake2s_ref.go           |   18 +
 vendor/golang.org/x/crypto/blake2s/blake2x.go |  178 ++
 .../golang.org/x/crypto/blake2s/register.go   |   22 +
 vendor/golang.org/x/crypto/bn256/bn256.go     |  429 +++
 vendor/golang.org/x/crypto/bn256/constants.go |   44 +
 vendor/golang.org/x/crypto/bn256/curve.go     |  287 ++
 vendor/golang.org/x/crypto/bn256/gfp12.go     |  200 ++
 vendor/golang.org/x/crypto/bn256/gfp2.go      |  219 ++
 vendor/golang.org/x/crypto/bn256/gfp6.go      |  296 ++
 vendor/golang.org/x/crypto/bn256/optate.go    |  395 +++
 vendor/golang.org/x/crypto/bn256/twist.go     |  258 ++
 vendor/golang.org/x/crypto/cast5/cast5.go     |  533 ++++
 .../x/crypto/chacha20/chacha_arm64.go         |    3 +-
 .../x/crypto/chacha20/chacha_arm64.s          |    3 +-
 .../x/crypto/chacha20/chacha_noasm.go         |    3 +-
 .../x/crypto/chacha20/chacha_ppc64le.go       |    3 +-
 .../x/crypto/chacha20/chacha_ppc64le.s        |    3 +-
 .../x/crypto/chacha20/chacha_s390x.go         |    3 +-
 .../x/crypto/chacha20/chacha_s390x.s          |    3 +-
 .../chacha20poly1305/chacha20poly1305.go      |   98 +
 .../chacha20poly1305_amd64.go                 |   87 +
 .../chacha20poly1305/chacha20poly1305_amd64.s | 2696 +++++++++++++++++
 .../chacha20poly1305_generic.go               |   81 +
 .../chacha20poly1305_noasm.go                 |   16 +
 .../chacha20poly1305/xchacha20poly1305.go     |   86 +
 vendor/golang.org/x/crypto/codereview.cfg     |    1 +
 vendor/golang.org/x/crypto/cryptobyte/asn1.go |   59 +-
 .../x/crypto/curve25519/curve25519.go         |   52 +-
 .../x/crypto/curve25519/curve25519_amd64.go   |  240 --
 .../x/crypto/curve25519/curve25519_amd64.s    | 1793 -----------
 .../x/crypto/curve25519/curve25519_generic.go |  828 -----
 .../x/crypto/curve25519/curve25519_noasm.go   |   11 -
 .../x/crypto/curve25519/internal/field/README |    7 +
 .../internal/field/_asm/fe_amd64_asm.go       |  298 ++
 .../curve25519/internal/field/_asm/go.mod     |   10 +
 .../curve25519/internal/field/_asm/go.sum     |   34 +
 .../x/crypto/curve25519/internal/field/fe.go  |  416 +++
 .../curve25519/internal/field/fe_amd64.go     |   13 +
 .../curve25519/internal/field/fe_amd64.s      |  379 +++
 .../internal/field/fe_amd64_noasm.go          |   12 +
 .../curve25519/internal/field/fe_arm64.go     |   16 +
 .../curve25519/internal/field/fe_arm64.s      |   43 +
 .../internal/field/fe_arm64_noasm.go          |   12 +
 .../curve25519/internal/field/fe_generic.go   |  264 ++
 .../curve25519/internal/field/sync.checkpoint |    1 +
 .../crypto/curve25519/internal/field/sync.sh  |   19 +
 vendor/golang.org/x/crypto/ed25519/ed25519.go |  187 +-
 .../x/crypto/ed25519/ed25519_go113.go         |   73 -
 .../ed25519/internal/edwards25519/const.go    | 1422 ---------
 .../internal/edwards25519/edwards25519.go     | 1793 -----------
 vendor/golang.org/x/crypto/go.mod             |   10 +-
 vendor/golang.org/x/crypto/go.sum             |   11 +
 vendor/golang.org/x/crypto/hkdf/hkdf.go       |   93 +
 .../{ => internal}/poly1305/bits_compat.go    |    1 +
 .../{ => internal}/poly1305/bits_go1.13.go    |    1 +
 .../{ => internal}/poly1305/mac_noasm.go      |    3 +-
 .../{ => internal}/poly1305/poly1305.go       |    2 +-
 .../{ => internal}/poly1305/sum_amd64.go      |    3 +-
 .../{ => internal}/poly1305/sum_amd64.s       |    3 +-
 .../{ => internal}/poly1305/sum_generic.go    |    0
 .../{ => internal}/poly1305/sum_ppc64le.go    |    3 +-
 .../{ => internal}/poly1305/sum_ppc64le.s     |   21 +-
 .../{ => internal}/poly1305/sum_s390x.go      |    3 +-
 .../{ => internal}/poly1305/sum_s390x.s       |    5 +-
 .../x/crypto/internal/subtle/aliasing.go      |    3 +-
 ...iasing_appengine.go => aliasing_purego.go} |    3 +-
 .../x/crypto/internal/wycheproof/README.md    |   12 +
 .../internal/wycheproof/internal/dsa/dsa.go   |   33 +
 vendor/golang.org/x/crypto/md4/md4.go         |  122 +
 vendor/golang.org/x/crypto/md4/md4block.go    |   89 +
 vendor/golang.org/x/crypto/nacl/auth/auth.go  |   58 +
 vendor/golang.org/x/crypto/nacl/box/box.go    |  182 ++
 .../x/crypto/nacl/secretbox/secretbox.go      |    2 +-
 vendor/golang.org/x/crypto/ocsp/ocsp.go       |    2 +-
 .../x/crypto/openpgp/armor/armor.go           |  230 ++
 .../x/crypto/openpgp/armor/encode.go          |  160 +
 .../x/crypto/openpgp/canonical_text.go        |   59 +
 .../x/crypto/openpgp/clearsign/clearsign.go   |  424 +++
 .../x/crypto/openpgp/elgamal/elgamal.go       |  130 +
 .../x/crypto/openpgp/errors/errors.go         |   78 +
 vendor/golang.org/x/crypto/openpgp/keys.go    |  693 +++++
 .../x/crypto/openpgp/packet/compressed.go     |  123 +
 .../x/crypto/openpgp/packet/config.go         |   91 +
 .../x/crypto/openpgp/packet/encrypted_key.go  |  208 ++
 .../x/crypto/openpgp/packet/literal.go        |   89 +
 .../x/crypto/openpgp/packet/ocfb.go           |  143 +
 .../openpgp/packet/one_pass_signature.go      |   73 +
 .../x/crypto/openpgp/packet/opaque.go         |  162 +
 .../x/crypto/openpgp/packet/packet.go         |  590 ++++
 .../x/crypto/openpgp/packet/private_key.go    |  385 +++
 .../x/crypto/openpgp/packet/public_key.go     |  753 +++++
 .../x/crypto/openpgp/packet/public_key_v3.go  |  279 ++
 .../x/crypto/openpgp/packet/reader.go         |   76 +
 .../x/crypto/openpgp/packet/signature.go      |  731 +++++
 .../x/crypto/openpgp/packet/signature_v3.go   |  146 +
 .../openpgp/packet/symmetric_key_encrypted.go |  155 +
 .../openpgp/packet/symmetrically_encrypted.go |  290 ++
 .../x/crypto/openpgp/packet/userattribute.go  |   91 +
 .../x/crypto/openpgp/packet/userid.go         |  160 +
 vendor/golang.org/x/crypto/openpgp/read.go    |  448 +++
 vendor/golang.org/x/crypto/openpgp/s2k/s2k.go |  279 ++
 vendor/golang.org/x/crypto/openpgp/write.go   |  418 +++
 .../x/crypto/poly1305/poly1305_compat.go      |   91 +
 .../x/crypto/ripemd160/ripemd160.go           |  124 +
 .../x/crypto/ripemd160/ripemd160block.go      |  165 +
 .../x/crypto/salsa20/salsa/salsa20_amd64.go   |    3 +-
 .../x/crypto/salsa20/salsa/salsa20_amd64.s    |  238 +-
 .../x/crypto/salsa20/salsa/salsa20_noasm.go   |    3 +-
 vendor/golang.org/x/crypto/salsa20/salsa20.go |   58 +
 vendor/golang.org/x/crypto/scrypt/scrypt.go   |  212 ++
 vendor/golang.org/x/crypto/sha3/doc.go        |   66 +
 vendor/golang.org/x/crypto/sha3/hashes.go     |   97 +
 .../x/crypto/sha3/hashes_generic.go           |   28 +
 vendor/golang.org/x/crypto/sha3/keccakf.go    |  413 +++
 .../golang.org/x/crypto/sha3/keccakf_amd64.go |   14 +
 .../golang.org/x/crypto/sha3/keccakf_amd64.s  |  391 +++
 vendor/golang.org/x/crypto/sha3/register.go   |   19 +
 vendor/golang.org/x/crypto/sha3/sha3.go       |  193 ++
 vendor/golang.org/x/crypto/sha3/sha3_s390x.go |  285 ++
 vendor/golang.org/x/crypto/sha3/sha3_s390x.s  |   34 +
 vendor/golang.org/x/crypto/sha3/shake.go      |  173 ++
 .../golang.org/x/crypto/sha3/shake_generic.go |   20 +
 vendor/golang.org/x/crypto/sha3/xor.go        |   24 +
 .../golang.org/x/crypto/sha3/xor_generic.go   |   28 +
 .../golang.org/x/crypto/sha3/xor_unaligned.go |   68 +
 .../golang.org/x/crypto/ssh/agent/client.go   |  819 +++++
 .../golang.org/x/crypto/ssh/agent/forward.go  |  103 +
 .../golang.org/x/crypto/ssh/agent/keyring.go  |  241 ++
 .../golang.org/x/crypto/ssh/agent/server.go   |  570 ++++
 vendor/golang.org/x/crypto/ssh/certs.go       |   85 +-
 vendor/golang.org/x/crypto/ssh/cipher.go      |   10 +-
 vendor/golang.org/x/crypto/ssh/client.go      |   20 +-
 vendor/golang.org/x/crypto/ssh/client_auth.go |  132 +-
 vendor/golang.org/x/crypto/ssh/common.go      |   76 +-
 vendor/golang.org/x/crypto/ssh/handshake.go   |   81 +-
 vendor/golang.org/x/crypto/ssh/kex.go         |  186 +-
 vendor/golang.org/x/crypto/ssh/keys.go        |  149 +-
 .../x/crypto/ssh/knownhosts/knownhosts.go     |  540 ++++
 vendor/golang.org/x/crypto/ssh/messages.go    |   21 +-
 vendor/golang.org/x/crypto/ssh/server.go      |   50 +-
 vendor/golang.org/x/crypto/ssh/session.go     |    1 +
 .../x/crypto/ssh/terminal/terminal.go         |   76 +
 vendor/golang.org/x/crypto/ssh/transport.go   |   10 +-
 vendor/golang.org/x/crypto/tea/cipher.go      |  116 +
 vendor/golang.org/x/crypto/twofish/twofish.go |  348 +++
 vendor/golang.org/x/crypto/xtea/block.go      |   66 +
 vendor/golang.org/x/crypto/xtea/cipher.go     |   90 +
 vendor/golang.org/x/crypto/xts/xts.go         |  164 +
 185 files changed, 31570 insertions(+), 6780 deletions(-)
 create mode 100644 vendor/golang.org/x/crypto/acme/acme.go
 create mode 100644 vendor/golang.org/x/crypto/acme/autocert/autocert.go
 create mode 100644 vendor/golang.org/x/crypto/acme/autocert/cache.go
 create mode 100644 vendor/golang.org/x/crypto/acme/autocert/internal/acmetest/ca.go
 create mode 100644 vendor/golang.org/x/crypto/acme/autocert/listener.go
 create mode 100644 vendor/golang.org/x/crypto/acme/autocert/renewal.go
 create mode 100644 vendor/golang.org/x/crypto/acme/http.go
 create mode 100644 vendor/golang.org/x/crypto/acme/internal/acmeprobe/prober.go
 create mode 100644 vendor/golang.org/x/crypto/acme/jws.go
 create mode 100644 vendor/golang.org/x/crypto/acme/rfc8555.go
 create mode 100644 vendor/golang.org/x/crypto/acme/types.go
 create mode 100644 vendor/golang.org/x/crypto/acme/version_go112.go
 create mode 100644 vendor/golang.org/x/crypto/argon2/argon2.go
 create mode 100644 vendor/golang.org/x/crypto/argon2/blake2b.go
 create mode 100644 vendor/golang.org/x/crypto/argon2/blamka_amd64.go
 create mode 100644 vendor/golang.org/x/crypto/argon2/blamka_amd64.s
 create mode 100644 vendor/golang.org/x/crypto/argon2/blamka_generic.go
 create mode 100644 vendor/golang.org/x/crypto/argon2/blamka_ref.go
 create mode 100644 vendor/golang.org/x/crypto/bcrypt/base64.go
 create mode 100644 vendor/golang.org/x/crypto/bcrypt/bcrypt.go
 create mode 100644 vendor/golang.org/x/crypto/blake2b/blake2b.go
 create mode 100644 vendor/golang.org/x/crypto/blake2b/blake2bAVX2_amd64.go
 create mode 100644 vendor/golang.org/x/crypto/blake2b/blake2bAVX2_amd64.s
 create mode 100644 vendor/golang.org/x/crypto/blake2b/blake2b_amd64.go
 create mode 100644 vendor/golang.org/x/crypto/blake2b/blake2b_amd64.s
 create mode 100644 vendor/golang.org/x/crypto/blake2b/blake2b_generic.go
 create mode 100644 vendor/golang.org/x/crypto/blake2b/blake2b_ref.go
 create mode 100644 vendor/golang.org/x/crypto/blake2b/blake2x.go
 create mode 100644 vendor/golang.org/x/crypto/blake2b/register.go
 create mode 100644 vendor/golang.org/x/crypto/blake2s/blake2s.go
 create mode 100644 vendor/golang.org/x/crypto/blake2s/blake2s_386.go
 create mode 100644 vendor/golang.org/x/crypto/blake2s/blake2s_386.s
 create mode 100644 vendor/golang.org/x/crypto/blake2s/blake2s_amd64.go
 create mode 100644 vendor/golang.org/x/crypto/blake2s/blake2s_amd64.s
 create mode 100644 vendor/golang.org/x/crypto/blake2s/blake2s_generic.go
 create mode 100644 vendor/golang.org/x/crypto/blake2s/blake2s_ref.go
 create mode 100644 vendor/golang.org/x/crypto/blake2s/blake2x.go
 create mode 100644 vendor/golang.org/x/crypto/blake2s/register.go
 create mode 100644 vendor/golang.org/x/crypto/bn256/bn256.go
 create mode 100644 vendor/golang.org/x/crypto/bn256/constants.go
 create mode 100644 vendor/golang.org/x/crypto/bn256/curve.go
 create mode 100644 vendor/golang.org/x/crypto/bn256/gfp12.go
 create mode 100644 vendor/golang.org/x/crypto/bn256/gfp2.go
 create mode 100644 vendor/golang.org/x/crypto/bn256/gfp6.go
 create mode 100644 vendor/golang.org/x/crypto/bn256/optate.go
 create mode 100644 vendor/golang.org/x/crypto/bn256/twist.go
 create mode 100644 vendor/golang.org/x/crypto/cast5/cast5.go
 create mode 100644 vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305.go
 create mode 100644 vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.go
 create mode 100644 vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.s
 create mode 100644 vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_generic.go
 create mode 100644 vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_noasm.go
 create mode 100644 vendor/golang.org/x/crypto/chacha20poly1305/xchacha20poly1305.go
 create mode 100644 vendor/golang.org/x/crypto/codereview.cfg
 delete mode 100644 vendor/golang.org/x/crypto/curve25519/curve25519_amd64.go
 delete mode 100644 vendor/golang.org/x/crypto/curve25519/curve25519_amd64.s
 delete mode 100644 vendor/golang.org/x/crypto/curve25519/curve25519_generic.go
 delete mode 100644 vendor/golang.org/x/crypto/curve25519/curve25519_noasm.go
 create mode 100644 vendor/golang.org/x/crypto/curve25519/internal/field/README
 create mode 100644 vendor/golang.org/x/crypto/curve25519/internal/field/_asm/fe_amd64_asm.go
 create mode 100644 vendor/golang.org/x/crypto/curve25519/internal/field/_asm/go.mod
 create mode 100644 vendor/golang.org/x/crypto/curve25519/internal/field/_asm/go.sum
 create mode 100644 vendor/golang.org/x/crypto/curve25519/internal/field/fe.go
 create mode 100644 vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64.go
 create mode 100644 vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64.s
 create mode 100644 vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64_noasm.go
 create mode 100644 vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64.go
 create mode 100644 vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64.s
 create mode 100644 vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64_noasm.go
 create mode 100644 vendor/golang.org/x/crypto/curve25519/internal/field/fe_generic.go
 create mode 100644 vendor/golang.org/x/crypto/curve25519/internal/field/sync.checkpoint
 create mode 100755 vendor/golang.org/x/crypto/curve25519/internal/field/sync.sh
 delete mode 100644 vendor/golang.org/x/crypto/ed25519/ed25519_go113.go
 delete mode 100644 vendor/golang.org/x/crypto/ed25519/internal/edwards25519/const.go
 delete mode 100644 vendor/golang.org/x/crypto/ed25519/internal/edwards25519/edwards25519.go
 create mode 100644 vendor/golang.org/x/crypto/go.sum
 create mode 100644 vendor/golang.org/x/crypto/hkdf/hkdf.go
 rename vendor/golang.org/x/crypto/{ => internal}/poly1305/bits_compat.go (98%)
 rename vendor/golang.org/x/crypto/{ => internal}/poly1305/bits_go1.13.go (96%)
 rename vendor/golang.org/x/crypto/{ => internal}/poly1305/mac_noasm.go (66%)
 rename vendor/golang.org/x/crypto/{ => internal}/poly1305/poly1305.go (98%)
 rename vendor/golang.org/x/crypto/{ => internal}/poly1305/sum_amd64.go (95%)
 rename vendor/golang.org/x/crypto/{ => internal}/poly1305/sum_amd64.s (98%)
 rename vendor/golang.org/x/crypto/{ => internal}/poly1305/sum_generic.go (100%)
 rename vendor/golang.org/x/crypto/{ => internal}/poly1305/sum_ppc64le.go (95%)
 rename vendor/golang.org/x/crypto/{ => internal}/poly1305/sum_ppc64le.s (94%)
 rename vendor/golang.org/x/crypto/{ => internal}/poly1305/sum_s390x.go (97%)
 rename vendor/golang.org/x/crypto/{ => internal}/poly1305/sum_s390x.s (99%)
 rename vendor/golang.org/x/crypto/internal/subtle/{aliasing_appengine.go => aliasing_purego.go} (97%)
 create mode 100644 vendor/golang.org/x/crypto/internal/wycheproof/README.md
 create mode 100644 vendor/golang.org/x/crypto/internal/wycheproof/internal/dsa/dsa.go
 create mode 100644 vendor/golang.org/x/crypto/md4/md4.go
 create mode 100644 vendor/golang.org/x/crypto/md4/md4block.go
 create mode 100644 vendor/golang.org/x/crypto/nacl/auth/auth.go
 create mode 100644 vendor/golang.org/x/crypto/nacl/box/box.go
 create mode 100644 vendor/golang.org/x/crypto/openpgp/armor/armor.go
 create mode 100644 vendor/golang.org/x/crypto/openpgp/armor/encode.go
 create mode 100644 vendor/golang.org/x/crypto/openpgp/canonical_text.go
 create mode 100644 vendor/golang.org/x/crypto/openpgp/clearsign/clearsign.go
 create mode 100644 vendor/golang.org/x/crypto/openpgp/elgamal/elgamal.go
 create mode 100644 vendor/golang.org/x/crypto/openpgp/errors/errors.go
 create mode 100644 vendor/golang.org/x/crypto/openpgp/keys.go
 create mode 100644 vendor/golang.org/x/crypto/openpgp/packet/compressed.go
 create mode 100644 vendor/golang.org/x/crypto/openpgp/packet/config.go
 create mode 100644 vendor/golang.org/x/crypto/openpgp/packet/encrypted_key.go
 create mode 100644 vendor/golang.org/x/crypto/openpgp/packet/literal.go
 create mode 100644 vendor/golang.org/x/crypto/openpgp/packet/ocfb.go
 create mode 100644 vendor/golang.org/x/crypto/openpgp/packet/one_pass_signature.go
 create mode 100644 vendor/golang.org/x/crypto/openpgp/packet/opaque.go
 create mode 100644 vendor/golang.org/x/crypto/openpgp/packet/packet.go
 create mode 100644 vendor/golang.org/x/crypto/openpgp/packet/private_key.go
 create mode 100644 vendor/golang.org/x/crypto/openpgp/packet/public_key.go
 create mode 100644 vendor/golang.org/x/crypto/openpgp/packet/public_key_v3.go
 create mode 100644 vendor/golang.org/x/crypto/openpgp/packet/reader.go
 create mode 100644 vendor/golang.org/x/crypto/openpgp/packet/signature.go
 create mode 100644 vendor/golang.org/x/crypto/openpgp/packet/signature_v3.go
 create mode 100644 vendor/golang.org/x/crypto/openpgp/packet/symmetric_key_encrypted.go
 create mode 100644 vendor/golang.org/x/crypto/openpgp/packet/symmetrically_encrypted.go
 create mode 100644 vendor/golang.org/x/crypto/openpgp/packet/userattribute.go
 create mode 100644 vendor/golang.org/x/crypto/openpgp/packet/userid.go
 create mode 100644 vendor/golang.org/x/crypto/openpgp/read.go
 create mode 100644 vendor/golang.org/x/crypto/openpgp/s2k/s2k.go
 create mode 100644 vendor/golang.org/x/crypto/openpgp/write.go
 create mode 100644 vendor/golang.org/x/crypto/poly1305/poly1305_compat.go
 create mode 100644 vendor/golang.org/x/crypto/ripemd160/ripemd160.go
 create mode 100644 vendor/golang.org/x/crypto/ripemd160/ripemd160block.go
 create mode 100644 vendor/golang.org/x/crypto/salsa20/salsa20.go
 create mode 100644 vendor/golang.org/x/crypto/scrypt/scrypt.go
 create mode 100644 vendor/golang.org/x/crypto/sha3/doc.go
 create mode 100644 vendor/golang.org/x/crypto/sha3/hashes.go
 create mode 100644 vendor/golang.org/x/crypto/sha3/hashes_generic.go
 create mode 100644 vendor/golang.org/x/crypto/sha3/keccakf.go
 create mode 100644 vendor/golang.org/x/crypto/sha3/keccakf_amd64.go
 create mode 100644 vendor/golang.org/x/crypto/sha3/keccakf_amd64.s
 create mode 100644 vendor/golang.org/x/crypto/sha3/register.go
 create mode 100644 vendor/golang.org/x/crypto/sha3/sha3.go
 create mode 100644 vendor/golang.org/x/crypto/sha3/sha3_s390x.go
 create mode 100644 vendor/golang.org/x/crypto/sha3/sha3_s390x.s
 create mode 100644 vendor/golang.org/x/crypto/sha3/shake.go
 create mode 100644 vendor/golang.org/x/crypto/sha3/shake_generic.go
 create mode 100644 vendor/golang.org/x/crypto/sha3/xor.go
 create mode 100644 vendor/golang.org/x/crypto/sha3/xor_generic.go
 create mode 100644 vendor/golang.org/x/crypto/sha3/xor_unaligned.go
 create mode 100644 vendor/golang.org/x/crypto/ssh/agent/client.go
 create mode 100644 vendor/golang.org/x/crypto/ssh/agent/forward.go
 create mode 100644 vendor/golang.org/x/crypto/ssh/agent/keyring.go
 create mode 100644 vendor/golang.org/x/crypto/ssh/agent/server.go
 create mode 100644 vendor/golang.org/x/crypto/ssh/knownhosts/knownhosts.go
 create mode 100644 vendor/golang.org/x/crypto/ssh/terminal/terminal.go
 create mode 100644 vendor/golang.org/x/crypto/tea/cipher.go
 create mode 100644 vendor/golang.org/x/crypto/twofish/twofish.go
 create mode 100644 vendor/golang.org/x/crypto/xtea/block.go
 create mode 100644 vendor/golang.org/x/crypto/xtea/cipher.go
 create mode 100644 vendor/golang.org/x/crypto/xts/xts.go

diff --git a/vendor.conf b/vendor.conf
index 04ac7581af..efd71515bb 100644
--- a/vendor.conf
+++ b/vendor.conf
@@ -152,7 +152,7 @@ github.com/golang/protobuf                          84668698ea25b64748563aa20726
 github.com/cloudflare/cfssl                         5d63dbd981b5c408effbb58c442d54761ff94fbd # 1.3.2
 github.com/fernet/fernet-go                         9eac43b88a5efb8651d24de9b68e87567e029736
 github.com/google/certificate-transparency-go       37a384cd035e722ea46e55029093e26687138edf # v1.0.20
-golang.org/x/crypto                                 c1f2f97bffc9c53fc40a1a28a5b460094c0050d9
+golang.org/x/crypto                                 3147a52a75dda54ac3a611ef8978640d85188a2a
 golang.org/x/time                                   555d28b269f0569763d25dbe1a237ae74c6bcc82
 github.com/hashicorp/go-memdb                       cb9a474f84cc5e41b273b20c6927680b2a8776ad
 github.com/hashicorp/go-immutable-radix             826af9ccf0feeee615d546d69b11f8e98da8c8f1 https://github.com/tonistiigi/go-immutable-radix.git
diff --git a/vendor/golang.org/x/crypto/README.md b/vendor/golang.org/x/crypto/README.md
index c9d6fecd1e..92f73cdfbf 100644
--- a/vendor/golang.org/x/crypto/README.md
+++ b/vendor/golang.org/x/crypto/README.md
@@ -1,5 +1,7 @@
 # Go Cryptography
 
+[![Go Reference](https://pkg.go.dev/badge/golang.org/x/crypto.svg)](https://pkg.go.dev/golang.org/x/crypto)
+
 This repository holds supplementary Go cryptography libraries.
 
 ## Download/Install
diff --git a/vendor/golang.org/x/crypto/acme/acme.go b/vendor/golang.org/x/crypto/acme/acme.go
new file mode 100644
index 0000000000..f2d23f6976
--- /dev/null
+++ b/vendor/golang.org/x/crypto/acme/acme.go
@@ -0,0 +1,805 @@
+// Copyright 2015 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 acme provides an implementation of the
+// Automatic Certificate Management Environment (ACME) spec,
+// most famously used by Let's Encrypt.
+//
+// The initial implementation of this package was based on an early version
+// of the spec. The current implementation supports only the modern
+// RFC 8555 but some of the old API surface remains for compatibility.
+// While code using the old API will still compile, it will return an error.
+// Note the deprecation comments to update your code.
+//
+// See https://tools.ietf.org/html/rfc8555 for the spec.
+//
+// Most common scenarios will want to use autocert subdirectory instead,
+// which provides automatic access to certificates from Let's Encrypt
+// and any other ACME-based CA.
+package acme
+
+import (
+	"context"
+	"crypto"
+	"crypto/ecdsa"
+	"crypto/elliptic"
+	"crypto/rand"
+	"crypto/sha256"
+	"crypto/tls"
+	"crypto/x509"
+	"crypto/x509/pkix"
+	"encoding/asn1"
+	"encoding/base64"
+	"encoding/hex"
+	"encoding/json"
+	"encoding/pem"
+	"errors"
+	"fmt"
+	"math/big"
+	"net/http"
+	"strings"
+	"sync"
+	"time"
+)
+
+const (
+	// LetsEncryptURL is the Directory endpoint of Let's Encrypt CA.
+	LetsEncryptURL = "https://acme-v02.api.letsencrypt.org/directory"
+
+	// ALPNProto is the ALPN protocol name used by a CA server when validating
+	// tls-alpn-01 challenges.
+	//
+	// Package users must ensure their servers can negotiate the ACME ALPN in
+	// order for tls-alpn-01 challenge verifications to succeed.
+	// See the crypto/tls package's Config.NextProtos field.
+	ALPNProto = "acme-tls/1"
+)
+
+// idPeACMEIdentifier is the OID for the ACME extension for the TLS-ALPN challenge.
+// https://tools.ietf.org/html/draft-ietf-acme-tls-alpn-05#section-5.1
+var idPeACMEIdentifier = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 1, 31}
+
+const (
+	maxChainLen = 5       // max depth and breadth of a certificate chain
+	maxCertSize = 1 << 20 // max size of a certificate, in DER bytes
+	// Used for decoding certs from application/pem-certificate-chain response,
+	// the default when in RFC mode.
+	maxCertChainSize = maxCertSize * maxChainLen
+
+	// Max number of collected nonces kept in memory.
+	// Expect usual peak of 1 or 2.
+	maxNonces = 100
+)
+
+// Client is an ACME client.
+//
+// The only required field is Key. An example of creating a client with a new key
+// is as follows:
+//
+// 	key, err := rsa.GenerateKey(rand.Reader, 2048)
+// 	if err != nil {
+// 		log.Fatal(err)
+// 	}
+// 	client := &Client{Key: key}
+//
+type Client struct {
+	// Key is the account key used to register with a CA and sign requests.
+	// Key.Public() must return a *rsa.PublicKey or *ecdsa.PublicKey.
+	//
+	// The following algorithms are supported:
+	// RS256, ES256, ES384 and ES512.
+	// See RFC7518 for more details about the algorithms.
+	Key crypto.Signer
+
+	// HTTPClient optionally specifies an HTTP client to use
+	// instead of http.DefaultClient.
+	HTTPClient *http.Client
+
+	// DirectoryURL points to the CA directory endpoint.
+	// If empty, LetsEncryptURL is used.
+	// Mutating this value after a successful call of Client's Discover method
+	// will have no effect.
+	DirectoryURL string
+
+	// RetryBackoff computes the duration after which the nth retry of a failed request
+	// should occur. The value of n for the first call on failure is 1.
+	// The values of r and resp are the request and response of the last failed attempt.
+	// If the returned value is negative or zero, no more retries are done and an error
+	// is returned to the caller of the original method.
+	//
+	// Requests which result in a 4xx client error are not retried,
+	// except for 400 Bad Request due to "bad nonce" errors and 429 Too Many Requests.
+	//
+	// If RetryBackoff is nil, a truncated exponential backoff algorithm
+	// with the ceiling of 10 seconds is used, where each subsequent retry n
+	// is done after either ("Retry-After" + jitter) or (2^n seconds + jitter),
+	// preferring the former if "Retry-After" header is found in the resp.
+	// The jitter is a random value up to 1 second.
+	RetryBackoff func(n int, r *http.Request, resp *http.Response) time.Duration
+
+	// UserAgent is prepended to the User-Agent header sent to the ACME server,
+	// which by default is this package's name and version.
+	//
+	// Reusable libraries and tools in particular should set this value to be
+	// identifiable by the server, in case they are causing issues.
+	UserAgent string
+
+	cacheMu sync.Mutex
+	dir     *Directory // cached result of Client's Discover method
+	// KID is the key identifier provided by the CA. If not provided it will be
+	// retrieved from the CA by making a call to the registration endpoint.
+	KID KeyID
+
+	noncesMu sync.Mutex
+	nonces   map[string]struct{} // nonces collected from previous responses
+}
+
+// accountKID returns a key ID associated with c.Key, the account identity
+// provided by the CA during RFC based registration.
+// It assumes c.Discover has already been called.
+//
+// accountKID requires at most one network roundtrip.
+// It caches only successful result.
+//
+// When in pre-RFC mode or when c.getRegRFC responds with an error, accountKID
+// returns noKeyID.
+func (c *Client) accountKID(ctx context.Context) KeyID {
+	c.cacheMu.Lock()
+	defer c.cacheMu.Unlock()
+	if c.KID != noKeyID {
+		return c.KID
+	}
+	a, err := c.getRegRFC(ctx)
+	if err != nil {
+		return noKeyID
+	}
+	c.KID = KeyID(a.URI)
+	return c.KID
+}
+
+var errPreRFC = errors.New("acme: server does not support the RFC 8555 version of ACME")
+
+// Discover performs ACME server discovery using c.DirectoryURL.
+//
+// It caches successful result. So, subsequent calls will not result in
+// a network round-trip. This also means mutating c.DirectoryURL after successful call
+// of this method will have no effect.
+func (c *Client) Discover(ctx context.Context) (Directory, error) {
+	c.cacheMu.Lock()
+	defer c.cacheMu.Unlock()
+	if c.dir != nil {
+		return *c.dir, nil
+	}
+
+	res, err := c.get(ctx, c.directoryURL(), wantStatus(http.StatusOK))
+	if err != nil {
+		return Directory{}, err
+	}
+	defer res.Body.Close()
+	c.addNonce(res.Header)
+
+	var v struct {
+		Reg       string `json:"newAccount"`
+		Authz     string `json:"newAuthz"`
+		Order     string `json:"newOrder"`
+		Revoke    string `json:"revokeCert"`
+		Nonce     string `json:"newNonce"`
+		KeyChange string `json:"keyChange"`
+		Meta      struct {
+			Terms        string   `json:"termsOfService"`
+			Website      string   `json:"website"`
+			CAA          []string `json:"caaIdentities"`
+			ExternalAcct bool     `json:"externalAccountRequired"`
+		}
+	}
+	if err := json.NewDecoder(res.Body).Decode(&v); err != nil {
+		return Directory{}, err
+	}
+	if v.Order == "" {
+		return Directory{}, errPreRFC
+	}
+	c.dir = &Directory{
+		RegURL:                  v.Reg,
+		AuthzURL:                v.Authz,
+		OrderURL:                v.Order,
+		RevokeURL:               v.Revoke,
+		NonceURL:                v.Nonce,
+		KeyChangeURL:            v.KeyChange,
+		Terms:                   v.Meta.Terms,
+		Website:                 v.Meta.Website,
+		CAA:                     v.Meta.CAA,
+		ExternalAccountRequired: v.Meta.ExternalAcct,
+	}
+	return *c.dir, nil
+}
+
+func (c *Client) directoryURL() string {
+	if c.DirectoryURL != "" {
+		return c.DirectoryURL
+	}
+	return LetsEncryptURL
+}
+
+// CreateCert was part of the old version of ACME. It is incompatible with RFC 8555.
+//
+// Deprecated: this was for the pre-RFC 8555 version of ACME. Callers should use CreateOrderCert.
+func (c *Client) CreateCert(ctx context.Context, csr []byte, exp time.Duration, bundle bool) (der [][]byte, certURL string, err error) {
+	return nil, "", errPreRFC
+}
+
+// FetchCert retrieves already issued certificate from the given url, in DER format.
+// It retries the request until the certificate is successfully retrieved,
+// context is cancelled by the caller or an error response is received.
+//
+// If the bundle argument is true, the returned value also contains the CA (issuer)
+// certificate chain.
+//
+// FetchCert returns an error if the CA's response or chain was unreasonably large.
+// Callers are encouraged to parse the returned value to ensure the certificate is valid
+// and has expected features.
+func (c *Client) FetchCert(ctx context.Context, url string, bundle bool) ([][]byte, error) {
+	if _, err := c.Discover(ctx); err != nil {
+		return nil, err
+	}
+	return c.fetchCertRFC(ctx, url, bundle)
+}
+
+// RevokeCert revokes a previously issued certificate cert, provided in DER format.
+//
+// The key argument, used to sign the request, must be authorized
+// to revoke the certificate. It's up to the CA to decide which keys are authorized.
+// For instance, the key pair of the certificate may be authorized.
+// If the key is nil, c.Key is used instead.
+func (c *Client) RevokeCert(ctx context.Context, key crypto.Signer, cert []byte, reason CRLReasonCode) error {
+	if _, err := c.Discover(ctx); err != nil {
+		return err
+	}
+	return c.revokeCertRFC(ctx, key, cert, reason)
+}
+
+// AcceptTOS always returns true to indicate the acceptance of a CA's Terms of Service
+// during account registration. See Register method of Client for more details.
+func AcceptTOS(tosURL string) bool { return true }
+
+// Register creates a new account with the CA using c.Key.
+// It returns the registered account. The account acct is not modified.
+//
+// The registration may require the caller to agree to the CA's Terms of Service (TOS).
+// If so, and the account has not indicated the acceptance of the terms (see Account for details),
+// Register calls prompt with a TOS URL provided by the CA. Prompt should report
+// whether the caller agrees to the terms. To always accept the terms, the caller can use AcceptTOS.
+//
+// When interfacing with an RFC-compliant CA, non-RFC 8555 fields of acct are ignored
+// and prompt is called if Directory's Terms field is non-zero.
+// Also see Error's Instance field for when a CA requires already registered accounts to agree
+// to an updated Terms of Service.
+func (c *Client) Register(ctx context.Context, acct *Account, prompt func(tosURL string) bool) (*Account, error) {
+	if c.Key == nil {
+		return nil, errors.New("acme: client.Key must be set to Register")
+	}
+	if _, err := c.Discover(ctx); err != nil {
+		return nil, err
+	}
+	return c.registerRFC(ctx, acct, prompt)
+}
+
+// GetReg retrieves an existing account associated with c.Key.
+//
+// The url argument is a legacy artifact of the pre-RFC 8555 API
+// and is ignored.
+func (c *Client) GetReg(ctx context.Context, url string) (*Account, error) {
+	if _, err := c.Discover(ctx); err != nil {
+		return nil, err
+	}
+	return c.getRegRFC(ctx)
+}
+
+// UpdateReg updates an existing registration.
+// It returns an updated account copy. The provided account is not modified.
+//
+// The account's URI is ignored and the account URL associated with
+// c.Key is used instead.
+func (c *Client) UpdateReg(ctx context.Context, acct *Account) (*Account, error) {
+	if _, err := c.Discover(ctx); err != nil {
+		return nil, err
+	}
+	return c.updateRegRFC(ctx, acct)
+}
+
+// Authorize performs the initial step in the pre-authorization flow,
+// as opposed to order-based flow.
+// The caller will then need to choose from and perform a set of returned
+// challenges using c.Accept in order to successfully complete authorization.
+//
+// Once complete, the caller can use AuthorizeOrder which the CA
+// should provision with the already satisfied authorization.
+// For pre-RFC CAs, the caller can proceed directly to requesting a certificate
+// using CreateCert method.
+//
+// If an authorization has been previously granted, the CA may return
+// a valid authorization which has its Status field set to StatusValid.
+//
+// More about pre-authorization can be found at
+// https://tools.ietf.org/html/rfc8555#section-7.4.1.
+func (c *Client) Authorize(ctx context.Context, domain string) (*Authorization, error) {
+	return c.authorize(ctx, "dns", domain)
+}
+
+// AuthorizeIP is the same as Authorize but requests IP address authorization.
+// Clients which successfully obtain such authorization may request to issue
+// a certificate for IP addresses.
+//
+// See the ACME spec extension for more details about IP address identifiers:
+// https://tools.ietf.org/html/draft-ietf-acme-ip.
+func (c *Client) AuthorizeIP(ctx context.Context, ipaddr string) (*Authorization, error) {
+	return c.authorize(ctx, "ip", ipaddr)
+}
+
+func (c *Client) authorize(ctx context.Context, typ, val string) (*Authorization, error) {
+	if _, err := c.Discover(ctx); err != nil {
+		return nil, err
+	}
+
+	type authzID struct {
+		Type  string `json:"type"`
+		Value string `json:"value"`
+	}
+	req := struct {
+		Resource   string  `json:"resource"`
+		Identifier authzID `json:"identifier"`
+	}{
+		Resource:   "new-authz",
+		Identifier: authzID{Type: typ, Value: val},
+	}
+	res, err := c.post(ctx, nil, c.dir.AuthzURL, req, wantStatus(http.StatusCreated))
+	if err != nil {
+		return nil, err
+	}
+	defer res.Body.Close()
+
+	var v wireAuthz
+	if err := json.NewDecoder(res.Body).Decode(&v); err != nil {
+		return nil, fmt.Errorf("acme: invalid response: %v", err)
+	}
+	if v.Status != StatusPending && v.Status != StatusValid {
+		return nil, fmt.Errorf("acme: unexpected status: %s", v.Status)
+	}
+	return v.authorization(res.Header.Get("Location")), nil
+}
+
+// GetAuthorization retrieves an authorization identified by the given URL.
+//
+// If a caller needs to poll an authorization until its status is final,
+// see the WaitAuthorization method.
+func (c *Client) GetAuthorization(ctx context.Context, url string) (*Authorization, error) {
+	if _, err := c.Discover(ctx); err != nil {
+		return nil, err
+	}
+
+	res, err := c.postAsGet(ctx, url, wantStatus(http.StatusOK))
+	if err != nil {
+		return nil, err
+	}
+	defer res.Body.Close()
+	var v wireAuthz
+	if err := json.NewDecoder(res.Body).Decode(&v); err != nil {
+		return nil, fmt.Errorf("acme: invalid response: %v", err)
+	}
+	return v.authorization(url), nil
+}
+
+// RevokeAuthorization relinquishes an existing authorization identified
+// by the given URL.
+// The url argument is an Authorization.URI value.
+//
+// If successful, the caller will be required to obtain a new authorization
+// using the Authorize or AuthorizeOrder methods before being able to request
+// a new certificate for the domain associated with the authorization.
+//
+// It does not revoke existing certificates.
+func (c *Client) RevokeAuthorization(ctx context.Context, url string) error {
+	if _, err := c.Discover(ctx); err != nil {
+		return err
+	}
+
+	req := struct {
+		Resource string `json:"resource"`
+		Status   string `json:"status"`
+		Delete   bool   `json:"delete"`
+	}{
+		Resource: "authz",
+		Status:   "deactivated",
+		Delete:   true,
+	}
+	res, err := c.post(ctx, nil, url, req, wantStatus(http.StatusOK))
+	if err != nil {
+		return err
+	}
+	defer res.Body.Close()
+	return nil
+}
+
+// WaitAuthorization polls an authorization at the given URL
+// until it is in one of the final states, StatusValid or StatusInvalid,
+// the ACME CA responded with a 4xx error code, or the context is done.
+//
+// It returns a non-nil Authorization only if its Status is StatusValid.
+// In all other cases WaitAuthorization returns an error.
+// If the Status is StatusInvalid, the returned error is of type *AuthorizationError.
+func (c *Client) WaitAuthorization(ctx context.Context, url string) (*Authorization, error) {
+	if _, err := c.Discover(ctx); err != nil {
+		return nil, err
+	}
+	for {
+		res, err := c.postAsGet(ctx, url, wantStatus(http.StatusOK, http.StatusAccepted))
+		if err != nil {
+			return nil, err
+		}
+
+		var raw wireAuthz
+		err = json.NewDecoder(res.Body).Decode(&raw)
+		res.Body.Close()
+		switch {
+		case err != nil:
+			// Skip and retry.
+		case raw.Status == StatusValid:
+			return raw.authorization(url), nil
+		case raw.Status == StatusInvalid:
+			return nil, raw.error(url)
+		}
+
+		// Exponential backoff is implemented in c.get above.
+		// This is just to prevent continuously hitting the CA
+		// while waiting for a final authorization status.
+		d := retryAfter(res.Header.Get("Retry-After"))
+		if d == 0 {
+			// Given that the fastest challenges TLS-SNI and HTTP-01
+			// require a CA to make at least 1 network round trip
+			// and most likely persist a challenge state,
+			// this default delay seems reasonable.
+			d = time.Second
+		}
+		t := time.NewTimer(d)
+		select {
+		case <-ctx.Done():
+			t.Stop()
+			return nil, ctx.Err()
+		case <-t.C:
+			// Retry.
+		}
+	}
+}
+
+// GetChallenge retrieves the current status of an challenge.
+//
+// A client typically polls a challenge status using this method.
+func (c *Client) GetChallenge(ctx context.Context, url string) (*Challenge, error) {
+	if _, err := c.Discover(ctx); err != nil {
+		return nil, err
+	}
+
+	res, err := c.postAsGet(ctx, url, wantStatus(http.StatusOK, http.StatusAccepted))
+	if err != nil {
+		return nil, err
+	}
+
+	defer res.Body.Close()
+	v := wireChallenge{URI: url}
+	if err := json.NewDecoder(res.Body).Decode(&v); err != nil {
+		return nil, fmt.Errorf("acme: invalid response: %v", err)
+	}
+	return v.challenge(), nil
+}
+
+// Accept informs the server that the client accepts one of its challenges
+// previously obtained with c.Authorize.
+//
+// The server will then perform the validation asynchronously.
+func (c *Client) Accept(ctx context.Context, chal *Challenge) (*Challenge, error) {
+	if _, err := c.Discover(ctx); err != nil {
+		return nil, err
+	}
+
+	res, err := c.post(ctx, nil, chal.URI, json.RawMessage("{}"), wantStatus(
+		http.StatusOK,       // according to the spec
+		http.StatusAccepted, // Let's Encrypt: see https://goo.gl/WsJ7VT (acme-divergences.md)
+	))
+	if err != nil {
+		return nil, err
+	}
+	defer res.Body.Close()
+
+	var v wireChallenge
+	if err := json.NewDecoder(res.Body).Decode(&v); err != nil {
+		return nil, fmt.Errorf("acme: invalid response: %v", err)
+	}
+	return v.challenge(), nil
+}
+
+// DNS01ChallengeRecord returns a DNS record value for a dns-01 challenge response.
+// A TXT record containing the returned value must be provisioned under
+// "_acme-challenge" name of the domain being validated.
+//
+// The token argument is a Challenge.Token value.
+func (c *Client) DNS01ChallengeRecord(token string) (string, error) {
+	ka, err := keyAuth(c.Key.Public(), token)
+	if err != nil {
+		return "", err
+	}
+	b := sha256.Sum256([]byte(ka))
+	return base64.RawURLEncoding.EncodeToString(b[:]), nil
+}
+
+// HTTP01ChallengeResponse returns the response for an http-01 challenge.
+// Servers should respond with the value to HTTP requests at the URL path
+// provided by HTTP01ChallengePath to validate the challenge and prove control
+// over a domain name.
+//
+// The token argument is a Challenge.Token value.
+func (c *Client) HTTP01ChallengeResponse(token string) (string, error) {
+	return keyAuth(c.Key.Public(), token)
+}
+
+// HTTP01ChallengePath returns the URL path at which the response for an http-01 challenge
+// should be provided by the servers.
+// The response value can be obtained with HTTP01ChallengeResponse.
+//
+// The token argument is a Challenge.Token value.
+func (c *Client) HTTP01ChallengePath(token string) string {
+	return "/.well-known/acme-challenge/" + token
+}
+
+// TLSSNI01ChallengeCert creates a certificate for TLS-SNI-01 challenge response.
+//
+// Deprecated: This challenge type is unused in both draft-02 and RFC versions of the ACME spec.
+func (c *Client) TLSSNI01ChallengeCert(token string, opt ...CertOption) (cert tls.Certificate, name string, err error) {
+	ka, err := keyAuth(c.Key.Public(), token)
+	if err != nil {
+		return tls.Certificate{}, "", err
+	}
+	b := sha256.Sum256([]byte(ka))
+	h := hex.EncodeToString(b[:])
+	name = fmt.Sprintf("%s.%s.acme.invalid", h[:32], h[32:])
+	cert, err = tlsChallengeCert([]string{name}, opt)
+	if err != nil {
+		return tls.Certificate{}, "", err
+	}
+	return cert, name, nil
+}
+
+// TLSSNI02ChallengeCert creates a certificate for TLS-SNI-02 challenge response.
+//
+// Deprecated: This challenge type is unused in both draft-02 and RFC versions of the ACME spec.
+func (c *Client) TLSSNI02ChallengeCert(token string, opt ...CertOption) (cert tls.Certificate, name string, err error) {
+	b := sha256.Sum256([]byte(token))
+	h := hex.EncodeToString(b[:])
+	sanA := fmt.Sprintf("%s.%s.token.acme.invalid", h[:32], h[32:])
+
+	ka, err := keyAuth(c.Key.Public(), token)
+	if err != nil {
+		return tls.Certificate{}, "", err
+	}
+	b = sha256.Sum256([]byte(ka))
+	h = hex.EncodeToString(b[:])
+	sanB := fmt.Sprintf("%s.%s.ka.acme.invalid", h[:32], h[32:])
+
+	cert, err = tlsChallengeCert([]string{sanA, sanB}, opt)
+	if err != nil {
+		return tls.Certificate{}, "", err
+	}
+	return cert, sanA, nil
+}
+
+// TLSALPN01ChallengeCert creates a certificate for TLS-ALPN-01 challenge response.
+// Servers can present the certificate to validate the challenge and prove control
+// over a domain name. For more details on TLS-ALPN-01 see
+// https://tools.ietf.org/html/draft-shoemaker-acme-tls-alpn-00#section-3
+//
+// The token argument is a Challenge.Token value.
+// If a WithKey option is provided, its private part signs the returned cert,
+// and the public part is used to specify the signee.
+// If no WithKey option is provided, a new ECDSA key is generated using P-256 curve.
+//
+// The returned certificate is valid for the next 24 hours and must be presented only when
+// the server name in the TLS ClientHello matches the domain, and the special acme-tls/1 ALPN protocol
+// has been specified.
+func (c *Client) TLSALPN01ChallengeCert(token, domain string, opt ...CertOption) (cert tls.Certificate, err error) {
+	ka, err := keyAuth(c.Key.Public(), token)
+	if err != nil {
+		return tls.Certificate{}, err
+	}
+	shasum := sha256.Sum256([]byte(ka))
+	extValue, err := asn1.Marshal(shasum[:])
+	if err != nil {
+		return tls.Certificate{}, err
+	}
+	acmeExtension := pkix.Extension{
+		Id:       idPeACMEIdentifier,
+		Critical: true,
+		Value:    extValue,
+	}
+
+	tmpl := defaultTLSChallengeCertTemplate()
+
+	var newOpt []CertOption
+	for _, o := range opt {
+		switch o := o.(type) {
+		case *certOptTemplate:
+			t := *(*x509.Certificate)(o) // shallow copy is ok
+			tmpl = &t
+		default:
+			newOpt = append(newOpt, o)
+		}
+	}
+	tmpl.ExtraExtensions = append(tmpl.ExtraExtensions, acmeExtension)
+	newOpt = append(newOpt, WithTemplate(tmpl))
+	return tlsChallengeCert([]string{domain}, newOpt)
+}
+
+// popNonce returns a nonce value previously stored with c.addNonce
+// or fetches a fresh one from c.dir.NonceURL.
+// If NonceURL is empty, it first tries c.directoryURL() and, failing that,
+// the provided url.
+func (c *Client) popNonce(ctx context.Context, url string) (string, error) {
+	c.noncesMu.Lock()
+	defer c.noncesMu.Unlock()
+	if len(c.nonces) == 0 {
+		if c.dir != nil && c.dir.NonceURL != "" {
+			return c.fetchNonce(ctx, c.dir.NonceURL)
+		}
+		dirURL := c.directoryURL()
+		v, err := c.fetchNonce(ctx, dirURL)
+		if err != nil && url != dirURL {
+			v, err = c.fetchNonce(ctx, url)
+		}
+		return v, err
+	}
+	var nonce string
+	for nonce = range c.nonces {
+		delete(c.nonces, nonce)
+		break
+	}
+	return nonce, nil
+}
+
+// clearNonces clears any stored nonces
+func (c *Client) clearNonces() {
+	c.noncesMu.Lock()
+	defer c.noncesMu.Unlock()
+	c.nonces = make(map[string]struct{})
+}
+
+// addNonce stores a nonce value found in h (if any) for future use.
+func (c *Client) addNonce(h http.Header) {
+	v := nonceFromHeader(h)
+	if v == "" {
+		return
+	}
+	c.noncesMu.Lock()
+	defer c.noncesMu.Unlock()
+	if len(c.nonces) >= maxNonces {
+		return
+	}
+	if c.nonces == nil {
+		c.nonces = make(map[string]struct{})
+	}
+	c.nonces[v] = struct{}{}
+}
+
+func (c *Client) fetchNonce(ctx context.Context, url string) (string, error) {
+	r, err := http.NewRequest("HEAD", url, nil)
+	if err != nil {
+		return "", err
+	}
+	resp, err := c.doNoRetry(ctx, r)
+	if err != nil {
+		return "", err
+	}
+	defer resp.Body.Close()
+	nonce := nonceFromHeader(resp.Header)
+	if nonce == "" {
+		if resp.StatusCode > 299 {
+			return "", responseError(resp)
+		}
+		return "", errors.New("acme: nonce not found")
+	}
+	return nonce, nil
+}
+
+func nonceFromHeader(h http.Header) string {
+	return h.Get("Replay-Nonce")
+}
+
+// linkHeader returns URI-Reference values of all Link headers
+// with relation-type rel.
+// See https://tools.ietf.org/html/rfc5988#section-5 for details.
+func linkHeader(h http.Header, rel string) []string {
+	var links []string
+	for _, v := range h["Link"] {
+		parts := strings.Split(v, ";")
+		for _, p := range parts {
+			p = strings.TrimSpace(p)
+			if !strings.HasPrefix(p, "rel=") {
+				continue
+			}
+			if v := strings.Trim(p[4:], `"`); v == rel {
+				links = append(links, strings.Trim(parts[0], "<>"))
+			}
+		}
+	}
+	return links
+}
+
+// keyAuth generates a key authorization string for a given token.
+func keyAuth(pub crypto.PublicKey, token string) (string, error) {
+	th, err := JWKThumbprint(pub)
+	if err != nil {
+		return "", err
+	}
+	return fmt.Sprintf("%s.%s", token, th), nil
+}
+
+// defaultTLSChallengeCertTemplate is a template used to create challenge certs for TLS challenges.
+func defaultTLSChallengeCertTemplate() *x509.Certificate {
+	return &x509.Certificate{
+		SerialNumber:          big.NewInt(1),
+		NotBefore:             time.Now(),
+		NotAfter:              time.Now().Add(24 * time.Hour),
+		BasicConstraintsValid: true,
+		KeyUsage:              x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
+		ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
+	}
+}
+
+// tlsChallengeCert creates a temporary certificate for TLS-SNI challenges
+// with the given SANs and auto-generated public/private key pair.
+// The Subject Common Name is set to the first SAN to aid debugging.
+// To create a cert with a custom key pair, specify WithKey option.
+func tlsChallengeCert(san []string, opt []CertOption) (tls.Certificate, error) {
+	var key crypto.Signer
+	tmpl := defaultTLSChallengeCertTemplate()
+	for _, o := range opt {
+		switch o := o.(type) {
+		case *certOptKey:
+			if key != nil {
+				return tls.Certificate{}, errors.New("acme: duplicate key option")
+			}
+			key = o.key
+		case *certOptTemplate:
+			t := *(*x509.Certificate)(o) // shallow copy is ok
+			tmpl = &t
+		default:
+			// package's fault, if we let this happen:
+			panic(fmt.Sprintf("unsupported option type %T", o))
+		}
+	}
+	if key == nil {
+		var err error
+		if key, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader); err != nil {
+			return tls.Certificate{}, err
+		}
+	}
+	tmpl.DNSNames = san
+	if len(san) > 0 {
+		tmpl.Subject.CommonName = san[0]
+	}
+
+	der, err := x509.CreateCertificate(rand.Reader, tmpl, tmpl, key.Public(), key)
+	if err != nil {
+		return tls.Certificate{}, err
+	}
+	return tls.Certificate{
+		Certificate: [][]byte{der},
+		PrivateKey:  key,
+	}, nil
+}
+
+// encodePEM returns b encoded as PEM with block of type typ.
+func encodePEM(typ string, b []byte) []byte {
+	pb := &pem.Block{Type: typ, Bytes: b}
+	return pem.EncodeToMemory(pb)
+}
+
+// timeNow is time.Now, except in tests which can mess with it.
+var timeNow = time.Now
diff --git a/vendor/golang.org/x/crypto/acme/autocert/autocert.go b/vendor/golang.org/x/crypto/acme/autocert/autocert.go
new file mode 100644
index 0000000000..1858184e81
--- /dev/null
+++ b/vendor/golang.org/x/crypto/acme/autocert/autocert.go
@@ -0,0 +1,1193 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package autocert provides automatic access to certificates from Let's Encrypt
+// and any other ACME-based CA.
+//
+// This package is a work in progress and makes no API stability promises.
+package autocert
+
+import (
+	"bytes"
+	"context"
+	"crypto"
+	"crypto/ecdsa"
+	"crypto/elliptic"
+	"crypto/rand"
+	"crypto/rsa"
+	"crypto/tls"
+	"crypto/x509"
+	"crypto/x509/pkix"
+	"encoding/pem"
+	"errors"
+	"fmt"
+	"io"
+	mathrand "math/rand"
+	"net"
+	"net/http"
+	"path"
+	"strings"
+	"sync"
+	"time"
+
+	"golang.org/x/crypto/acme"
+	"golang.org/x/net/idna"
+)
+
+// DefaultACMEDirectory is the default ACME Directory URL used when the Manager's Client is nil.
+const DefaultACMEDirectory = "https://acme-v02.api.letsencrypt.org/directory"
+
+// createCertRetryAfter is how much time to wait before removing a failed state
+// entry due to an unsuccessful createCert call.
+// This is a variable instead of a const for testing.
+// TODO: Consider making it configurable or an exp backoff?
+var createCertRetryAfter = time.Minute
+
+// pseudoRand is safe for concurrent use.
+var pseudoRand *lockedMathRand
+
+var errPreRFC = errors.New("autocert: ACME server doesn't support RFC 8555")
+
+func init() {
+	src := mathrand.NewSource(time.Now().UnixNano())
+	pseudoRand = &lockedMathRand{rnd: mathrand.New(src)}
+}
+
+// AcceptTOS is a Manager.Prompt function that always returns true to
+// indicate acceptance of the CA's Terms of Service during account
+// registration.
+func AcceptTOS(tosURL string) bool { return true }
+
+// HostPolicy specifies which host names the Manager is allowed to respond to.
+// It returns a non-nil error if the host should be rejected.
+// The returned error is accessible via tls.Conn.Handshake and its callers.
+// See Manager's HostPolicy field and GetCertificate method docs for more details.
+type HostPolicy func(ctx context.Context, host string) error
+
+// HostWhitelist returns a policy where only the specified host names are allowed.
+// Only exact matches are currently supported. Subdomains, regexp or wildcard
+// will not match.
+//
+// Note that all hosts will be converted to Punycode via idna.Lookup.ToASCII so that
+// Manager.GetCertificate can handle the Unicode IDN and mixedcase hosts correctly.
+// Invalid hosts will be silently ignored.
+func HostWhitelist(hosts ...string) HostPolicy {
+	whitelist := make(map[string]bool, len(hosts))
+	for _, h := range hosts {
+		if h, err := idna.Lookup.ToASCII(h); err == nil {
+			whitelist[h] = true
+		}
+	}
+	return func(_ context.Context, host string) error {
+		if !whitelist[host] {
+			return fmt.Errorf("acme/autocert: host %q not configured in HostWhitelist", host)
+		}
+		return nil
+	}
+}
+
+// defaultHostPolicy is used when Manager.HostPolicy is not set.
+func defaultHostPolicy(context.Context, string) error {
+	return nil
+}
+
+// Manager is a stateful certificate manager built on top of acme.Client.
+// It obtains and refreshes certificates automatically using "tls-alpn-01"
+// or "http-01" challenge types, as well as providing them to a TLS server
+// via tls.Config.
+//
+// You must specify a cache implementation, such as DirCache,
+// to reuse obtained certificates across program restarts.
+// Otherwise your server is very likely to exceed the certificate
+// issuer's request rate limits.
+type Manager struct {
+	// Prompt specifies a callback function to conditionally accept a CA's Terms of Service (TOS).
+	// The registration may require the caller to agree to the CA's TOS.
+	// If so, Manager calls Prompt with a TOS URL provided by the CA. Prompt should report
+	// whether the caller agrees to the terms.
+	//
+	// To always accept the terms, the callers can use AcceptTOS.
+	Prompt func(tosURL string) bool
+
+	// Cache optionally stores and retrieves previously-obtained certificates
+	// and other state. If nil, certs will only be cached for the lifetime of
+	// the Manager. Multiple Managers can share the same Cache.
+	//
+	// Using a persistent Cache, such as DirCache, is strongly recommended.
+	Cache Cache
+
+	// HostPolicy controls which domains the Manager will attempt
+	// to retrieve new certificates for. It does not affect cached certs.
+	//
+	// If non-nil, HostPolicy is called before requesting a new cert.
+	// If nil, all hosts are currently allowed. This is not recommended,
+	// as it opens a potential attack where clients connect to a server
+	// by IP address and pretend to be asking for an incorrect host name.
+	// Manager will attempt to obtain a certificate for that host, incorrectly,
+	// eventually reaching the CA's rate limit for certificate requests
+	// and making it impossible to obtain actual certificates.
+	//
+	// See GetCertificate for more details.
+	HostPolicy HostPolicy
+
+	// RenewBefore optionally specifies how early certificates should
+	// be renewed before they expire.
+	//
+	// If zero, they're renewed 30 days before expiration.
+	RenewBefore time.Duration
+
+	// Client is used to perform low-level operations, such as account registration
+	// and requesting new certificates.
+	//
+	// If Client is nil, a zero-value acme.Client is used with DefaultACMEDirectory
+	// as the directory endpoint.
+	// If the Client.Key is nil, a new ECDSA P-256 key is generated and,
+	// if Cache is not nil, stored in cache.
+	//
+	// Mutating the field after the first call of GetCertificate method will have no effect.
+	Client *acme.Client
+
+	// Email optionally specifies a contact email address.
+	// This is used by CAs, such as Let's Encrypt, to notify about problems
+	// with issued certificates.
+	//
+	// If the Client's account key is already registered, Email is not used.
+	Email string
+
+	// ForceRSA used to make the Manager generate RSA certificates. It is now ignored.
+	//
+	// Deprecated: the Manager will request the correct type of certificate based
+	// on what each client supports.
+	ForceRSA bool
+
+	// ExtraExtensions are used when generating a new CSR (Certificate Request),
+	// thus allowing customization of the resulting certificate.
+	// For instance, TLS Feature Extension (RFC 7633) can be used
+	// to prevent an OCSP downgrade attack.
+	//
+	// The field value is passed to crypto/x509.CreateCertificateRequest
+	// in the template's ExtraExtensions field as is.
+	ExtraExtensions []pkix.Extension
+
+	clientMu sync.Mutex
+	client   *acme.Client // initialized by acmeClient method
+
+	stateMu sync.Mutex
+	state   map[certKey]*certState
+
+	// renewal tracks the set of domains currently running renewal timers.
+	renewalMu sync.Mutex
+	renewal   map[certKey]*domainRenewal
+
+	// challengeMu guards tryHTTP01, certTokens and httpTokens.
+	challengeMu sync.RWMutex
+	// tryHTTP01 indicates whether the Manager should try "http-01" challenge type
+	// during the authorization flow.
+	tryHTTP01 bool
+	// httpTokens contains response body values for http-01 challenges
+	// and is keyed by the URL path at which a challenge response is expected
+	// to be provisioned.
+	// The entries are stored for the duration of the authorization flow.
+	httpTokens map[string][]byte
+	// certTokens contains temporary certificates for tls-alpn-01 challenges
+	// and is keyed by the domain name which matches the ClientHello server name.
+	// The entries are stored for the duration of the authorization flow.
+	certTokens map[string]*tls.Certificate
+
+	// nowFunc, if not nil, returns the current time. This may be set for
+	// testing purposes.
+	nowFunc func() time.Time
+}
+
+// certKey is the key by which certificates are tracked in state, renewal and cache.
+type certKey struct {
+	domain  string // without trailing dot
+	isRSA   bool   // RSA cert for legacy clients (as opposed to default ECDSA)
+	isToken bool   // tls-based challenge token cert; key type is undefined regardless of isRSA
+}
+
+func (c certKey) String() string {
+	if c.isToken {
+		return c.domain + "+token"
+	}
+	if c.isRSA {
+		return c.domain + "+rsa"
+	}
+	return c.domain
+}
+
+// TLSConfig creates a new TLS config suitable for net/http.Server servers,
+// supporting HTTP/2 and the tls-alpn-01 ACME challenge type.
+func (m *Manager) TLSConfig() *tls.Config {
+	return &tls.Config{
+		GetCertificate: m.GetCertificate,
+		NextProtos: []string{
+			"h2", "http/1.1", // enable HTTP/2
+			acme.ALPNProto, // enable tls-alpn ACME challenges
+		},
+	}
+}
+
+// GetCertificate implements the tls.Config.GetCertificate hook.
+// It provides a TLS certificate for hello.ServerName host, including answering
+// tls-alpn-01 challenges.
+// All other fields of hello are ignored.
+//
+// If m.HostPolicy is non-nil, GetCertificate calls the policy before requesting
+// a new cert. A non-nil error returned from m.HostPolicy halts TLS negotiation.
+// The error is propagated back to the caller of GetCertificate and is user-visible.
+// This does not affect cached certs. See HostPolicy field description for more details.
+//
+// If GetCertificate is used directly, instead of via Manager.TLSConfig, package users will
+// also have to add acme.ALPNProto to NextProtos for tls-alpn-01, or use HTTPHandler for http-01.
+func (m *Manager) GetCertificate(hello *tls.ClientHelloInfo) (*tls.Certificate, error) {
+	if m.Prompt == nil {
+		return nil, errors.New("acme/autocert: Manager.Prompt not set")
+	}
+
+	name := hello.ServerName
+	if name == "" {
+		return nil, errors.New("acme/autocert: missing server name")
+	}
+	if !strings.Contains(strings.Trim(name, "."), ".") {
+		return nil, errors.New("acme/autocert: server name component count invalid")
+	}
+
+	// Note that this conversion is necessary because some server names in the handshakes
+	// started by some clients (such as cURL) are not converted to Punycode, which will
+	// prevent us from obtaining certificates for them. In addition, we should also treat
+	// example.com and EXAMPLE.COM as equivalent and return the same certificate for them.
+	// Fortunately, this conversion also helped us deal with this kind of mixedcase problems.
+	//
+	// Due to the "σςΣ" problem (see https://unicode.org/faq/idn.html#22), we can't use
+	// idna.Punycode.ToASCII (or just idna.ToASCII) here.
+	name, err := idna.Lookup.ToASCII(name)
+	if err != nil {
+		return nil, errors.New("acme/autocert: server name contains invalid character")
+	}
+
+	// In the worst-case scenario, the timeout needs to account for caching, host policy,
+	// domain ownership verification and certificate issuance.
+	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
+	defer cancel()
+
+	// Check whether this is a token cert requested for TLS-ALPN challenge.
+	if wantsTokenCert(hello) {
+		m.challengeMu.RLock()
+		defer m.challengeMu.RUnlock()
+		if cert := m.certTokens[name]; cert != nil {
+			return cert, nil
+		}
+		if cert, err := m.cacheGet(ctx, certKey{domain: name, isToken: true}); err == nil {
+			return cert, nil
+		}
+		// TODO: cache error results?
+		return nil, fmt.Errorf("acme/autocert: no token cert for %q", name)
+	}
+
+	// regular domain
+	ck := certKey{
+		domain: strings.TrimSuffix(name, "."), // golang.org/issue/18114
+		isRSA:  !supportsECDSA(hello),
+	}
+	cert, err := m.cert(ctx, ck)
+	if err == nil {
+		return cert, nil
+	}
+	if err != ErrCacheMiss {
+		return nil, err
+	}
+
+	// first-time
+	if err := m.hostPolicy()(ctx, name); err != nil {
+		return nil, err
+	}
+	cert, err = m.createCert(ctx, ck)
+	if err != nil {
+		return nil, err
+	}
+	m.cachePut(ctx, ck, cert)
+	return cert, nil
+}
+
+// wantsTokenCert reports whether a TLS request with SNI is made by a CA server
+// for a challenge verification.
+func wantsTokenCert(hello *tls.ClientHelloInfo) bool {
+	// tls-alpn-01
+	if len(hello.SupportedProtos) == 1 && hello.SupportedProtos[0] == acme.ALPNProto {
+		return true
+	}
+	return false
+}
+
+func supportsECDSA(hello *tls.ClientHelloInfo) bool {
+	// The "signature_algorithms" extension, if present, limits the key exchange
+	// algorithms allowed by the cipher suites. See RFC 5246, section 7.4.1.4.1.
+	if hello.SignatureSchemes != nil {
+		ecdsaOK := false
+	schemeLoop:
+		for _, scheme := range hello.SignatureSchemes {
+			const tlsECDSAWithSHA1 tls.SignatureScheme = 0x0203 // constant added in Go 1.10
+			switch scheme {
+			case tlsECDSAWithSHA1, tls.ECDSAWithP256AndSHA256,
+				tls.ECDSAWithP384AndSHA384, tls.ECDSAWithP521AndSHA512:
+				ecdsaOK = true
+				break schemeLoop
+			}
+		}
+		if !ecdsaOK {
+			return false
+		}
+	}
+	if hello.SupportedCurves != nil {
+		ecdsaOK := false
+		for _, curve := range hello.SupportedCurves {
+			if curve == tls.CurveP256 {
+				ecdsaOK = true
+				break
+			}
+		}
+		if !ecdsaOK {
+			return false
+		}
+	}
+	for _, suite := range hello.CipherSuites {
+		switch suite {
+		case tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
+			tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
+			tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
+			tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
+			tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
+			tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
+			tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305:
+			return true
+		}
+	}
+	return false
+}
+
+// HTTPHandler configures the Manager to provision ACME "http-01" challenge responses.
+// It returns an http.Handler that responds to the challenges and must be
+// running on port 80. If it receives a request that is not an ACME challenge,
+// it delegates the request to the optional fallback handler.
+//
+// If fallback is nil, the returned handler redirects all GET and HEAD requests
+// to the default TLS port 443 with 302 Found status code, preserving the original
+// request path and query. It responds with 400 Bad Request to all other HTTP methods.
+// The fallback is not protected by the optional HostPolicy.
+//
+// Because the fallback handler is run with unencrypted port 80 requests,
+// the fallback should not serve TLS-only requests.
+//
+// If HTTPHandler is never called, the Manager will only use the "tls-alpn-01"
+// challenge for domain verification.
+func (m *Manager) HTTPHandler(fallback http.Handler) http.Handler {
+	m.challengeMu.Lock()
+	defer m.challengeMu.Unlock()
+	m.tryHTTP01 = true
+
+	if fallback == nil {
+		fallback = http.HandlerFunc(handleHTTPRedirect)
+	}
+	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+		if !strings.HasPrefix(r.URL.Path, "/.well-known/acme-challenge/") {
+			fallback.ServeHTTP(w, r)
+			return
+		}
+		// A reasonable context timeout for cache and host policy only,
+		// because we don't wait for a new certificate issuance here.
+		ctx, cancel := context.WithTimeout(r.Context(), time.Minute)
+		defer cancel()
+		if err := m.hostPolicy()(ctx, r.Host); err != nil {
+			http.Error(w, err.Error(), http.StatusForbidden)
+			return
+		}
+		data, err := m.httpToken(ctx, r.URL.Path)
+		if err != nil {
+			http.Error(w, err.Error(), http.StatusNotFound)
+			return
+		}
+		w.Write(data)
+	})
+}
+
+func handleHTTPRedirect(w http.ResponseWriter, r *http.Request) {
+	if r.Method != "GET" && r.Method != "HEAD" {
+		http.Error(w, "Use HTTPS", http.StatusBadRequest)
+		return
+	}
+	target := "https://" + stripPort(r.Host) + r.URL.RequestURI()
+	http.Redirect(w, r, target, http.StatusFound)
+}
+
+func stripPort(hostport string) string {
+	host, _, err := net.SplitHostPort(hostport)
+	if err != nil {
+		return hostport
+	}
+	return net.JoinHostPort(host, "443")
+}
+
+// cert returns an existing certificate either from m.state or cache.
+// If a certificate is found in cache but not in m.state, the latter will be filled
+// with the cached value.
+func (m *Manager) cert(ctx context.Context, ck certKey) (*tls.Certificate, error) {
+	m.stateMu.Lock()
+	if s, ok := m.state[ck]; ok {
+		m.stateMu.Unlock()
+		s.RLock()
+		defer s.RUnlock()
+		return s.tlscert()
+	}
+	defer m.stateMu.Unlock()
+	cert, err := m.cacheGet(ctx, ck)
+	if err != nil {
+		return nil, err
+	}
+	signer, ok := cert.PrivateKey.(crypto.Signer)
+	if !ok {
+		return nil, errors.New("acme/autocert: private key cannot sign")
+	}
+	if m.state == nil {
+		m.state = make(map[certKey]*certState)
+	}
+	s := &certState{
+		key:  signer,
+		cert: cert.Certificate,
+		leaf: cert.Leaf,
+	}
+	m.state[ck] = s
+	go m.startRenew(ck, s.key, s.leaf.NotAfter)
+	return cert, nil
+}
+
+// cacheGet always returns a valid certificate, or an error otherwise.
+// If a cached certificate exists but is not valid, ErrCacheMiss is returned.
+func (m *Manager) cacheGet(ctx context.Context, ck certKey) (*tls.Certificate, error) {
+	if m.Cache == nil {
+		return nil, ErrCacheMiss
+	}
+	data, err := m.Cache.Get(ctx, ck.String())
+	if err != nil {
+		return nil, err
+	}
+
+	// private
+	priv, pub := pem.Decode(data)
+	if priv == nil || !strings.Contains(priv.Type, "PRIVATE") {
+		return nil, ErrCacheMiss
+	}
+	privKey, err := parsePrivateKey(priv.Bytes)
+	if err != nil {
+		return nil, err
+	}
+
+	// public
+	var pubDER [][]byte
+	for len(pub) > 0 {
+		var b *pem.Block
+		b, pub = pem.Decode(pub)
+		if b == nil {
+			break
+		}
+		pubDER = append(pubDER, b.Bytes)
+	}
+	if len(pub) > 0 {
+		// Leftover content not consumed by pem.Decode. Corrupt. Ignore.
+		return nil, ErrCacheMiss
+	}
+
+	// verify and create TLS cert
+	leaf, err := validCert(ck, pubDER, privKey, m.now())
+	if err != nil {
+		return nil, ErrCacheMiss
+	}
+	tlscert := &tls.Certificate{
+		Certificate: pubDER,
+		PrivateKey:  privKey,
+		Leaf:        leaf,
+	}
+	return tlscert, nil
+}
+
+func (m *Manager) cachePut(ctx context.Context, ck certKey, tlscert *tls.Certificate) error {
+	if m.Cache == nil {
+		return nil
+	}
+
+	// contains PEM-encoded data
+	var buf bytes.Buffer
+
+	// private
+	switch key := tlscert.PrivateKey.(type) {
+	case *ecdsa.PrivateKey:
+		if err := encodeECDSAKey(&buf, key); err != nil {
+			return err
+		}
+	case *rsa.PrivateKey:
+		b := x509.MarshalPKCS1PrivateKey(key)
+		pb := &pem.Block{Type: "RSA PRIVATE KEY", Bytes: b}
+		if err := pem.Encode(&buf, pb); err != nil {
+			return err
+		}
+	default:
+		return errors.New("acme/autocert: unknown private key type")
+	}
+
+	// public
+	for _, b := range tlscert.Certificate {
+		pb := &pem.Block{Type: "CERTIFICATE", Bytes: b}
+		if err := pem.Encode(&buf, pb); err != nil {
+			return err
+		}
+	}
+
+	return m.Cache.Put(ctx, ck.String(), buf.Bytes())
+}
+
+func encodeECDSAKey(w io.Writer, key *ecdsa.PrivateKey) error {
+	b, err := x509.MarshalECPrivateKey(key)
+	if err != nil {
+		return err
+	}
+	pb := &pem.Block{Type: "EC PRIVATE KEY", Bytes: b}
+	return pem.Encode(w, pb)
+}
+
+// createCert starts the domain ownership verification and returns a certificate
+// for that domain upon success.
+//
+// If the domain is already being verified, it waits for the existing verification to complete.
+// Either way, createCert blocks for the duration of the whole process.
+func (m *Manager) createCert(ctx context.Context, ck certKey) (*tls.Certificate, error) {
+	// TODO: maybe rewrite this whole piece using sync.Once
+	state, err := m.certState(ck)
+	if err != nil {
+		return nil, err
+	}
+	// state may exist if another goroutine is already working on it
+	// in which case just wait for it to finish
+	if !state.locked {
+		state.RLock()
+		defer state.RUnlock()
+		return state.tlscert()
+	}
+
+	// We are the first; state is locked.
+	// Unblock the readers when domain ownership is verified
+	// and we got the cert or the process failed.
+	defer state.Unlock()
+	state.locked = false
+
+	der, leaf, err := m.authorizedCert(ctx, state.key, ck)
+	if err != nil {
+		// Remove the failed state after some time,
+		// making the manager call createCert again on the following TLS hello.
+		didRemove := testDidRemoveState // The lifetime of this timer is untracked, so copy mutable local state to avoid races.
+		time.AfterFunc(createCertRetryAfter, func() {
+			defer didRemove(ck)
+			m.stateMu.Lock()
+			defer m.stateMu.Unlock()
+			// Verify the state hasn't changed and it's still invalid
+			// before deleting.
+			s, ok := m.state[ck]
+			if !ok {
+				return
+			}
+			if _, err := validCert(ck, s.cert, s.key, m.now()); err == nil {
+				return
+			}
+			delete(m.state, ck)
+		})
+		return nil, err
+	}
+	state.cert = der
+	state.leaf = leaf
+	go m.startRenew(ck, state.key, state.leaf.NotAfter)
+	return state.tlscert()
+}
+
+// certState returns a new or existing certState.
+// If a new certState is returned, state.exist is false and the state is locked.
+// The returned error is non-nil only in the case where a new state could not be created.
+func (m *Manager) certState(ck certKey) (*certState, error) {
+	m.stateMu.Lock()
+	defer m.stateMu.Unlock()
+	if m.state == nil {
+		m.state = make(map[certKey]*certState)
+	}
+	// existing state
+	if state, ok := m.state[ck]; ok {
+		return state, nil
+	}
+
+	// new locked state
+	var (
+		err error
+		key crypto.Signer
+	)
+	if ck.isRSA {
+		key, err = rsa.GenerateKey(rand.Reader, 2048)
+	} else {
+		key, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
+	}
+	if err != nil {
+		return nil, err
+	}
+
+	state := &certState{
+		key:    key,
+		locked: true,
+	}
+	state.Lock() // will be unlocked by m.certState caller
+	m.state[ck] = state
+	return state, nil
+}
+
+// authorizedCert starts the domain ownership verification process and requests a new cert upon success.
+// The key argument is the certificate private key.
+func (m *Manager) authorizedCert(ctx context.Context, key crypto.Signer, ck certKey) (der [][]byte, leaf *x509.Certificate, err error) {
+	csr, err := certRequest(key, ck.domain, m.ExtraExtensions)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	client, err := m.acmeClient(ctx)
+	if err != nil {
+		return nil, nil, err
+	}
+	dir, err := client.Discover(ctx)
+	if err != nil {
+		return nil, nil, err
+	}
+	if dir.OrderURL == "" {
+		return nil, nil, errPreRFC
+	}
+
+	o, err := m.verifyRFC(ctx, client, ck.domain)
+	if err != nil {
+		return nil, nil, err
+	}
+	chain, _, err := client.CreateOrderCert(ctx, o.FinalizeURL, csr, true)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	leaf, err = validCert(ck, chain, key, m.now())
+	if err != nil {
+		return nil, nil, err
+	}
+	return chain, leaf, nil
+}
+
+// verifyRFC runs the identifier (domain) order-based authorization flow for RFC compliant CAs
+// using each applicable ACME challenge type.
+func (m *Manager) verifyRFC(ctx context.Context, client *acme.Client, domain string) (*acme.Order, error) {
+	// Try each supported challenge type starting with a new order each time.
+	// The nextTyp index of the next challenge type to try is shared across
+	// all order authorizations: if we've tried a challenge type once and it didn't work,
+	// it will most likely not work on another order's authorization either.
+	challengeTypes := m.supportedChallengeTypes()
+	nextTyp := 0 // challengeTypes index
+AuthorizeOrderLoop:
+	for {
+		o, err := client.AuthorizeOrder(ctx, acme.DomainIDs(domain))
+		if err != nil {
+			return nil, err
+		}
+		// Remove all hanging authorizations to reduce rate limit quotas
+		// after we're done.
+		defer func(urls []string) {
+			go m.deactivatePendingAuthz(urls)
+		}(o.AuthzURLs)
+
+		// Check if there's actually anything we need to do.
+		switch o.Status {
+		case acme.StatusReady:
+			// Already authorized.
+			return o, nil
+		case acme.StatusPending:
+			// Continue normal Order-based flow.
+		default:
+			return nil, fmt.Errorf("acme/autocert: invalid new order status %q; order URL: %q", o.Status, o.URI)
+		}
+
+		// Satisfy all pending authorizations.
+		for _, zurl := range o.AuthzURLs {
+			z, err := client.GetAuthorization(ctx, zurl)
+			if err != nil {
+				return nil, err
+			}
+			if z.Status != acme.StatusPending {
+				// We are interested only in pending authorizations.
+				continue
+			}
+			// Pick the next preferred challenge.
+			var chal *acme.Challenge
+			for chal == nil && nextTyp < len(challengeTypes) {
+				chal = pickChallenge(challengeTypes[nextTyp], z.Challenges)
+				nextTyp++
+			}
+			if chal == nil {
+				return nil, fmt.Errorf("acme/autocert: unable to satisfy %q for domain %q: no viable challenge type found", z.URI, domain)
+			}
+			// Respond to the challenge and wait for validation result.
+			cleanup, err := m.fulfill(ctx, client, chal, domain)
+			if err != nil {
+				continue AuthorizeOrderLoop
+			}
+			defer cleanup()
+			if _, err := client.Accept(ctx, chal); err != nil {
+				continue AuthorizeOrderLoop
+			}
+			if _, err := client.WaitAuthorization(ctx, z.URI); err != nil {
+				continue AuthorizeOrderLoop
+			}
+		}
+
+		// All authorizations are satisfied.
+		// Wait for the CA to update the order status.
+		o, err = client.WaitOrder(ctx, o.URI)
+		if err != nil {
+			continue AuthorizeOrderLoop
+		}
+		return o, nil
+	}
+}
+
+func pickChallenge(typ string, chal []*acme.Challenge) *acme.Challenge {
+	for _, c := range chal {
+		if c.Type == typ {
+			return c
+		}
+	}
+	return nil
+}
+
+func (m *Manager) supportedChallengeTypes() []string {
+	m.challengeMu.RLock()
+	defer m.challengeMu.RUnlock()
+	typ := []string{"tls-alpn-01"}
+	if m.tryHTTP01 {
+		typ = append(typ, "http-01")
+	}
+	return typ
+}
+
+// deactivatePendingAuthz relinquishes all authorizations identified by the elements
+// of the provided uri slice which are in "pending" state.
+// It ignores revocation errors.
+//
+// deactivatePendingAuthz takes no context argument and instead runs with its own
+// "detached" context because deactivations are done in a goroutine separate from
+// that of the main issuance or renewal flow.
+func (m *Manager) deactivatePendingAuthz(uri []string) {
+	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
+	defer cancel()
+	client, err := m.acmeClient(ctx)
+	if err != nil {
+		return
+	}
+	for _, u := range uri {
+		z, err := client.GetAuthorization(ctx, u)
+		if err == nil && z.Status == acme.StatusPending {
+			client.RevokeAuthorization(ctx, u)
+		}
+	}
+}
+
+// fulfill provisions a response to the challenge chal.
+// The cleanup is non-nil only if provisioning succeeded.
+func (m *Manager) fulfill(ctx context.Context, client *acme.Client, chal *acme.Challenge, domain string) (cleanup func(), err error) {
+	switch chal.Type {
+	case "tls-alpn-01":
+		cert, err := client.TLSALPN01ChallengeCert(chal.Token, domain)
+		if err != nil {
+			return nil, err
+		}
+		m.putCertToken(ctx, domain, &cert)
+		return func() { go m.deleteCertToken(domain) }, nil
+	case "http-01":
+		resp, err := client.HTTP01ChallengeResponse(chal.Token)
+		if err != nil {
+			return nil, err
+		}
+		p := client.HTTP01ChallengePath(chal.Token)
+		m.putHTTPToken(ctx, p, resp)
+		return func() { go m.deleteHTTPToken(p) }, nil
+	}
+	return nil, fmt.Errorf("acme/autocert: unknown challenge type %q", chal.Type)
+}
+
+// putCertToken stores the token certificate with the specified name
+// in both m.certTokens map and m.Cache.
+func (m *Manager) putCertToken(ctx context.Context, name string, cert *tls.Certificate) {
+	m.challengeMu.Lock()
+	defer m.challengeMu.Unlock()
+	if m.certTokens == nil {
+		m.certTokens = make(map[string]*tls.Certificate)
+	}
+	m.certTokens[name] = cert
+	m.cachePut(ctx, certKey{domain: name, isToken: true}, cert)
+}
+
+// deleteCertToken removes the token certificate with the specified name
+// from both m.certTokens map and m.Cache.
+func (m *Manager) deleteCertToken(name string) {
+	m.challengeMu.Lock()
+	defer m.challengeMu.Unlock()
+	delete(m.certTokens, name)
+	if m.Cache != nil {
+		ck := certKey{domain: name, isToken: true}
+		m.Cache.Delete(context.Background(), ck.String())
+	}
+}
+
+// httpToken retrieves an existing http-01 token value from an in-memory map
+// or the optional cache.
+func (m *Manager) httpToken(ctx context.Context, tokenPath string) ([]byte, error) {
+	m.challengeMu.RLock()
+	defer m.challengeMu.RUnlock()
+	if v, ok := m.httpTokens[tokenPath]; ok {
+		return v, nil
+	}
+	if m.Cache == nil {
+		return nil, fmt.Errorf("acme/autocert: no token at %q", tokenPath)
+	}
+	return m.Cache.Get(ctx, httpTokenCacheKey(tokenPath))
+}
+
+// putHTTPToken stores an http-01 token value using tokenPath as key
+// in both in-memory map and the optional Cache.
+//
+// It ignores any error returned from Cache.Put.
+func (m *Manager) putHTTPToken(ctx context.Context, tokenPath, val string) {
+	m.challengeMu.Lock()
+	defer m.challengeMu.Unlock()
+	if m.httpTokens == nil {
+		m.httpTokens = make(map[string][]byte)
+	}
+	b := []byte(val)
+	m.httpTokens[tokenPath] = b
+	if m.Cache != nil {
+		m.Cache.Put(ctx, httpTokenCacheKey(tokenPath), b)
+	}
+}
+
+// deleteHTTPToken removes an http-01 token value from both in-memory map
+// and the optional Cache, ignoring any error returned from the latter.
+//
+// If m.Cache is non-nil, it blocks until Cache.Delete returns without a timeout.
+func (m *Manager) deleteHTTPToken(tokenPath string) {
+	m.challengeMu.Lock()
+	defer m.challengeMu.Unlock()
+	delete(m.httpTokens, tokenPath)
+	if m.Cache != nil {
+		m.Cache.Delete(context.Background(), httpTokenCacheKey(tokenPath))
+	}
+}
+
+// httpTokenCacheKey returns a key at which an http-01 token value may be stored
+// in the Manager's optional Cache.
+func httpTokenCacheKey(tokenPath string) string {
+	return path.Base(tokenPath) + "+http-01"
+}
+
+// startRenew starts a cert renewal timer loop, one per domain.
+//
+// The loop is scheduled in two cases:
+// - a cert was fetched from cache for the first time (wasn't in m.state)
+// - a new cert was created by m.createCert
+//
+// The key argument is a certificate private key.
+// The exp argument is the cert expiration time (NotAfter).
+func (m *Manager) startRenew(ck certKey, key crypto.Signer, exp time.Time) {
+	m.renewalMu.Lock()
+	defer m.renewalMu.Unlock()
+	if m.renewal[ck] != nil {
+		// another goroutine is already on it
+		return
+	}
+	if m.renewal == nil {
+		m.renewal = make(map[certKey]*domainRenewal)
+	}
+	dr := &domainRenewal{m: m, ck: ck, key: key}
+	m.renewal[ck] = dr
+	dr.start(exp)
+}
+
+// stopRenew stops all currently running cert renewal timers.
+// The timers are not restarted during the lifetime of the Manager.
+func (m *Manager) stopRenew() {
+	m.renewalMu.Lock()
+	defer m.renewalMu.Unlock()
+	for name, dr := range m.renewal {
+		delete(m.renewal, name)
+		dr.stop()
+	}
+}
+
+func (m *Manager) accountKey(ctx context.Context) (crypto.Signer, error) {
+	const keyName = "acme_account+key"
+
+	// Previous versions of autocert stored the value under a different key.
+	const legacyKeyName = "acme_account.key"
+
+	genKey := func() (*ecdsa.PrivateKey, error) {
+		return ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
+	}
+
+	if m.Cache == nil {
+		return genKey()
+	}
+
+	data, err := m.Cache.Get(ctx, keyName)
+	if err == ErrCacheMiss {
+		data, err = m.Cache.Get(ctx, legacyKeyName)
+	}
+	if err == ErrCacheMiss {
+		key, err := genKey()
+		if err != nil {
+			return nil, err
+		}
+		var buf bytes.Buffer
+		if err := encodeECDSAKey(&buf, key); err != nil {
+			return nil, err
+		}
+		if err := m.Cache.Put(ctx, keyName, buf.Bytes()); err != nil {
+			return nil, err
+		}
+		return key, nil
+	}
+	if err != nil {
+		return nil, err
+	}
+
+	priv, _ := pem.Decode(data)
+	if priv == nil || !strings.Contains(priv.Type, "PRIVATE") {
+		return nil, errors.New("acme/autocert: invalid account key found in cache")
+	}
+	return parsePrivateKey(priv.Bytes)
+}
+
+func (m *Manager) acmeClient(ctx context.Context) (*acme.Client, error) {
+	m.clientMu.Lock()
+	defer m.clientMu.Unlock()
+	if m.client != nil {
+		return m.client, nil
+	}
+
+	client := m.Client
+	if client == nil {
+		client = &acme.Client{DirectoryURL: DefaultACMEDirectory}
+	}
+	if client.Key == nil {
+		var err error
+		client.Key, err = m.accountKey(ctx)
+		if err != nil {
+			return nil, err
+		}
+	}
+	if client.UserAgent == "" {
+		client.UserAgent = "autocert"
+	}
+	var contact []string
+	if m.Email != "" {
+		contact = []string{"mailto:" + m.Email}
+	}
+	a := &acme.Account{Contact: contact}
+	_, err := client.Register(ctx, a, m.Prompt)
+	if err == nil || isAccountAlreadyExist(err) {
+		m.client = client
+		err = nil
+	}
+	return m.client, err
+}
+
+// isAccountAlreadyExist reports whether the err, as returned from acme.Client.Register,
+// indicates the account has already been registered.
+func isAccountAlreadyExist(err error) bool {
+	if err == acme.ErrAccountAlreadyExists {
+		return true
+	}
+	ae, ok := err.(*acme.Error)
+	return ok && ae.StatusCode == http.StatusConflict
+}
+
+func (m *Manager) hostPolicy() HostPolicy {
+	if m.HostPolicy != nil {
+		return m.HostPolicy
+	}
+	return defaultHostPolicy
+}
+
+func (m *Manager) renewBefore() time.Duration {
+	if m.RenewBefore > renewJitter {
+		return m.RenewBefore
+	}
+	return 720 * time.Hour // 30 days
+}
+
+func (m *Manager) now() time.Time {
+	if m.nowFunc != nil {
+		return m.nowFunc()
+	}
+	return time.Now()
+}
+
+// certState is ready when its mutex is unlocked for reading.
+type certState struct {
+	sync.RWMutex
+	locked bool              // locked for read/write
+	key    crypto.Signer     // private key for cert
+	cert   [][]byte          // DER encoding
+	leaf   *x509.Certificate // parsed cert[0]; always non-nil if cert != nil
+}
+
+// tlscert creates a tls.Certificate from s.key and s.cert.
+// Callers should wrap it in s.RLock() and s.RUnlock().
+func (s *certState) tlscert() (*tls.Certificate, error) {
+	if s.key == nil {
+		return nil, errors.New("acme/autocert: missing signer")
+	}
+	if len(s.cert) == 0 {
+		return nil, errors.New("acme/autocert: missing certificate")
+	}
+	return &tls.Certificate{
+		PrivateKey:  s.key,
+		Certificate: s.cert,
+		Leaf:        s.leaf,
+	}, nil
+}
+
+// certRequest generates a CSR for the given common name.
+func certRequest(key crypto.Signer, name string, ext []pkix.Extension) ([]byte, error) {
+	req := &x509.CertificateRequest{
+		Subject:         pkix.Name{CommonName: name},
+		DNSNames:        []string{name},
+		ExtraExtensions: ext,
+	}
+	return x509.CreateCertificateRequest(rand.Reader, req, key)
+}
+
+// Attempt to parse the given private key DER block. OpenSSL 0.9.8 generates
+// PKCS#1 private keys by default, while OpenSSL 1.0.0 generates PKCS#8 keys.
+// OpenSSL ecparam generates SEC1 EC private keys for ECDSA. We try all three.
+//
+// Inspired by parsePrivateKey in crypto/tls/tls.go.
+func parsePrivateKey(der []byte) (crypto.Signer, error) {
+	if key, err := x509.ParsePKCS1PrivateKey(der); err == nil {
+		return key, nil
+	}
+	if key, err := x509.ParsePKCS8PrivateKey(der); err == nil {
+		switch key := key.(type) {
+		case *rsa.PrivateKey:
+			return key, nil
+		case *ecdsa.PrivateKey:
+			return key, nil
+		default:
+			return nil, errors.New("acme/autocert: unknown private key type in PKCS#8 wrapping")
+		}
+	}
+	if key, err := x509.ParseECPrivateKey(der); err == nil {
+		return key, nil
+	}
+
+	return nil, errors.New("acme/autocert: failed to parse private key")
+}
+
+// validCert parses a cert chain provided as der argument and verifies the leaf and der[0]
+// correspond to the private key, the domain and key type match, and expiration dates
+// are valid. It doesn't do any revocation checking.
+//
+// The returned value is the verified leaf cert.
+func validCert(ck certKey, der [][]byte, key crypto.Signer, now time.Time) (leaf *x509.Certificate, err error) {
+	// parse public part(s)
+	var n int
+	for _, b := range der {
+		n += len(b)
+	}
+	pub := make([]byte, n)
+	n = 0
+	for _, b := range der {
+		n += copy(pub[n:], b)
+	}
+	x509Cert, err := x509.ParseCertificates(pub)
+	if err != nil || len(x509Cert) == 0 {
+		return nil, errors.New("acme/autocert: no public key found")
+	}
+	// verify the leaf is not expired and matches the domain name
+	leaf = x509Cert[0]
+	if now.Before(leaf.NotBefore) {
+		return nil, errors.New("acme/autocert: certificate is not valid yet")
+	}
+	if now.After(leaf.NotAfter) {
+		return nil, errors.New("acme/autocert: expired certificate")
+	}
+	if err := leaf.VerifyHostname(ck.domain); err != nil {
+		return nil, err
+	}
+	// renew certificates revoked by Let's Encrypt in January 2022
+	if isRevokedLetsEncrypt(leaf) {
+		return nil, errors.New("acme/autocert: certificate was probably revoked by Let's Encrypt")
+	}
+	// ensure the leaf corresponds to the private key and matches the certKey type
+	switch pub := leaf.PublicKey.(type) {
+	case *rsa.PublicKey:
+		prv, ok := key.(*rsa.PrivateKey)
+		if !ok {
+			return nil, errors.New("acme/autocert: private key type does not match public key type")
+		}
+		if pub.N.Cmp(prv.N) != 0 {
+			return nil, errors.New("acme/autocert: private key does not match public key")
+		}
+		if !ck.isRSA && !ck.isToken {
+			return nil, errors.New("acme/autocert: key type does not match expected value")
+		}
+	case *ecdsa.PublicKey:
+		prv, ok := key.(*ecdsa.PrivateKey)
+		if !ok {
+			return nil, errors.New("acme/autocert: private key type does not match public key type")
+		}
+		if pub.X.Cmp(prv.X) != 0 || pub.Y.Cmp(prv.Y) != 0 {
+			return nil, errors.New("acme/autocert: private key does not match public key")
+		}
+		if ck.isRSA && !ck.isToken {
+			return nil, errors.New("acme/autocert: key type does not match expected value")
+		}
+	default:
+		return nil, errors.New("acme/autocert: unknown public key algorithm")
+	}
+	return leaf, nil
+}
+
+// https://community.letsencrypt.org/t/2022-01-25-issue-with-tls-alpn-01-validation-method/170450
+var letsEncryptFixDeployTime = time.Date(2022, time.January, 26, 00, 48, 0, 0, time.UTC)
+
+// isRevokedLetsEncrypt returns whether the certificate is likely to be part of
+// a batch of certificates revoked by Let's Encrypt in January 2022. This check
+// can be safely removed from May 2022.
+func isRevokedLetsEncrypt(cert *x509.Certificate) bool {
+	O := cert.Issuer.Organization
+	return len(O) == 1 && O[0] == "Let's Encrypt" &&
+		cert.NotBefore.Before(letsEncryptFixDeployTime)
+}
+
+type lockedMathRand struct {
+	sync.Mutex
+	rnd *mathrand.Rand
+}
+
+func (r *lockedMathRand) int63n(max int64) int64 {
+	r.Lock()
+	n := r.rnd.Int63n(max)
+	r.Unlock()
+	return n
+}
+
+// For easier testing.
+var (
+	// Called when a state is removed.
+	testDidRemoveState = func(certKey) {}
+)
diff --git a/vendor/golang.org/x/crypto/acme/autocert/cache.go b/vendor/golang.org/x/crypto/acme/autocert/cache.go
new file mode 100644
index 0000000000..03f63022fa
--- /dev/null
+++ b/vendor/golang.org/x/crypto/acme/autocert/cache.go
@@ -0,0 +1,136 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package autocert
+
+import (
+	"context"
+	"errors"
+	"io/ioutil"
+	"os"
+	"path/filepath"
+)
+
+// ErrCacheMiss is returned when a certificate is not found in cache.
+var ErrCacheMiss = errors.New("acme/autocert: certificate cache miss")
+
+// Cache is used by Manager to store and retrieve previously obtained certificates
+// and other account data as opaque blobs.
+//
+// Cache implementations should not rely on the key naming pattern. Keys can
+// include any printable ASCII characters, except the following: \/:*?"<>|
+type Cache interface {
+	// Get returns a certificate data for the specified key.
+	// If there's no such key, Get returns ErrCacheMiss.
+	Get(ctx context.Context, key string) ([]byte, error)
+
+	// Put stores the data in the cache under the specified key.
+	// Underlying implementations may use any data storage format,
+	// as long as the reverse operation, Get, results in the original data.
+	Put(ctx context.Context, key string, data []byte) error
+
+	// Delete removes a certificate data from the cache under the specified key.
+	// If there's no such key in the cache, Delete returns nil.
+	Delete(ctx context.Context, key string) error
+}
+
+// DirCache implements Cache using a directory on the local filesystem.
+// If the directory does not exist, it will be created with 0700 permissions.
+type DirCache string
+
+// Get reads a certificate data from the specified file name.
+func (d DirCache) Get(ctx context.Context, name string) ([]byte, error) {
+	name = filepath.Join(string(d), name)
+	var (
+		data []byte
+		err  error
+		done = make(chan struct{})
+	)
+	go func() {
+		data, err = ioutil.ReadFile(name)
+		close(done)
+	}()
+	select {
+	case <-ctx.Done():
+		return nil, ctx.Err()
+	case <-done:
+	}
+	if os.IsNotExist(err) {
+		return nil, ErrCacheMiss
+	}
+	return data, err
+}
+
+// Put writes the certificate data to the specified file name.
+// The file will be created with 0600 permissions.
+func (d DirCache) Put(ctx context.Context, name string, data []byte) error {
+	if err := os.MkdirAll(string(d), 0700); err != nil {
+		return err
+	}
+
+	done := make(chan struct{})
+	var err error
+	go func() {
+		defer close(done)
+		var tmp string
+		if tmp, err = d.writeTempFile(name, data); err != nil {
+			return
+		}
+		defer os.Remove(tmp)
+		select {
+		case <-ctx.Done():
+			// Don't overwrite the file if the context was canceled.
+		default:
+			newName := filepath.Join(string(d), name)
+			err = os.Rename(tmp, newName)
+		}
+	}()
+	select {
+	case <-ctx.Done():
+		return ctx.Err()
+	case <-done:
+	}
+	return err
+}
+
+// Delete removes the specified file name.
+func (d DirCache) Delete(ctx context.Context, name string) error {
+	name = filepath.Join(string(d), name)
+	var (
+		err  error
+		done = make(chan struct{})
+	)
+	go func() {
+		err = os.Remove(name)
+		close(done)
+	}()
+	select {
+	case <-ctx.Done():
+		return ctx.Err()
+	case <-done:
+	}
+	if err != nil && !os.IsNotExist(err) {
+		return err
+	}
+	return nil
+}
+
+// writeTempFile writes b to a temporary file, closes the file and returns its path.
+func (d DirCache) writeTempFile(prefix string, b []byte) (name string, reterr error) {
+	// TempFile uses 0600 permissions
+	f, err := ioutil.TempFile(string(d), prefix)
+	if err != nil {
+		return "", err
+	}
+	defer func() {
+		if reterr != nil {
+			os.Remove(f.Name())
+		}
+	}()
+	if _, err := f.Write(b); err != nil {
+		f.Close()
+		return "", err
+	}
+	return f.Name(), f.Close()
+}
diff --git a/vendor/golang.org/x/crypto/acme/autocert/internal/acmetest/ca.go b/vendor/golang.org/x/crypto/acme/autocert/internal/acmetest/ca.go
new file mode 100644
index 0000000000..8c4c6426a1
--- /dev/null
+++ b/vendor/golang.org/x/crypto/acme/autocert/internal/acmetest/ca.go
@@ -0,0 +1,762 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package acmetest provides types for testing acme and autocert packages.
+//
+// TODO: Consider moving this to x/crypto/acme/internal/acmetest for acme tests as well.
+package acmetest
+
+import (
+	"context"
+	"crypto"
+	"crypto/ecdsa"
+	"crypto/elliptic"
+	"crypto/rand"
+	"crypto/rsa"
+	"crypto/tls"
+	"crypto/x509"
+	"crypto/x509/pkix"
+	"encoding/asn1"
+	"encoding/base64"
+	"encoding/json"
+	"encoding/pem"
+	"fmt"
+	"io"
+	"math/big"
+	"net"
+	"net/http"
+	"net/http/httptest"
+	"path"
+	"strconv"
+	"strings"
+	"sync"
+	"testing"
+	"time"
+
+	"golang.org/x/crypto/acme"
+)
+
+// CAServer is a simple test server which implements ACME spec bits needed for testing.
+type CAServer struct {
+	rootKey      crypto.Signer
+	rootCert     []byte // DER encoding
+	rootTemplate *x509.Certificate
+
+	t              *testing.T
+	server         *httptest.Server
+	issuer         pkix.Name
+	challengeTypes []string
+	url            string
+	roots          *x509.CertPool
+
+	mu             sync.Mutex
+	certCount      int                           // number of issued certs
+	acctRegistered bool                          // set once an account has been registered
+	domainAddr     map[string]string             // domain name to addr:port resolution
+	domainGetCert  map[string]getCertificateFunc // domain name to GetCertificate function
+	domainHandler  map[string]http.Handler       // domain name to Handle function
+	validAuthz     map[string]*authorization     // valid authz, keyed by domain name
+	authorizations []*authorization              // all authz, index is used as ID
+	orders         []*order                      // index is used as order ID
+	errors         []error                       // encountered client errors
+}
+
+type getCertificateFunc func(hello *tls.ClientHelloInfo) (*tls.Certificate, error)
+
+// NewCAServer creates a new ACME test server. The returned CAServer issues
+// certs signed with the CA roots available in the Roots field.
+func NewCAServer(t *testing.T) *CAServer {
+	ca := &CAServer{t: t,
+		challengeTypes: []string{"fake-01", "tls-alpn-01", "http-01"},
+		domainAddr:     make(map[string]string),
+		domainGetCert:  make(map[string]getCertificateFunc),
+		domainHandler:  make(map[string]http.Handler),
+		validAuthz:     make(map[string]*authorization),
+	}
+
+	ca.server = httptest.NewUnstartedServer(http.HandlerFunc(ca.handle))
+
+	r, err := rand.Int(rand.Reader, big.NewInt(1000000))
+	if err != nil {
+		panic(fmt.Sprintf("rand.Int: %v", err))
+	}
+	ca.issuer = pkix.Name{
+		Organization: []string{"Test Acme Co"},
+		CommonName:   "Root CA " + r.String(),
+	}
+
+	return ca
+}
+
+func (ca *CAServer) generateRoot() {
+	key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
+	if err != nil {
+		panic(fmt.Sprintf("ecdsa.GenerateKey: %v", err))
+	}
+	tmpl := &x509.Certificate{
+		SerialNumber:          big.NewInt(1),
+		Subject:               ca.issuer,
+		NotBefore:             time.Now(),
+		NotAfter:              time.Now().Add(365 * 24 * time.Hour),
+		KeyUsage:              x509.KeyUsageCertSign,
+		BasicConstraintsValid: true,
+		IsCA:                  true,
+	}
+	der, err := x509.CreateCertificate(rand.Reader, tmpl, tmpl, &key.PublicKey, key)
+	if err != nil {
+		panic(fmt.Sprintf("x509.CreateCertificate: %v", err))
+	}
+	cert, err := x509.ParseCertificate(der)
+	if err != nil {
+		panic(fmt.Sprintf("x509.ParseCertificate: %v", err))
+	}
+	ca.roots = x509.NewCertPool()
+	ca.roots.AddCert(cert)
+	ca.rootKey = key
+	ca.rootCert = der
+	ca.rootTemplate = tmpl
+}
+
+// IssuerName sets the name of the issuing CA.
+func (ca *CAServer) IssuerName(name pkix.Name) *CAServer {
+	if ca.url != "" {
+		panic("IssuerName must be called before Start")
+	}
+	ca.issuer = name
+	return ca
+}
+
+// ChallengeTypes sets the supported challenge types.
+func (ca *CAServer) ChallengeTypes(types ...string) *CAServer {
+	if ca.url != "" {
+		panic("ChallengeTypes must be called before Start")
+	}
+	ca.challengeTypes = types
+	return ca
+}
+
+// URL returns the server address, after Start has been called.
+func (ca *CAServer) URL() string {
+	if ca.url == "" {
+		panic("URL called before Start")
+	}
+	return ca.url
+}
+
+// Roots returns a pool cointaining the CA root.
+func (ca *CAServer) Roots() *x509.CertPool {
+	if ca.url == "" {
+		panic("Roots called before Start")
+	}
+	return ca.roots
+}
+
+// Start starts serving requests. The server address becomes available in the
+// URL field.
+func (ca *CAServer) Start() *CAServer {
+	if ca.url == "" {
+		ca.generateRoot()
+		ca.server.Start()
+		ca.t.Cleanup(ca.server.Close)
+		ca.url = ca.server.URL
+	}
+	return ca
+}
+
+func (ca *CAServer) serverURL(format string, arg ...interface{}) string {
+	return ca.server.URL + fmt.Sprintf(format, arg...)
+}
+
+func (ca *CAServer) addr(domain string) (string, bool) {
+	ca.mu.Lock()
+	defer ca.mu.Unlock()
+	addr, ok := ca.domainAddr[domain]
+	return addr, ok
+}
+
+func (ca *CAServer) getCert(domain string) (getCertificateFunc, bool) {
+	ca.mu.Lock()
+	defer ca.mu.Unlock()
+	f, ok := ca.domainGetCert[domain]
+	return f, ok
+}
+
+func (ca *CAServer) getHandler(domain string) (http.Handler, bool) {
+	ca.mu.Lock()
+	defer ca.mu.Unlock()
+	h, ok := ca.domainHandler[domain]
+	return h, ok
+}
+
+func (ca *CAServer) httpErrorf(w http.ResponseWriter, code int, format string, a ...interface{}) {
+	s := fmt.Sprintf(format, a...)
+	ca.t.Errorf(format, a...)
+	http.Error(w, s, code)
+}
+
+// Resolve adds a domain to address resolution for the ca to dial to
+// when validating challenges for the domain authorization.
+func (ca *CAServer) Resolve(domain, addr string) {
+	ca.mu.Lock()
+	defer ca.mu.Unlock()
+	ca.domainAddr[domain] = addr
+}
+
+// ResolveGetCertificate redirects TLS connections for domain to f when
+// validating challenges for the domain authorization.
+func (ca *CAServer) ResolveGetCertificate(domain string, f getCertificateFunc) {
+	ca.mu.Lock()
+	defer ca.mu.Unlock()
+	ca.domainGetCert[domain] = f
+}
+
+// ResolveHandler redirects HTTP requests for domain to f when
+// validating challenges for the domain authorization.
+func (ca *CAServer) ResolveHandler(domain string, h http.Handler) {
+	ca.mu.Lock()
+	defer ca.mu.Unlock()
+	ca.domainHandler[domain] = h
+}
+
+type discovery struct {
+	NewNonce   string `json:"newNonce"`
+	NewAccount string `json:"newAccount"`
+	NewOrder   string `json:"newOrder"`
+	NewAuthz   string `json:"newAuthz"`
+}
+
+type challenge struct {
+	URI   string `json:"uri"`
+	Type  string `json:"type"`
+	Token string `json:"token"`
+}
+
+type authorization struct {
+	Status     string      `json:"status"`
+	Challenges []challenge `json:"challenges"`
+
+	domain string
+	id     int
+}
+
+type order struct {
+	Status      string   `json:"status"`
+	AuthzURLs   []string `json:"authorizations"`
+	FinalizeURL string   `json:"finalize"`    // CSR submit URL
+	CertURL     string   `json:"certificate"` // already issued cert
+
+	leaf []byte // issued cert in DER format
+}
+
+func (ca *CAServer) handle(w http.ResponseWriter, r *http.Request) {
+	ca.t.Logf("%s %s", r.Method, r.URL)
+	w.Header().Set("Replay-Nonce", "nonce")
+	// TODO: Verify nonce header for all POST requests.
+
+	switch {
+	default:
+		ca.httpErrorf(w, http.StatusBadRequest, "unrecognized r.URL.Path: %s", r.URL.Path)
+
+	// Discovery request.
+	case r.URL.Path == "/":
+		resp := &discovery{
+			NewNonce:   ca.serverURL("/new-nonce"),
+			NewAccount: ca.serverURL("/new-account"),
+			NewOrder:   ca.serverURL("/new-order"),
+		}
+		if err := json.NewEncoder(w).Encode(resp); err != nil {
+			panic(fmt.Sprintf("discovery response: %v", err))
+		}
+
+	// Nonce requests.
+	case r.URL.Path == "/new-nonce":
+		// Nonce values are always set. Nothing else to do.
+		return
+
+	// Client key registration request.
+	case r.URL.Path == "/new-account":
+		ca.mu.Lock()
+		defer ca.mu.Unlock()
+		if ca.acctRegistered {
+			ca.httpErrorf(w, http.StatusServiceUnavailable, "multiple accounts are not implemented")
+			return
+		}
+		ca.acctRegistered = true
+		// TODO: Check the user account key against a ca.accountKeys?
+		w.Header().Set("Location", ca.serverURL("/accounts/1"))
+		w.WriteHeader(http.StatusCreated)
+		w.Write([]byte("{}"))
+
+	// New order request.
+	case r.URL.Path == "/new-order":
+		var req struct {
+			Identifiers []struct{ Value string }
+		}
+		if err := decodePayload(&req, r.Body); err != nil {
+			ca.httpErrorf(w, http.StatusBadRequest, err.Error())
+			return
+		}
+		ca.mu.Lock()
+		defer ca.mu.Unlock()
+		o := &order{Status: acme.StatusPending}
+		for _, id := range req.Identifiers {
+			z := ca.authz(id.Value)
+			o.AuthzURLs = append(o.AuthzURLs, ca.serverURL("/authz/%d", z.id))
+		}
+		orderID := len(ca.orders)
+		ca.orders = append(ca.orders, o)
+		w.Header().Set("Location", ca.serverURL("/orders/%d", orderID))
+		w.WriteHeader(http.StatusCreated)
+		if err := json.NewEncoder(w).Encode(o); err != nil {
+			panic(err)
+		}
+
+	// Existing order status requests.
+	case strings.HasPrefix(r.URL.Path, "/orders/"):
+		ca.mu.Lock()
+		defer ca.mu.Unlock()
+		o, err := ca.storedOrder(strings.TrimPrefix(r.URL.Path, "/orders/"))
+		if err != nil {
+			ca.httpErrorf(w, http.StatusBadRequest, err.Error())
+			return
+		}
+		if err := json.NewEncoder(w).Encode(o); err != nil {
+			panic(err)
+		}
+
+	// Accept challenge requests.
+	case strings.HasPrefix(r.URL.Path, "/challenge/"):
+		parts := strings.Split(r.URL.Path, "/")
+		typ, id := parts[len(parts)-2], parts[len(parts)-1]
+		ca.mu.Lock()
+		supported := false
+		for _, suppTyp := range ca.challengeTypes {
+			if suppTyp == typ {
+				supported = true
+			}
+		}
+		a, err := ca.storedAuthz(id)
+		ca.mu.Unlock()
+		if !supported {
+			ca.httpErrorf(w, http.StatusBadRequest, "unsupported challenge: %v", typ)
+			return
+		}
+		if err != nil {
+			ca.httpErrorf(w, http.StatusBadRequest, "challenge accept: %v", err)
+			return
+		}
+		go ca.validateChallenge(a, typ)
+		w.Write([]byte("{}"))
+
+	// Get authorization status requests.
+	case strings.HasPrefix(r.URL.Path, "/authz/"):
+		var req struct{ Status string }
+		decodePayload(&req, r.Body)
+		deactivate := req.Status == "deactivated"
+		ca.mu.Lock()
+		defer ca.mu.Unlock()
+		authz, err := ca.storedAuthz(strings.TrimPrefix(r.URL.Path, "/authz/"))
+		if err != nil {
+			ca.httpErrorf(w, http.StatusNotFound, "%v", err)
+			return
+		}
+		if deactivate {
+			// Note we don't invalidate authorized orders as we should.
+			authz.Status = "deactivated"
+			ca.t.Logf("authz %d is now %s", authz.id, authz.Status)
+			ca.updatePendingOrders()
+		}
+		if err := json.NewEncoder(w).Encode(authz); err != nil {
+			panic(fmt.Sprintf("encoding authz %d: %v", authz.id, err))
+		}
+
+	// Certificate issuance request.
+	case strings.HasPrefix(r.URL.Path, "/new-cert/"):
+		ca.mu.Lock()
+		defer ca.mu.Unlock()
+		orderID := strings.TrimPrefix(r.URL.Path, "/new-cert/")
+		o, err := ca.storedOrder(orderID)
+		if err != nil {
+			ca.httpErrorf(w, http.StatusBadRequest, err.Error())
+			return
+		}
+		if o.Status != acme.StatusReady {
+			ca.httpErrorf(w, http.StatusForbidden, "order status: %s", o.Status)
+			return
+		}
+		// Validate CSR request.
+		var req struct {
+			CSR string `json:"csr"`
+		}
+		decodePayload(&req, r.Body)
+		b, _ := base64.RawURLEncoding.DecodeString(req.CSR)
+		csr, err := x509.ParseCertificateRequest(b)
+		if err != nil {
+			ca.httpErrorf(w, http.StatusBadRequest, err.Error())
+			return
+		}
+		// Issue the certificate.
+		der, err := ca.leafCert(csr)
+		if err != nil {
+			ca.httpErrorf(w, http.StatusBadRequest, "new-cert response: ca.leafCert: %v", err)
+			return
+		}
+		o.leaf = der
+		o.CertURL = ca.serverURL("/issued-cert/%s", orderID)
+		o.Status = acme.StatusValid
+		if err := json.NewEncoder(w).Encode(o); err != nil {
+			panic(err)
+		}
+
+	// Already issued cert download requests.
+	case strings.HasPrefix(r.URL.Path, "/issued-cert/"):
+		ca.mu.Lock()
+		defer ca.mu.Unlock()
+		o, err := ca.storedOrder(strings.TrimPrefix(r.URL.Path, "/issued-cert/"))
+		if err != nil {
+			ca.httpErrorf(w, http.StatusBadRequest, err.Error())
+			return
+		}
+		if o.Status != acme.StatusValid {
+			ca.httpErrorf(w, http.StatusForbidden, "order status: %s", o.Status)
+			return
+		}
+		w.Header().Set("Content-Type", "application/pem-certificate-chain")
+		pem.Encode(w, &pem.Block{Type: "CERTIFICATE", Bytes: o.leaf})
+		pem.Encode(w, &pem.Block{Type: "CERTIFICATE", Bytes: ca.rootCert})
+	}
+}
+
+// storedOrder retrieves a previously created order at index i.
+// It requires ca.mu to be locked.
+func (ca *CAServer) storedOrder(i string) (*order, error) {
+	idx, err := strconv.Atoi(i)
+	if err != nil {
+		return nil, fmt.Errorf("storedOrder: %v", err)
+	}
+	if idx < 0 {
+		return nil, fmt.Errorf("storedOrder: invalid order index %d", idx)
+	}
+	if idx > len(ca.orders)-1 {
+		return nil, fmt.Errorf("storedOrder: no such order %d", idx)
+	}
+
+	ca.updatePendingOrders()
+	return ca.orders[idx], nil
+}
+
+// storedAuthz retrieves a previously created authz at index i.
+// It requires ca.mu to be locked.
+func (ca *CAServer) storedAuthz(i string) (*authorization, error) {
+	idx, err := strconv.Atoi(i)
+	if err != nil {
+		return nil, fmt.Errorf("storedAuthz: %v", err)
+	}
+	if idx < 0 {
+		return nil, fmt.Errorf("storedAuthz: invalid authz index %d", idx)
+	}
+	if idx > len(ca.authorizations)-1 {
+		return nil, fmt.Errorf("storedAuthz: no such authz %d", idx)
+	}
+	return ca.authorizations[idx], nil
+}
+
+// authz returns an existing valid authorization for the identifier or creates a
+// new one. It requires ca.mu to be locked.
+func (ca *CAServer) authz(identifier string) *authorization {
+	authz, ok := ca.validAuthz[identifier]
+	if !ok {
+		authzId := len(ca.authorizations)
+		authz = &authorization{
+			id:     authzId,
+			domain: identifier,
+			Status: acme.StatusPending,
+		}
+		for _, typ := range ca.challengeTypes {
+			authz.Challenges = append(authz.Challenges, challenge{
+				Type:  typ,
+				URI:   ca.serverURL("/challenge/%s/%d", typ, authzId),
+				Token: challengeToken(authz.domain, typ, authzId),
+			})
+		}
+		ca.authorizations = append(ca.authorizations, authz)
+	}
+	return authz
+}
+
+// leafCert issues a new certificate.
+// It requires ca.mu to be locked.
+func (ca *CAServer) leafCert(csr *x509.CertificateRequest) (der []byte, err error) {
+	ca.certCount++ // next leaf cert serial number
+	leaf := &x509.Certificate{
+		SerialNumber:          big.NewInt(int64(ca.certCount)),
+		Subject:               pkix.Name{Organization: []string{"Test Acme Co"}},
+		NotBefore:             time.Now(),
+		NotAfter:              time.Now().Add(90 * 24 * time.Hour),
+		KeyUsage:              x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment,
+		ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
+		DNSNames:              csr.DNSNames,
+		BasicConstraintsValid: true,
+	}
+	if len(csr.DNSNames) == 0 {
+		leaf.DNSNames = []string{csr.Subject.CommonName}
+	}
+	return x509.CreateCertificate(rand.Reader, leaf, ca.rootTemplate, csr.PublicKey, ca.rootKey)
+}
+
+// LeafCert issues a leaf certificate.
+func (ca *CAServer) LeafCert(name, keyType string, notBefore, notAfter time.Time) *tls.Certificate {
+	if ca.url == "" {
+		panic("LeafCert called before Start")
+	}
+
+	ca.mu.Lock()
+	defer ca.mu.Unlock()
+	var pk crypto.Signer
+	switch keyType {
+	case "RSA":
+		var err error
+		pk, err = rsa.GenerateKey(rand.Reader, 1024)
+		if err != nil {
+			ca.t.Fatal(err)
+		}
+	case "ECDSA":
+		var err error
+		pk, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
+		if err != nil {
+			ca.t.Fatal(err)
+		}
+	default:
+		panic("LeafCert: unknown key type")
+	}
+	ca.certCount++ // next leaf cert serial number
+	leaf := &x509.Certificate{
+		SerialNumber:          big.NewInt(int64(ca.certCount)),
+		Subject:               pkix.Name{Organization: []string{"Test Acme Co"}},
+		NotBefore:             notBefore,
+		NotAfter:              notAfter,
+		KeyUsage:              x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment,
+		ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
+		DNSNames:              []string{name},
+		BasicConstraintsValid: true,
+	}
+	der, err := x509.CreateCertificate(rand.Reader, leaf, ca.rootTemplate, pk.Public(), ca.rootKey)
+	if err != nil {
+		ca.t.Fatal(err)
+	}
+	return &tls.Certificate{
+		Certificate: [][]byte{der},
+		PrivateKey:  pk,
+	}
+}
+
+func (ca *CAServer) validateChallenge(authz *authorization, typ string) {
+	var err error
+	switch typ {
+	case "tls-alpn-01":
+		err = ca.verifyALPNChallenge(authz)
+	case "http-01":
+		err = ca.verifyHTTPChallenge(authz)
+	default:
+		panic(fmt.Sprintf("validation of %q is not implemented", typ))
+	}
+	ca.mu.Lock()
+	defer ca.mu.Unlock()
+	if err != nil {
+		authz.Status = "invalid"
+	} else {
+		authz.Status = "valid"
+		ca.validAuthz[authz.domain] = authz
+	}
+	ca.t.Logf("validated %q for %q, err: %v", typ, authz.domain, err)
+	ca.t.Logf("authz %d is now %s", authz.id, authz.Status)
+
+	ca.updatePendingOrders()
+}
+
+func (ca *CAServer) updatePendingOrders() {
+	// Update all pending orders.
+	// An order becomes "ready" if all authorizations are "valid".
+	// An order becomes "invalid" if any authorization is "invalid".
+	// Status changes: https://tools.ietf.org/html/rfc8555#section-7.1.6
+	for i, o := range ca.orders {
+		if o.Status != acme.StatusPending {
+			continue
+		}
+
+		countValid, countInvalid := ca.validateAuthzURLs(o.AuthzURLs, i)
+		if countInvalid > 0 {
+			o.Status = acme.StatusInvalid
+			ca.t.Logf("order %d is now invalid", i)
+			continue
+		}
+		if countValid == len(o.AuthzURLs) {
+			o.Status = acme.StatusReady
+			o.FinalizeURL = ca.serverURL("/new-cert/%d", i)
+			ca.t.Logf("order %d is now ready", i)
+		}
+	}
+}
+
+func (ca *CAServer) validateAuthzURLs(urls []string, orderNum int) (countValid, countInvalid int) {
+	for _, zurl := range urls {
+		z, err := ca.storedAuthz(path.Base(zurl))
+		if err != nil {
+			ca.t.Logf("no authz %q for order %d", zurl, orderNum)
+			continue
+		}
+		if z.Status == acme.StatusInvalid {
+			countInvalid++
+		}
+		if z.Status == acme.StatusValid {
+			countValid++
+		}
+	}
+	return countValid, countInvalid
+}
+
+func (ca *CAServer) verifyALPNChallenge(a *authorization) error {
+	const acmeALPNProto = "acme-tls/1"
+
+	addr, haveAddr := ca.addr(a.domain)
+	getCert, haveGetCert := ca.getCert(a.domain)
+	if !haveAddr && !haveGetCert {
+		return fmt.Errorf("no resolution information for %q", a.domain)
+	}
+	if haveAddr && haveGetCert {
+		return fmt.Errorf("overlapping resolution information for %q", a.domain)
+	}
+
+	var crt *x509.Certificate
+	switch {
+	case haveAddr:
+		conn, err := tls.Dial("tcp", addr, &tls.Config{
+			ServerName:         a.domain,
+			InsecureSkipVerify: true,
+			NextProtos:         []string{acmeALPNProto},
+			MinVersion:         tls.VersionTLS12,
+		})
+		if err != nil {
+			return err
+		}
+		if v := conn.ConnectionState().NegotiatedProtocol; v != acmeALPNProto {
+			return fmt.Errorf("CAServer: verifyALPNChallenge: negotiated proto is %q; want %q", v, acmeALPNProto)
+		}
+		if n := len(conn.ConnectionState().PeerCertificates); n != 1 {
+			return fmt.Errorf("len(PeerCertificates) = %d; want 1", n)
+		}
+		crt = conn.ConnectionState().PeerCertificates[0]
+	case haveGetCert:
+		hello := &tls.ClientHelloInfo{
+			ServerName: a.domain,
+			// TODO: support selecting ECDSA.
+			CipherSuites:      []uint16{tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305},
+			SupportedProtos:   []string{acme.ALPNProto},
+			SupportedVersions: []uint16{tls.VersionTLS12},
+		}
+		c, err := getCert(hello)
+		if err != nil {
+			return err
+		}
+		crt, err = x509.ParseCertificate(c.Certificate[0])
+		if err != nil {
+			return err
+		}
+	}
+
+	if err := crt.VerifyHostname(a.domain); err != nil {
+		return fmt.Errorf("verifyALPNChallenge: VerifyHostname: %v", err)
+	}
+	// See RFC 8737, Section 6.1.
+	oid := asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 1, 31}
+	for _, x := range crt.Extensions {
+		if x.Id.Equal(oid) {
+			// TODO: check the token.
+			return nil
+		}
+	}
+	return fmt.Errorf("verifyTokenCert: no id-pe-acmeIdentifier extension found")
+}
+
+func (ca *CAServer) verifyHTTPChallenge(a *authorization) error {
+	addr, haveAddr := ca.addr(a.domain)
+	handler, haveHandler := ca.getHandler(a.domain)
+	if !haveAddr && !haveHandler {
+		return fmt.Errorf("no resolution information for %q", a.domain)
+	}
+	if haveAddr && haveHandler {
+		return fmt.Errorf("overlapping resolution information for %q", a.domain)
+	}
+
+	token := challengeToken(a.domain, "http-01", a.id)
+	path := "/.well-known/acme-challenge/" + token
+
+	var body string
+	switch {
+	case haveAddr:
+		t := &http.Transport{
+			DialContext: func(ctx context.Context, network, _ string) (net.Conn, error) {
+				return (&net.Dialer{}).DialContext(ctx, network, addr)
+			},
+		}
+		req, err := http.NewRequest("GET", "http://"+a.domain+path, nil)
+		if err != nil {
+			return err
+		}
+		res, err := t.RoundTrip(req)
+		if err != nil {
+			return err
+		}
+		if res.StatusCode != http.StatusOK {
+			return fmt.Errorf("http token: w.Code = %d; want %d", res.StatusCode, http.StatusOK)
+		}
+		b, err := io.ReadAll(res.Body)
+		if err != nil {
+			return err
+		}
+		body = string(b)
+	case haveHandler:
+		r := httptest.NewRequest("GET", path, nil)
+		r.Host = a.domain
+		w := httptest.NewRecorder()
+		handler.ServeHTTP(w, r)
+		if w.Code != http.StatusOK {
+			return fmt.Errorf("http token: w.Code = %d; want %d", w.Code, http.StatusOK)
+		}
+		body = w.Body.String()
+	}
+
+	if !strings.HasPrefix(body, token) {
+		return fmt.Errorf("http token value = %q; want 'token-http-01.' prefix", body)
+	}
+	return nil
+}
+
+func decodePayload(v interface{}, r io.Reader) error {
+	var req struct{ Payload string }
+	if err := json.NewDecoder(r).Decode(&req); err != nil {
+		return err
+	}
+	payload, err := base64.RawURLEncoding.DecodeString(req.Payload)
+	if err != nil {
+		return err
+	}
+	return json.Unmarshal(payload, v)
+}
+
+func challengeToken(domain, challType string, authzID int) string {
+	return fmt.Sprintf("token-%s-%s-%d", domain, challType, authzID)
+}
+
+func unique(a []string) []string {
+	seen := make(map[string]bool)
+	var res []string
+	for _, s := range a {
+		if s != "" && !seen[s] {
+			seen[s] = true
+			res = append(res, s)
+		}
+	}
+	return res
+}
diff --git a/vendor/golang.org/x/crypto/acme/autocert/listener.go b/vendor/golang.org/x/crypto/acme/autocert/listener.go
new file mode 100644
index 0000000000..cb48609737
--- /dev/null
+++ b/vendor/golang.org/x/crypto/acme/autocert/listener.go
@@ -0,0 +1,155 @@
+// Copyright 2017 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 autocert
+
+import (
+	"crypto/tls"
+	"log"
+	"net"
+	"os"
+	"path/filepath"
+	"runtime"
+	"time"
+)
+
+// NewListener returns a net.Listener that listens on the standard TLS
+// port (443) on all interfaces and returns *tls.Conn connections with
+// LetsEncrypt certificates for the provided domain or domains.
+//
+// It enables one-line HTTPS servers:
+//
+//     log.Fatal(http.Serve(autocert.NewListener("example.com"), handler))
+//
+// NewListener is a convenience function for a common configuration.
+// More complex or custom configurations can use the autocert.Manager
+// type instead.
+//
+// Use of this function implies acceptance of the LetsEncrypt Terms of
+// Service. If domains is not empty, the provided domains are passed
+// to HostWhitelist. If domains is empty, the listener will do
+// LetsEncrypt challenges for any requested domain, which is not
+// recommended.
+//
+// Certificates are cached in a "golang-autocert" directory under an
+// operating system-specific cache or temp directory. This may not
+// be suitable for servers spanning multiple machines.
+//
+// The returned listener uses a *tls.Config that enables HTTP/2, and
+// should only be used with servers that support HTTP/2.
+//
+// The returned Listener also enables TCP keep-alives on the accepted
+// connections. The returned *tls.Conn are returned before their TLS
+// handshake has completed.
+func NewListener(domains ...string) net.Listener {
+	m := &Manager{
+		Prompt: AcceptTOS,
+	}
+	if len(domains) > 0 {
+		m.HostPolicy = HostWhitelist(domains...)
+	}
+	dir := cacheDir()
+	if err := os.MkdirAll(dir, 0700); err != nil {
+		log.Printf("warning: autocert.NewListener not using a cache: %v", err)
+	} else {
+		m.Cache = DirCache(dir)
+	}
+	return m.Listener()
+}
+
+// Listener listens on the standard TLS port (443) on all interfaces
+// and returns a net.Listener returning *tls.Conn connections.
+//
+// The returned listener uses a *tls.Config that enables HTTP/2, and
+// should only be used with servers that support HTTP/2.
+//
+// The returned Listener also enables TCP keep-alives on the accepted
+// connections. The returned *tls.Conn are returned before their TLS
+// handshake has completed.
+//
+// Unlike NewListener, it is the caller's responsibility to initialize
+// the Manager m's Prompt, Cache, HostPolicy, and other desired options.
+func (m *Manager) Listener() net.Listener {
+	ln := &listener{
+		conf: m.TLSConfig(),
+	}
+	ln.tcpListener, ln.tcpListenErr = net.Listen("tcp", ":443")
+	return ln
+}
+
+type listener struct {
+	conf *tls.Config
+
+	tcpListener  net.Listener
+	tcpListenErr error
+}
+
+func (ln *listener) Accept() (net.Conn, error) {
+	if ln.tcpListenErr != nil {
+		return nil, ln.tcpListenErr
+	}
+	conn, err := ln.tcpListener.Accept()
+	if err != nil {
+		return nil, err
+	}
+	tcpConn := conn.(*net.TCPConn)
+
+	// Because Listener is a convenience function, help out with
+	// this too.  This is not possible for the caller to set once
+	// we return a *tcp.Conn wrapping an inaccessible net.Conn.
+	// If callers don't want this, they can do things the manual
+	// way and tweak as needed. But this is what net/http does
+	// itself, so copy that. If net/http changes, we can change
+	// here too.
+	tcpConn.SetKeepAlive(true)
+	tcpConn.SetKeepAlivePeriod(3 * time.Minute)
+
+	return tls.Server(tcpConn, ln.conf), nil
+}
+
+func (ln *listener) Addr() net.Addr {
+	if ln.tcpListener != nil {
+		return ln.tcpListener.Addr()
+	}
+	// net.Listen failed. Return something non-nil in case callers
+	// call Addr before Accept:
+	return &net.TCPAddr{IP: net.IP{0, 0, 0, 0}, Port: 443}
+}
+
+func (ln *listener) Close() error {
+	if ln.tcpListenErr != nil {
+		return ln.tcpListenErr
+	}
+	return ln.tcpListener.Close()
+}
+
+func homeDir() string {
+	if runtime.GOOS == "windows" {
+		return os.Getenv("HOMEDRIVE") + os.Getenv("HOMEPATH")
+	}
+	if h := os.Getenv("HOME"); h != "" {
+		return h
+	}
+	return "/"
+}
+
+func cacheDir() string {
+	const base = "golang-autocert"
+	switch runtime.GOOS {
+	case "darwin":
+		return filepath.Join(homeDir(), "Library", "Caches", base)
+	case "windows":
+		for _, ev := range []string{"APPDATA", "CSIDL_APPDATA", "TEMP", "TMP"} {
+			if v := os.Getenv(ev); v != "" {
+				return filepath.Join(v, base)
+			}
+		}
+		// Worst case:
+		return filepath.Join(homeDir(), base)
+	}
+	if xdg := os.Getenv("XDG_CACHE_HOME"); xdg != "" {
+		return filepath.Join(xdg, base)
+	}
+	return filepath.Join(homeDir(), ".cache", base)
+}
diff --git a/vendor/golang.org/x/crypto/acme/autocert/renewal.go b/vendor/golang.org/x/crypto/acme/autocert/renewal.go
new file mode 100644
index 0000000000..0df7da78a6
--- /dev/null
+++ b/vendor/golang.org/x/crypto/acme/autocert/renewal.go
@@ -0,0 +1,156 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package autocert
+
+import (
+	"context"
+	"crypto"
+	"sync"
+	"time"
+)
+
+// renewJitter is the maximum deviation from Manager.RenewBefore.
+const renewJitter = time.Hour
+
+// domainRenewal tracks the state used by the periodic timers
+// renewing a single domain's cert.
+type domainRenewal struct {
+	m   *Manager
+	ck  certKey
+	key crypto.Signer
+
+	timerMu    sync.Mutex
+	timer      *time.Timer
+	timerClose chan struct{} // if non-nil, renew closes this channel (and nils out the timer fields) instead of running
+}
+
+// start starts a cert renewal timer at the time
+// defined by the certificate expiration time exp.
+//
+// If the timer is already started, calling start is a noop.
+func (dr *domainRenewal) start(exp time.Time) {
+	dr.timerMu.Lock()
+	defer dr.timerMu.Unlock()
+	if dr.timer != nil {
+		return
+	}
+	dr.timer = time.AfterFunc(dr.next(exp), dr.renew)
+}
+
+// stop stops the cert renewal timer and waits for any in-flight calls to renew
+// to complete. If the timer is already stopped, calling stop is a noop.
+func (dr *domainRenewal) stop() {
+	dr.timerMu.Lock()
+	defer dr.timerMu.Unlock()
+	for {
+		if dr.timer == nil {
+			return
+		}
+		if dr.timer.Stop() {
+			dr.timer = nil
+			return
+		} else {
+			// dr.timer fired, and we acquired dr.timerMu before the renew callback did.
+			// (We know this because otherwise the renew callback would have reset dr.timer!)
+			timerClose := make(chan struct{})
+			dr.timerClose = timerClose
+			dr.timerMu.Unlock()
+			<-timerClose
+			dr.timerMu.Lock()
+		}
+	}
+}
+
+// renew is called periodically by a timer.
+// The first renew call is kicked off by dr.start.
+func (dr *domainRenewal) renew() {
+	dr.timerMu.Lock()
+	defer dr.timerMu.Unlock()
+	if dr.timerClose != nil {
+		close(dr.timerClose)
+		dr.timer, dr.timerClose = nil, nil
+		return
+	}
+
+	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Minute)
+	defer cancel()
+	// TODO: rotate dr.key at some point?
+	next, err := dr.do(ctx)
+	if err != nil {
+		next = renewJitter / 2
+		next += time.Duration(pseudoRand.int63n(int64(next)))
+	}
+	testDidRenewLoop(next, err)
+	dr.timer = time.AfterFunc(next, dr.renew)
+}
+
+// updateState locks and replaces the relevant Manager.state item with the given
+// state. It additionally updates dr.key with the given state's key.
+func (dr *domainRenewal) updateState(state *certState) {
+	dr.m.stateMu.Lock()
+	defer dr.m.stateMu.Unlock()
+	dr.key = state.key
+	dr.m.state[dr.ck] = state
+}
+
+// do is similar to Manager.createCert but it doesn't lock a Manager.state item.
+// Instead, it requests a new certificate independently and, upon success,
+// replaces dr.m.state item with a new one and updates cache for the given domain.
+//
+// It may lock and update the Manager.state if the expiration date of the currently
+// cached cert is far enough in the future.
+//
+// The returned value is a time interval after which the renewal should occur again.
+func (dr *domainRenewal) do(ctx context.Context) (time.Duration, error) {
+	// a race is likely unavoidable in a distributed environment
+	// but we try nonetheless
+	if tlscert, err := dr.m.cacheGet(ctx, dr.ck); err == nil {
+		next := dr.next(tlscert.Leaf.NotAfter)
+		if next > dr.m.renewBefore()+renewJitter {
+			signer, ok := tlscert.PrivateKey.(crypto.Signer)
+			if ok {
+				state := &certState{
+					key:  signer,
+					cert: tlscert.Certificate,
+					leaf: tlscert.Leaf,
+				}
+				dr.updateState(state)
+				return next, nil
+			}
+		}
+	}
+
+	der, leaf, err := dr.m.authorizedCert(ctx, dr.key, dr.ck)
+	if err != nil {
+		return 0, err
+	}
+	state := &certState{
+		key:  dr.key,
+		cert: der,
+		leaf: leaf,
+	}
+	tlscert, err := state.tlscert()
+	if err != nil {
+		return 0, err
+	}
+	if err := dr.m.cachePut(ctx, dr.ck, tlscert); err != nil {
+		return 0, err
+	}
+	dr.updateState(state)
+	return dr.next(leaf.NotAfter), nil
+}
+
+func (dr *domainRenewal) next(expiry time.Time) time.Duration {
+	d := expiry.Sub(dr.m.now()) - dr.m.renewBefore()
+	// add a bit of randomness to renew deadline
+	n := pseudoRand.int63n(int64(renewJitter))
+	d -= time.Duration(n)
+	if d < 0 {
+		return 0
+	}
+	return d
+}
+
+var testDidRenewLoop = func(next time.Duration, err error) {}
diff --git a/vendor/golang.org/x/crypto/acme/http.go b/vendor/golang.org/x/crypto/acme/http.go
new file mode 100644
index 0000000000..2b4c1a10d8
--- /dev/null
+++ b/vendor/golang.org/x/crypto/acme/http.go
@@ -0,0 +1,325 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package acme
+
+import (
+	"bytes"
+	"context"
+	"crypto"
+	"crypto/rand"
+	"encoding/json"
+	"errors"
+	"fmt"
+	"io/ioutil"
+	"math/big"
+	"net/http"
+	"strconv"
+	"strings"
+	"time"
+)
+
+// retryTimer encapsulates common logic for retrying unsuccessful requests.
+// It is not safe for concurrent use.
+type retryTimer struct {
+	// backoffFn provides backoff delay sequence for retries.
+	// See Client.RetryBackoff doc comment.
+	backoffFn func(n int, r *http.Request, res *http.Response) time.Duration
+	// n is the current retry attempt.
+	n int
+}
+
+func (t *retryTimer) inc() {
+	t.n++
+}
+
+// backoff pauses the current goroutine as described in Client.RetryBackoff.
+func (t *retryTimer) backoff(ctx context.Context, r *http.Request, res *http.Response) error {
+	d := t.backoffFn(t.n, r, res)
+	if d <= 0 {
+		return fmt.Errorf("acme: no more retries for %s; tried %d time(s)", r.URL, t.n)
+	}
+	wakeup := time.NewTimer(d)
+	defer wakeup.Stop()
+	select {
+	case <-ctx.Done():
+		return ctx.Err()
+	case <-wakeup.C:
+		return nil
+	}
+}
+
+func (c *Client) retryTimer() *retryTimer {
+	f := c.RetryBackoff
+	if f == nil {
+		f = defaultBackoff
+	}
+	return &retryTimer{backoffFn: f}
+}
+
+// defaultBackoff provides default Client.RetryBackoff implementation
+// using a truncated exponential backoff algorithm,
+// as described in Client.RetryBackoff.
+//
+// The n argument is always bounded between 1 and 30.
+// The returned value is always greater than 0.
+func defaultBackoff(n int, r *http.Request, res *http.Response) time.Duration {
+	const max = 10 * time.Second
+	var jitter time.Duration
+	if x, err := rand.Int(rand.Reader, big.NewInt(1000)); err == nil {
+		// Set the minimum to 1ms to avoid a case where
+		// an invalid Retry-After value is parsed into 0 below,
+		// resulting in the 0 returned value which would unintentionally
+		// stop the retries.
+		jitter = (1 + time.Duration(x.Int64())) * time.Millisecond
+	}
+	if v, ok := res.Header["Retry-After"]; ok {
+		return retryAfter(v[0]) + jitter
+	}
+
+	if n < 1 {
+		n = 1
+	}
+	if n > 30 {
+		n = 30
+	}
+	d := time.Duration(1<<uint(n-1))*time.Second + jitter
+	if d > max {
+		return max
+	}
+	return d
+}
+
+// retryAfter parses a Retry-After HTTP header value,
+// trying to convert v into an int (seconds) or use http.ParseTime otherwise.
+// It returns zero value if v cannot be parsed.
+func retryAfter(v string) time.Duration {
+	if i, err := strconv.Atoi(v); err == nil {
+		return time.Duration(i) * time.Second
+	}
+	t, err := http.ParseTime(v)
+	if err != nil {
+		return 0
+	}
+	return t.Sub(timeNow())
+}
+
+// resOkay is a function that reports whether the provided response is okay.
+// It is expected to keep the response body unread.
+type resOkay func(*http.Response) bool
+
+// wantStatus returns a function which reports whether the code
+// matches the status code of a response.
+func wantStatus(codes ...int) resOkay {
+	return func(res *http.Response) bool {
+		for _, code := range codes {
+			if code == res.StatusCode {
+				return true
+			}
+		}
+		return false
+	}
+}
+
+// get issues an unsigned GET request to the specified URL.
+// It returns a non-error value only when ok reports true.
+//
+// get retries unsuccessful attempts according to c.RetryBackoff
+// until the context is done or a non-retriable error is received.
+func (c *Client) get(ctx context.Context, url string, ok resOkay) (*http.Response, error) {
+	retry := c.retryTimer()
+	for {
+		req, err := http.NewRequest("GET", url, nil)
+		if err != nil {
+			return nil, err
+		}
+		res, err := c.doNoRetry(ctx, req)
+		switch {
+		case err != nil:
+			return nil, err
+		case ok(res):
+			return res, nil
+		case isRetriable(res.StatusCode):
+			retry.inc()
+			resErr := responseError(res)
+			res.Body.Close()
+			// Ignore the error value from retry.backoff
+			// and return the one from last retry, as received from the CA.
+			if retry.backoff(ctx, req, res) != nil {
+				return nil, resErr
+			}
+		default:
+			defer res.Body.Close()
+			return nil, responseError(res)
+		}
+	}
+}
+
+// postAsGet is POST-as-GET, a replacement for GET in RFC8555
+// as described in https://tools.ietf.org/html/rfc8555#section-6.3.
+// It makes a POST request in KID form with zero JWS payload.
+// See nopayload doc comments in jws.go.
+func (c *Client) postAsGet(ctx context.Context, url string, ok resOkay) (*http.Response, error) {
+	return c.post(ctx, nil, url, noPayload, ok)
+}
+
+// post issues a signed POST request in JWS format using the provided key
+// to the specified URL. If key is nil, c.Key is used instead.
+// It returns a non-error value only when ok reports true.
+//
+// post retries unsuccessful attempts according to c.RetryBackoff
+// until the context is done or a non-retriable error is received.
+// It uses postNoRetry to make individual requests.
+func (c *Client) post(ctx context.Context, key crypto.Signer, url string, body interface{}, ok resOkay) (*http.Response, error) {
+	retry := c.retryTimer()
+	for {
+		res, req, err := c.postNoRetry(ctx, key, url, body)
+		if err != nil {
+			return nil, err
+		}
+		if ok(res) {
+			return res, nil
+		}
+		resErr := responseError(res)
+		res.Body.Close()
+		switch {
+		// Check for bad nonce before isRetriable because it may have been returned
+		// with an unretriable response code such as 400 Bad Request.
+		case isBadNonce(resErr):
+			// Consider any previously stored nonce values to be invalid.
+			c.clearNonces()
+		case !isRetriable(res.StatusCode):
+			return nil, resErr
+		}
+		retry.inc()
+		// Ignore the error value from retry.backoff
+		// and return the one from last retry, as received from the CA.
+		if err := retry.backoff(ctx, req, res); err != nil {
+			return nil, resErr
+		}
+	}
+}
+
+// postNoRetry signs the body with the given key and POSTs it to the provided url.
+// It is used by c.post to retry unsuccessful attempts.
+// The body argument must be JSON-serializable.
+//
+// If key argument is nil, c.Key is used to sign the request.
+// If key argument is nil and c.accountKID returns a non-zero keyID,
+// the request is sent in KID form. Otherwise, JWK form is used.
+//
+// In practice, when interfacing with RFC-compliant CAs most requests are sent in KID form
+// and JWK is used only when KID is unavailable: new account endpoint and certificate
+// revocation requests authenticated by a cert key.
+// See jwsEncodeJSON for other details.
+func (c *Client) postNoRetry(ctx context.Context, key crypto.Signer, url string, body interface{}) (*http.Response, *http.Request, error) {
+	kid := noKeyID
+	if key == nil {
+		if c.Key == nil {
+			return nil, nil, errors.New("acme: Client.Key must be populated to make POST requests")
+		}
+		key = c.Key
+		kid = c.accountKID(ctx)
+	}
+	nonce, err := c.popNonce(ctx, url)
+	if err != nil {
+		return nil, nil, err
+	}
+	b, err := jwsEncodeJSON(body, key, kid, nonce, url)
+	if err != nil {
+		return nil, nil, err
+	}
+	req, err := http.NewRequest("POST", url, bytes.NewReader(b))
+	if err != nil {
+		return nil, nil, err
+	}
+	req.Header.Set("Content-Type", "application/jose+json")
+	res, err := c.doNoRetry(ctx, req)
+	if err != nil {
+		return nil, nil, err
+	}
+	c.addNonce(res.Header)
+	return res, req, nil
+}
+
+// doNoRetry issues a request req, replacing its context (if any) with ctx.
+func (c *Client) doNoRetry(ctx context.Context, req *http.Request) (*http.Response, error) {
+	req.Header.Set("User-Agent", c.userAgent())
+	res, err := c.httpClient().Do(req.WithContext(ctx))
+	if err != nil {
+		select {
+		case <-ctx.Done():
+			// Prefer the unadorned context error.
+			// (The acme package had tests assuming this, previously from ctxhttp's
+			// behavior, predating net/http supporting contexts natively)
+			// TODO(bradfitz): reconsider this in the future. But for now this
+			// requires no test updates.
+			return nil, ctx.Err()
+		default:
+			return nil, err
+		}
+	}
+	return res, nil
+}
+
+func (c *Client) httpClient() *http.Client {
+	if c.HTTPClient != nil {
+		return c.HTTPClient
+	}
+	return http.DefaultClient
+}
+
+// packageVersion is the version of the module that contains this package, for
+// sending as part of the User-Agent header. It's set in version_go112.go.
+var packageVersion string
+
+// userAgent returns the User-Agent header value. It includes the package name,
+// the module version (if available), and the c.UserAgent value (if set).
+func (c *Client) userAgent() string {
+	ua := "golang.org/x/crypto/acme"
+	if packageVersion != "" {
+		ua += "@" + packageVersion
+	}
+	if c.UserAgent != "" {
+		ua = c.UserAgent + " " + ua
+	}
+	return ua
+}
+
+// isBadNonce reports whether err is an ACME "badnonce" error.
+func isBadNonce(err error) bool {
+	// According to the spec badNonce is urn:ietf:params:acme:error:badNonce.
+	// However, ACME servers in the wild return their versions of the error.
+	// See https://tools.ietf.org/html/draft-ietf-acme-acme-02#section-5.4
+	// and https://github.com/letsencrypt/boulder/blob/0e07eacb/docs/acme-divergences.md#section-66.
+	ae, ok := err.(*Error)
+	return ok && strings.HasSuffix(strings.ToLower(ae.ProblemType), ":badnonce")
+}
+
+// isRetriable reports whether a request can be retried
+// based on the response status code.
+//
+// Note that a "bad nonce" error is returned with a non-retriable 400 Bad Request code.
+// Callers should parse the response and check with isBadNonce.
+func isRetriable(code int) bool {
+	return code <= 399 || code >= 500 || code == http.StatusTooManyRequests
+}
+
+// responseError creates an error of Error type from resp.
+func responseError(resp *http.Response) error {
+	// don't care if ReadAll returns an error:
+	// json.Unmarshal will fail in that case anyway
+	b, _ := ioutil.ReadAll(resp.Body)
+	e := &wireError{Status: resp.StatusCode}
+	if err := json.Unmarshal(b, e); err != nil {
+		// this is not a regular error response:
+		// populate detail with anything we received,
+		// e.Status will already contain HTTP response code value
+		e.Detail = string(b)
+		if e.Detail == "" {
+			e.Detail = resp.Status
+		}
+	}
+	return e.error(resp.Header)
+}
diff --git a/vendor/golang.org/x/crypto/acme/internal/acmeprobe/prober.go b/vendor/golang.org/x/crypto/acme/internal/acmeprobe/prober.go
new file mode 100644
index 0000000000..471707de02
--- /dev/null
+++ b/vendor/golang.org/x/crypto/acme/internal/acmeprobe/prober.go
@@ -0,0 +1,433 @@
+// Copyright 2019 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.
+
+// The acmeprober program runs against an actual ACME CA implementation.
+// It spins up an HTTP server to fulfill authorization challenges
+// or execute a DNS script to provision a response to dns-01 challenge.
+//
+// For http-01 and tls-alpn-01 challenge types this requires the ACME CA
+// to be able to reach the HTTP server.
+//
+// A usage example:
+//
+//     go run prober.go \
+//       -d https://acme-staging-v02.api.letsencrypt.org/directory \
+//       -f order \
+//       -t http-01 \
+//       -a :8080 \
+//       -domain some.example.org
+//
+// The above assumes a TCP tunnel from some.example.org:80 to 0.0.0.0:8080
+// in order for the test to be able to fulfill http-01 challenge.
+// To test tls-alpn-01 challenge, 443 port would need to be tunneled
+// to 0.0.0.0:8080.
+// When running with dns-01 challenge type, use -s argument instead of -a.
+package main
+
+import (
+	"context"
+	"crypto"
+	"crypto/ecdsa"
+	"crypto/elliptic"
+	"crypto/rand"
+	"crypto/tls"
+	"crypto/x509"
+	"encoding/pem"
+	"errors"
+	"flag"
+	"fmt"
+	"log"
+	"net"
+	"net/http"
+	"os"
+	"os/exec"
+	"strings"
+	"time"
+
+	"golang.org/x/crypto/acme"
+)
+
+var (
+	// ACME CA directory URL.
+	// Let's Encrypt v2 prod: https://acme-v02.api.letsencrypt.org/directory
+	// Let's Encrypt v2 staging: https://acme-staging-v02.api.letsencrypt.org/directory
+	// See the following for more CAs implementing ACME protocol:
+	// https://en.wikipedia.org/wiki/Automated_Certificate_Management_Environment#CAs_&_PKIs_that_offer_ACME_certificates
+	directory = flag.String("d", "", "ACME directory URL.")
+	reginfo   = flag.String("r", "", "ACME account registration info.")
+	flow      = flag.String("f", "", `Flow to run: "order" or "preauthz" (RFC8555).`)
+	chaltyp   = flag.String("t", "", "Challenge type: tls-alpn-01, http-01 or dns-01.")
+	addr      = flag.String("a", "", "Local server address for tls-alpn-01 and http-01.")
+	dnsscript = flag.String("s", "", "Script to run for provisioning dns-01 challenges.")
+	domain    = flag.String("domain", "", "Space separate domain identifiers.")
+	ipaddr    = flag.String("ip", "", "Space separate IP address identifiers.")
+)
+
+func main() {
+	flag.Usage = func() {
+		fmt.Fprintln(flag.CommandLine.Output(), `
+The prober program runs against an actual ACME CA implementation.
+It spins up an HTTP server to fulfill authorization challenges
+or execute a DNS script to provision a response to dns-01 challenge.
+
+For http-01 and tls-alpn-01 challenge types this requires the ACME CA
+to be able to reach the HTTP server.
+
+A usage example:
+
+    go run prober.go \
+      -d https://acme-staging-v02.api.letsencrypt.org/directory \
+      -f order \
+      -t http-01 \
+      -a :8080 \
+      -domain some.example.org
+
+The above assumes a TCP tunnel from some.example.org:80 to 0.0.0.0:8080
+in order for the test to be able to fulfill http-01 challenge.
+To test tls-alpn-01 challenge, 443 port would need to be tunneled
+to 0.0.0.0:8080.
+When running with dns-01 challenge type, use -s argument instead of -a.
+		`)
+		flag.PrintDefaults()
+	}
+	flag.Parse()
+
+	identifiers := acme.DomainIDs(strings.Fields(*domain)...)
+	identifiers = append(identifiers, acme.IPIDs(strings.Fields(*ipaddr)...)...)
+	if len(identifiers) == 0 {
+		log.Fatal("at least one domain or IP addr identifier is required")
+	}
+
+	// Duration of the whole run.
+	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Minute)
+	defer cancel()
+
+	// Create and register a new account.
+	akey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
+	if err != nil {
+		log.Fatal(err)
+	}
+	cl := &acme.Client{Key: akey, DirectoryURL: *directory}
+	a := &acme.Account{Contact: strings.Fields(*reginfo)}
+	if _, err := cl.Register(ctx, a, acme.AcceptTOS); err != nil {
+		log.Fatalf("Register: %v", err)
+	}
+
+	// Run the desired flow test.
+	p := &prober{
+		client:    cl,
+		chalType:  *chaltyp,
+		localAddr: *addr,
+		dnsScript: *dnsscript,
+	}
+	switch *flow {
+	case "order":
+		p.runOrder(ctx, identifiers)
+	case "preauthz":
+		p.runPreauthz(ctx, identifiers)
+	default:
+		log.Fatalf("unknown flow: %q", *flow)
+	}
+	if len(p.errors) > 0 {
+		os.Exit(1)
+	}
+}
+
+type prober struct {
+	client    *acme.Client
+	chalType  string
+	localAddr string
+	dnsScript string
+
+	errors []error
+}
+
+func (p *prober) errorf(format string, a ...interface{}) {
+	err := fmt.Errorf(format, a...)
+	log.Print(err)
+	p.errors = append(p.errors, err)
+}
+
+func (p *prober) runOrder(ctx context.Context, identifiers []acme.AuthzID) {
+	// Create a new order and pick a challenge.
+	// Note that Let's Encrypt will reply with 400 error:malformed
+	// "NotBefore and NotAfter are not supported" when providing a NotAfter
+	// value like WithOrderNotAfter(time.Now().Add(24 * time.Hour)).
+	o, err := p.client.AuthorizeOrder(ctx, identifiers)
+	if err != nil {
+		log.Fatalf("AuthorizeOrder: %v", err)
+	}
+
+	var zurls []string
+	for _, u := range o.AuthzURLs {
+		z, err := p.client.GetAuthorization(ctx, u)
+		if err != nil {
+			log.Fatalf("GetAuthorization(%q): %v", u, err)
+		}
+		log.Printf("%+v", z)
+		if z.Status != acme.StatusPending {
+			log.Printf("authz status is %q; skipping", z.Status)
+			continue
+		}
+		if err := p.fulfill(ctx, z); err != nil {
+			log.Fatalf("fulfill(%s): %v", z.URI, err)
+		}
+		zurls = append(zurls, z.URI)
+		log.Printf("authorized for %+v", z.Identifier)
+	}
+
+	log.Print("all challenges are done")
+	if _, err := p.client.WaitOrder(ctx, o.URI); err != nil {
+		log.Fatalf("WaitOrder(%q): %v", o.URI, err)
+	}
+	csr, certkey := newCSR(identifiers)
+	der, curl, err := p.client.CreateOrderCert(ctx, o.FinalizeURL, csr, true)
+	if err != nil {
+		log.Fatalf("CreateOrderCert: %v", err)
+	}
+	log.Printf("cert URL: %s", curl)
+	if err := checkCert(der, identifiers); err != nil {
+		p.errorf("invalid cert: %v", err)
+	}
+
+	// Deactivate all authorizations we satisfied earlier.
+	for _, v := range zurls {
+		if err := p.client.RevokeAuthorization(ctx, v); err != nil {
+			p.errorf("RevokAuthorization(%q): %v", v, err)
+			continue
+		}
+	}
+	// Deactivate the account. We don't need it for any further calls.
+	if err := p.client.DeactivateReg(ctx); err != nil {
+		p.errorf("DeactivateReg: %v", err)
+	}
+	// Try revoking the issued cert using its private key.
+	if err := p.client.RevokeCert(ctx, certkey, der[0], acme.CRLReasonCessationOfOperation); err != nil {
+		p.errorf("RevokeCert: %v", err)
+	}
+}
+
+func (p *prober) runPreauthz(ctx context.Context, identifiers []acme.AuthzID) {
+	dir, err := p.client.Discover(ctx)
+	if err != nil {
+		log.Fatalf("Discover: %v", err)
+	}
+	if dir.AuthzURL == "" {
+		log.Fatal("CA does not support pre-authorization")
+	}
+
+	var zurls []string
+	for _, id := range identifiers {
+		z, err := authorize(ctx, p.client, id)
+		if err != nil {
+			log.Fatalf("AuthorizeID(%+v): %v", z, err)
+		}
+		if z.Status == acme.StatusValid {
+			log.Printf("authz %s is valid; skipping", z.URI)
+			continue
+		}
+		if err := p.fulfill(ctx, z); err != nil {
+			log.Fatalf("fulfill(%s): %v", z.URI, err)
+		}
+		zurls = append(zurls, z.URI)
+		log.Printf("authorized for %+v", id)
+	}
+
+	// We should be all set now.
+	// Expect all authorizations to be satisfied.
+	log.Print("all challenges are done")
+	o, err := p.client.AuthorizeOrder(ctx, identifiers)
+	if err != nil {
+		log.Fatalf("AuthorizeOrder: %v", err)
+	}
+	waitCtx, cancel := context.WithTimeout(ctx, time.Minute)
+	defer cancel()
+	if _, err := p.client.WaitOrder(waitCtx, o.URI); err != nil {
+		log.Fatalf("WaitOrder(%q): %v", o.URI, err)
+	}
+	csr, certkey := newCSR(identifiers)
+	der, curl, err := p.client.CreateOrderCert(ctx, o.FinalizeURL, csr, true)
+	if err != nil {
+		log.Fatalf("CreateOrderCert: %v", err)
+	}
+	log.Printf("cert URL: %s", curl)
+	if err := checkCert(der, identifiers); err != nil {
+		p.errorf("invalid cert: %v", err)
+	}
+
+	// Deactivate all authorizations we satisfied earlier.
+	for _, v := range zurls {
+		if err := p.client.RevokeAuthorization(ctx, v); err != nil {
+			p.errorf("RevokeAuthorization(%q): %v", v, err)
+			continue
+		}
+	}
+	// Deactivate the account. We don't need it for any further calls.
+	if err := p.client.DeactivateReg(ctx); err != nil {
+		p.errorf("DeactivateReg: %v", err)
+	}
+	// Try revoking the issued cert using its private key.
+	if err := p.client.RevokeCert(ctx, certkey, der[0], acme.CRLReasonCessationOfOperation); err != nil {
+		p.errorf("RevokeCert: %v", err)
+	}
+}
+
+func (p *prober) fulfill(ctx context.Context, z *acme.Authorization) error {
+	var chal *acme.Challenge
+	for i, c := range z.Challenges {
+		log.Printf("challenge %d: %+v", i, c)
+		if c.Type == p.chalType {
+			log.Printf("picked %s for authz %s", c.URI, z.URI)
+			chal = c
+		}
+	}
+	if chal == nil {
+		return fmt.Errorf("challenge type %q wasn't offered for authz %s", p.chalType, z.URI)
+	}
+
+	switch chal.Type {
+	case "tls-alpn-01":
+		return p.runTLSALPN01(ctx, z, chal)
+	case "http-01":
+		return p.runHTTP01(ctx, z, chal)
+	case "dns-01":
+		return p.runDNS01(ctx, z, chal)
+	default:
+		return fmt.Errorf("unknown challenge type %q", chal.Type)
+	}
+}
+
+func (p *prober) runTLSALPN01(ctx context.Context, z *acme.Authorization, chal *acme.Challenge) error {
+	tokenCert, err := p.client.TLSALPN01ChallengeCert(chal.Token, z.Identifier.Value)
+	if err != nil {
+		return fmt.Errorf("TLSALPN01ChallengeCert: %v", err)
+	}
+	s := &http.Server{
+		Addr: p.localAddr,
+		TLSConfig: &tls.Config{
+			NextProtos: []string{acme.ALPNProto},
+			GetCertificate: func(hello *tls.ClientHelloInfo) (*tls.Certificate, error) {
+				log.Printf("hello: %+v", hello)
+				return &tokenCert, nil
+			},
+		},
+		Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+			log.Printf("%s %s", r.Method, r.URL)
+			w.WriteHeader(http.StatusNotFound)
+		}),
+	}
+	go s.ListenAndServeTLS("", "")
+	defer s.Close()
+
+	if _, err := p.client.Accept(ctx, chal); err != nil {
+		return fmt.Errorf("Accept(%q): %v", chal.URI, err)
+	}
+	_, zerr := p.client.WaitAuthorization(ctx, z.URI)
+	return zerr
+}
+
+func (p *prober) runHTTP01(ctx context.Context, z *acme.Authorization, chal *acme.Challenge) error {
+	body, err := p.client.HTTP01ChallengeResponse(chal.Token)
+	if err != nil {
+		return fmt.Errorf("HTTP01ChallengeResponse: %v", err)
+	}
+	s := &http.Server{
+		Addr: p.localAddr,
+		Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+			log.Printf("%s %s", r.Method, r.URL)
+			if r.URL.Path != p.client.HTTP01ChallengePath(chal.Token) {
+				w.WriteHeader(http.StatusNotFound)
+				return
+			}
+			w.Write([]byte(body))
+		}),
+	}
+	go s.ListenAndServe()
+	defer s.Close()
+
+	if _, err := p.client.Accept(ctx, chal); err != nil {
+		return fmt.Errorf("Accept(%q): %v", chal.URI, err)
+	}
+	_, zerr := p.client.WaitAuthorization(ctx, z.URI)
+	return zerr
+}
+
+func (p *prober) runDNS01(ctx context.Context, z *acme.Authorization, chal *acme.Challenge) error {
+	token, err := p.client.DNS01ChallengeRecord(chal.Token)
+	if err != nil {
+		return fmt.Errorf("DNS01ChallengeRecord: %v", err)
+	}
+
+	name := fmt.Sprintf("_acme-challenge.%s", z.Identifier.Value)
+	cmd := exec.CommandContext(ctx, p.dnsScript, name, token)
+	cmd.Stdin = os.Stdin
+	cmd.Stdout = os.Stdout
+	cmd.Stderr = os.Stderr
+	if err := cmd.Run(); err != nil {
+		return fmt.Errorf("%s: %v", p.dnsScript, err)
+	}
+
+	if _, err := p.client.Accept(ctx, chal); err != nil {
+		return fmt.Errorf("Accept(%q): %v", chal.URI, err)
+	}
+	_, zerr := p.client.WaitAuthorization(ctx, z.URI)
+	return zerr
+}
+
+func authorize(ctx context.Context, client *acme.Client, id acme.AuthzID) (*acme.Authorization, error) {
+	if id.Type == "ip" {
+		return client.AuthorizeIP(ctx, id.Value)
+	}
+	return client.Authorize(ctx, id.Value)
+}
+
+func checkCert(derChain [][]byte, id []acme.AuthzID) error {
+	if len(derChain) == 0 {
+		return errors.New("cert chain is zero bytes")
+	}
+	for i, b := range derChain {
+		crt, err := x509.ParseCertificate(b)
+		if err != nil {
+			return fmt.Errorf("%d: ParseCertificate: %v", i, err)
+		}
+		log.Printf("%d: serial: 0x%s", i, crt.SerialNumber)
+		log.Printf("%d: subject: %s", i, crt.Subject)
+		log.Printf("%d: issuer: %s", i, crt.Issuer)
+		log.Printf("%d: expires in %.1f day(s)", i, time.Until(crt.NotAfter).Hours()/24)
+		if i > 0 { // not a leaf cert
+			continue
+		}
+		p := &pem.Block{Type: "CERTIFICATE", Bytes: b}
+		log.Printf("%d: leaf:\n%s", i, pem.EncodeToMemory(p))
+		for _, v := range id {
+			if err := crt.VerifyHostname(v.Value); err != nil {
+				return err
+			}
+		}
+	}
+	return nil
+}
+
+func newCSR(identifiers []acme.AuthzID) ([]byte, crypto.Signer) {
+	var csr x509.CertificateRequest
+	for _, id := range identifiers {
+		switch id.Type {
+		case "dns":
+			csr.DNSNames = append(csr.DNSNames, id.Value)
+		case "ip":
+			csr.IPAddresses = append(csr.IPAddresses, net.ParseIP(id.Value))
+		default:
+			panic(fmt.Sprintf("newCSR: unknown identifier type %q", id.Type))
+		}
+	}
+	k, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
+	if err != nil {
+		panic(fmt.Sprintf("newCSR: ecdsa.GenerateKey for a cert: %v", err))
+	}
+	b, err := x509.CreateCertificateRequest(rand.Reader, &csr, k)
+	if err != nil {
+		panic(fmt.Sprintf("newCSR: x509.CreateCertificateRequest: %v", err))
+	}
+	return b, k
+}
diff --git a/vendor/golang.org/x/crypto/acme/jws.go b/vendor/golang.org/x/crypto/acme/jws.go
new file mode 100644
index 0000000000..403e5b0c23
--- /dev/null
+++ b/vendor/golang.org/x/crypto/acme/jws.go
@@ -0,0 +1,232 @@
+// Copyright 2015 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 acme
+
+import (
+	"crypto"
+	"crypto/ecdsa"
+	"crypto/hmac"
+	"crypto/rand"
+	"crypto/rsa"
+	"crypto/sha256"
+	_ "crypto/sha512" // need for EC keys
+	"encoding/asn1"
+	"encoding/base64"
+	"encoding/json"
+	"errors"
+	"fmt"
+	"math/big"
+)
+
+// KeyID is the account key identity provided by a CA during registration.
+type KeyID string
+
+// noKeyID indicates that jwsEncodeJSON should compute and use JWK instead of a KID.
+// See jwsEncodeJSON for details.
+const noKeyID = KeyID("")
+
+// noPayload indicates jwsEncodeJSON will encode zero-length octet string
+// in a JWS request. This is called POST-as-GET in RFC 8555 and is used to make
+// authenticated GET requests via POSTing with an empty payload.
+// See https://tools.ietf.org/html/rfc8555#section-6.3 for more details.
+const noPayload = ""
+
+// jsonWebSignature can be easily serialized into a JWS following
+// https://tools.ietf.org/html/rfc7515#section-3.2.
+type jsonWebSignature struct {
+	Protected string `json:"protected"`
+	Payload   string `json:"payload"`
+	Sig       string `json:"signature"`
+}
+
+// jwsEncodeJSON signs claimset using provided key and a nonce.
+// The result is serialized in JSON format containing either kid or jwk
+// fields based on the provided KeyID value.
+//
+// If kid is non-empty, its quoted value is inserted in the protected head
+// as "kid" field value. Otherwise, JWK is computed using jwkEncode and inserted
+// as "jwk" field value. The "jwk" and "kid" fields are mutually exclusive.
+//
+// See https://tools.ietf.org/html/rfc7515#section-7.
+func jwsEncodeJSON(claimset interface{}, key crypto.Signer, kid KeyID, nonce, url string) ([]byte, error) {
+	if key == nil {
+		return nil, errors.New("nil key")
+	}
+	alg, sha := jwsHasher(key.Public())
+	if alg == "" || !sha.Available() {
+		return nil, ErrUnsupportedKey
+	}
+	var phead string
+	switch kid {
+	case noKeyID:
+		jwk, err := jwkEncode(key.Public())
+		if err != nil {
+			return nil, err
+		}
+		phead = fmt.Sprintf(`{"alg":%q,"jwk":%s,"nonce":%q,"url":%q}`, alg, jwk, nonce, url)
+	default:
+		phead = fmt.Sprintf(`{"alg":%q,"kid":%q,"nonce":%q,"url":%q}`, alg, kid, nonce, url)
+	}
+	phead = base64.RawURLEncoding.EncodeToString([]byte(phead))
+	var payload string
+	if claimset != noPayload {
+		cs, err := json.Marshal(claimset)
+		if err != nil {
+			return nil, err
+		}
+		payload = base64.RawURLEncoding.EncodeToString(cs)
+	}
+	hash := sha.New()
+	hash.Write([]byte(phead + "." + payload))
+	sig, err := jwsSign(key, sha, hash.Sum(nil))
+	if err != nil {
+		return nil, err
+	}
+	enc := jsonWebSignature{
+		Protected: phead,
+		Payload:   payload,
+		Sig:       base64.RawURLEncoding.EncodeToString(sig),
+	}
+	return json.Marshal(&enc)
+}
+
+// jwsWithMAC creates and signs a JWS using the given key and the HS256
+// algorithm. kid and url are included in the protected header. rawPayload
+// should not be base64-URL-encoded.
+func jwsWithMAC(key []byte, kid, url string, rawPayload []byte) (*jsonWebSignature, error) {
+	if len(key) == 0 {
+		return nil, errors.New("acme: cannot sign JWS with an empty MAC key")
+	}
+	header := struct {
+		Algorithm string `json:"alg"`
+		KID       string `json:"kid"`
+		URL       string `json:"url,omitempty"`
+	}{
+		// Only HMAC-SHA256 is supported.
+		Algorithm: "HS256",
+		KID:       kid,
+		URL:       url,
+	}
+	rawProtected, err := json.Marshal(header)
+	if err != nil {
+		return nil, err
+	}
+	protected := base64.RawURLEncoding.EncodeToString(rawProtected)
+	payload := base64.RawURLEncoding.EncodeToString(rawPayload)
+
+	h := hmac.New(sha256.New, key)
+	if _, err := h.Write([]byte(protected + "." + payload)); err != nil {
+		return nil, err
+	}
+	mac := h.Sum(nil)
+
+	return &jsonWebSignature{
+		Protected: protected,
+		Payload:   payload,
+		Sig:       base64.RawURLEncoding.EncodeToString(mac),
+	}, nil
+}
+
+// jwkEncode encodes public part of an RSA or ECDSA key into a JWK.
+// The result is also suitable for creating a JWK thumbprint.
+// https://tools.ietf.org/html/rfc7517
+func jwkEncode(pub crypto.PublicKey) (string, error) {
+	switch pub := pub.(type) {
+	case *rsa.PublicKey:
+		// https://tools.ietf.org/html/rfc7518#section-6.3.1
+		n := pub.N
+		e := big.NewInt(int64(pub.E))
+		// Field order is important.
+		// See https://tools.ietf.org/html/rfc7638#section-3.3 for details.
+		return fmt.Sprintf(`{"e":"%s","kty":"RSA","n":"%s"}`,
+			base64.RawURLEncoding.EncodeToString(e.Bytes()),
+			base64.RawURLEncoding.EncodeToString(n.Bytes()),
+		), nil
+	case *ecdsa.PublicKey:
+		// https://tools.ietf.org/html/rfc7518#section-6.2.1
+		p := pub.Curve.Params()
+		n := p.BitSize / 8
+		if p.BitSize%8 != 0 {
+			n++
+		}
+		x := pub.X.Bytes()
+		if n > len(x) {
+			x = append(make([]byte, n-len(x)), x...)
+		}
+		y := pub.Y.Bytes()
+		if n > len(y) {
+			y = append(make([]byte, n-len(y)), y...)
+		}
+		// Field order is important.
+		// See https://tools.ietf.org/html/rfc7638#section-3.3 for details.
+		return fmt.Sprintf(`{"crv":"%s","kty":"EC","x":"%s","y":"%s"}`,
+			p.Name,
+			base64.RawURLEncoding.EncodeToString(x),
+			base64.RawURLEncoding.EncodeToString(y),
+		), nil
+	}
+	return "", ErrUnsupportedKey
+}
+
+// jwsSign signs the digest using the given key.
+// The hash is unused for ECDSA keys.
+func jwsSign(key crypto.Signer, hash crypto.Hash, digest []byte) ([]byte, error) {
+	switch pub := key.Public().(type) {
+	case *rsa.PublicKey:
+		return key.Sign(rand.Reader, digest, hash)
+	case *ecdsa.PublicKey:
+		sigASN1, err := key.Sign(rand.Reader, digest, hash)
+		if err != nil {
+			return nil, err
+		}
+
+		var rs struct{ R, S *big.Int }
+		if _, err := asn1.Unmarshal(sigASN1, &rs); err != nil {
+			return nil, err
+		}
+
+		rb, sb := rs.R.Bytes(), rs.S.Bytes()
+		size := pub.Params().BitSize / 8
+		if size%8 > 0 {
+			size++
+		}
+		sig := make([]byte, size*2)
+		copy(sig[size-len(rb):], rb)
+		copy(sig[size*2-len(sb):], sb)
+		return sig, nil
+	}
+	return nil, ErrUnsupportedKey
+}
+
+// jwsHasher indicates suitable JWS algorithm name and a hash function
+// to use for signing a digest with the provided key.
+// It returns ("", 0) if the key is not supported.
+func jwsHasher(pub crypto.PublicKey) (string, crypto.Hash) {
+	switch pub := pub.(type) {
+	case *rsa.PublicKey:
+		return "RS256", crypto.SHA256
+	case *ecdsa.PublicKey:
+		switch pub.Params().Name {
+		case "P-256":
+			return "ES256", crypto.SHA256
+		case "P-384":
+			return "ES384", crypto.SHA384
+		case "P-521":
+			return "ES512", crypto.SHA512
+		}
+	}
+	return "", 0
+}
+
+// JWKThumbprint creates a JWK thumbprint out of pub
+// as specified in https://tools.ietf.org/html/rfc7638.
+func JWKThumbprint(pub crypto.PublicKey) (string, error) {
+	jwk, err := jwkEncode(pub)
+	if err != nil {
+		return "", err
+	}
+	b := sha256.Sum256([]byte(jwk))
+	return base64.RawURLEncoding.EncodeToString(b[:]), nil
+}
diff --git a/vendor/golang.org/x/crypto/acme/rfc8555.go b/vendor/golang.org/x/crypto/acme/rfc8555.go
new file mode 100644
index 0000000000..928a5aa036
--- /dev/null
+++ b/vendor/golang.org/x/crypto/acme/rfc8555.go
@@ -0,0 +1,438 @@
+// Copyright 2019 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 acme
+
+import (
+	"context"
+	"crypto"
+	"encoding/base64"
+	"encoding/json"
+	"encoding/pem"
+	"errors"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"net/http"
+	"time"
+)
+
+// DeactivateReg permanently disables an existing account associated with c.Key.
+// A deactivated account can no longer request certificate issuance or access
+// resources related to the account, such as orders or authorizations.
+//
+// It only works with CAs implementing RFC 8555.
+func (c *Client) DeactivateReg(ctx context.Context) error {
+	url := string(c.accountKID(ctx))
+	if url == "" {
+		return ErrNoAccount
+	}
+	req := json.RawMessage(`{"status": "deactivated"}`)
+	res, err := c.post(ctx, nil, url, req, wantStatus(http.StatusOK))
+	if err != nil {
+		return err
+	}
+	res.Body.Close()
+	return nil
+}
+
+// registerRFC is equivalent to c.Register but for CAs implementing RFC 8555.
+// It expects c.Discover to have already been called.
+func (c *Client) registerRFC(ctx context.Context, acct *Account, prompt func(tosURL string) bool) (*Account, error) {
+	c.cacheMu.Lock() // guard c.kid access
+	defer c.cacheMu.Unlock()
+
+	req := struct {
+		TermsAgreed            bool              `json:"termsOfServiceAgreed,omitempty"`
+		Contact                []string          `json:"contact,omitempty"`
+		ExternalAccountBinding *jsonWebSignature `json:"externalAccountBinding,omitempty"`
+	}{
+		Contact: acct.Contact,
+	}
+	if c.dir.Terms != "" {
+		req.TermsAgreed = prompt(c.dir.Terms)
+	}
+
+	// set 'externalAccountBinding' field if requested
+	if acct.ExternalAccountBinding != nil {
+		eabJWS, err := c.encodeExternalAccountBinding(acct.ExternalAccountBinding)
+		if err != nil {
+			return nil, fmt.Errorf("acme: failed to encode external account binding: %v", err)
+		}
+		req.ExternalAccountBinding = eabJWS
+	}
+
+	res, err := c.post(ctx, c.Key, c.dir.RegURL, req, wantStatus(
+		http.StatusOK,      // account with this key already registered
+		http.StatusCreated, // new account created
+	))
+	if err != nil {
+		return nil, err
+	}
+
+	defer res.Body.Close()
+	a, err := responseAccount(res)
+	if err != nil {
+		return nil, err
+	}
+	// Cache Account URL even if we return an error to the caller.
+	// It is by all means a valid and usable "kid" value for future requests.
+	c.KID = KeyID(a.URI)
+	if res.StatusCode == http.StatusOK {
+		return nil, ErrAccountAlreadyExists
+	}
+	return a, nil
+}
+
+// encodeExternalAccountBinding will encode an external account binding stanza
+// as described in https://tools.ietf.org/html/rfc8555#section-7.3.4.
+func (c *Client) encodeExternalAccountBinding(eab *ExternalAccountBinding) (*jsonWebSignature, error) {
+	jwk, err := jwkEncode(c.Key.Public())
+	if err != nil {
+		return nil, err
+	}
+	return jwsWithMAC(eab.Key, eab.KID, c.dir.RegURL, []byte(jwk))
+}
+
+// updateRegRFC is equivalent to c.UpdateReg but for CAs implementing RFC 8555.
+// It expects c.Discover to have already been called.
+func (c *Client) updateRegRFC(ctx context.Context, a *Account) (*Account, error) {
+	url := string(c.accountKID(ctx))
+	if url == "" {
+		return nil, ErrNoAccount
+	}
+	req := struct {
+		Contact []string `json:"contact,omitempty"`
+	}{
+		Contact: a.Contact,
+	}
+	res, err := c.post(ctx, nil, url, req, wantStatus(http.StatusOK))
+	if err != nil {
+		return nil, err
+	}
+	defer res.Body.Close()
+	return responseAccount(res)
+}
+
+// getGegRFC is equivalent to c.GetReg but for CAs implementing RFC 8555.
+// It expects c.Discover to have already been called.
+func (c *Client) getRegRFC(ctx context.Context) (*Account, error) {
+	req := json.RawMessage(`{"onlyReturnExisting": true}`)
+	res, err := c.post(ctx, c.Key, c.dir.RegURL, req, wantStatus(http.StatusOK))
+	if e, ok := err.(*Error); ok && e.ProblemType == "urn:ietf:params:acme:error:accountDoesNotExist" {
+		return nil, ErrNoAccount
+	}
+	if err != nil {
+		return nil, err
+	}
+
+	defer res.Body.Close()
+	return responseAccount(res)
+}
+
+func responseAccount(res *http.Response) (*Account, error) {
+	var v struct {
+		Status  string
+		Contact []string
+		Orders  string
+	}
+	if err := json.NewDecoder(res.Body).Decode(&v); err != nil {
+		return nil, fmt.Errorf("acme: invalid account response: %v", err)
+	}
+	return &Account{
+		URI:       res.Header.Get("Location"),
+		Status:    v.Status,
+		Contact:   v.Contact,
+		OrdersURL: v.Orders,
+	}, nil
+}
+
+// AuthorizeOrder initiates the order-based application for certificate issuance,
+// as opposed to pre-authorization in Authorize.
+// It is only supported by CAs implementing RFC 8555.
+//
+// The caller then needs to fetch each authorization with GetAuthorization,
+// identify those with StatusPending status and fulfill a challenge using Accept.
+// Once all authorizations are satisfied, the caller will typically want to poll
+// order status using WaitOrder until it's in StatusReady state.
+// To finalize the order and obtain a certificate, the caller submits a CSR with CreateOrderCert.
+func (c *Client) AuthorizeOrder(ctx context.Context, id []AuthzID, opt ...OrderOption) (*Order, error) {
+	dir, err := c.Discover(ctx)
+	if err != nil {
+		return nil, err
+	}
+
+	req := struct {
+		Identifiers []wireAuthzID `json:"identifiers"`
+		NotBefore   string        `json:"notBefore,omitempty"`
+		NotAfter    string        `json:"notAfter,omitempty"`
+	}{}
+	for _, v := range id {
+		req.Identifiers = append(req.Identifiers, wireAuthzID{
+			Type:  v.Type,
+			Value: v.Value,
+		})
+	}
+	for _, o := range opt {
+		switch o := o.(type) {
+		case orderNotBeforeOpt:
+			req.NotBefore = time.Time(o).Format(time.RFC3339)
+		case orderNotAfterOpt:
+			req.NotAfter = time.Time(o).Format(time.RFC3339)
+		default:
+			// Package's fault if we let this happen.
+			panic(fmt.Sprintf("unsupported order option type %T", o))
+		}
+	}
+
+	res, err := c.post(ctx, nil, dir.OrderURL, req, wantStatus(http.StatusCreated))
+	if err != nil {
+		return nil, err
+	}
+	defer res.Body.Close()
+	return responseOrder(res)
+}
+
+// GetOrder retrives an order identified by the given URL.
+// For orders created with AuthorizeOrder, the url value is Order.URI.
+//
+// If a caller needs to poll an order until its status is final,
+// see the WaitOrder method.
+func (c *Client) GetOrder(ctx context.Context, url string) (*Order, error) {
+	if _, err := c.Discover(ctx); err != nil {
+		return nil, err
+	}
+
+	res, err := c.postAsGet(ctx, url, wantStatus(http.StatusOK))
+	if err != nil {
+		return nil, err
+	}
+	defer res.Body.Close()
+	return responseOrder(res)
+}
+
+// WaitOrder polls an order from the given URL until it is in one of the final states,
+// StatusReady, StatusValid or StatusInvalid, the CA responded with a non-retryable error
+// or the context is done.
+//
+// It returns a non-nil Order only if its Status is StatusReady or StatusValid.
+// In all other cases WaitOrder returns an error.
+// If the Status is StatusInvalid, the returned error is of type *OrderError.
+func (c *Client) WaitOrder(ctx context.Context, url string) (*Order, error) {
+	if _, err := c.Discover(ctx); err != nil {
+		return nil, err
+	}
+	for {
+		res, err := c.postAsGet(ctx, url, wantStatus(http.StatusOK))
+		if err != nil {
+			return nil, err
+		}
+		o, err := responseOrder(res)
+		res.Body.Close()
+		switch {
+		case err != nil:
+			// Skip and retry.
+		case o.Status == StatusInvalid:
+			return nil, &OrderError{OrderURL: o.URI, Status: o.Status}
+		case o.Status == StatusReady || o.Status == StatusValid:
+			return o, nil
+		}
+
+		d := retryAfter(res.Header.Get("Retry-After"))
+		if d == 0 {
+			// Default retry-after.
+			// Same reasoning as in WaitAuthorization.
+			d = time.Second
+		}
+		t := time.NewTimer(d)
+		select {
+		case <-ctx.Done():
+			t.Stop()
+			return nil, ctx.Err()
+		case <-t.C:
+			// Retry.
+		}
+	}
+}
+
+func responseOrder(res *http.Response) (*Order, error) {
+	var v struct {
+		Status         string
+		Expires        time.Time
+		Identifiers    []wireAuthzID
+		NotBefore      time.Time
+		NotAfter       time.Time
+		Error          *wireError
+		Authorizations []string
+		Finalize       string
+		Certificate    string
+	}
+	if err := json.NewDecoder(res.Body).Decode(&v); err != nil {
+		return nil, fmt.Errorf("acme: error reading order: %v", err)
+	}
+	o := &Order{
+		URI:         res.Header.Get("Location"),
+		Status:      v.Status,
+		Expires:     v.Expires,
+		NotBefore:   v.NotBefore,
+		NotAfter:    v.NotAfter,
+		AuthzURLs:   v.Authorizations,
+		FinalizeURL: v.Finalize,
+		CertURL:     v.Certificate,
+	}
+	for _, id := range v.Identifiers {
+		o.Identifiers = append(o.Identifiers, AuthzID{Type: id.Type, Value: id.Value})
+	}
+	if v.Error != nil {
+		o.Error = v.Error.error(nil /* headers */)
+	}
+	return o, nil
+}
+
+// CreateOrderCert submits the CSR (Certificate Signing Request) to a CA at the specified URL.
+// The URL is the FinalizeURL field of an Order created with AuthorizeOrder.
+//
+// If the bundle argument is true, the returned value also contain the CA (issuer)
+// certificate chain. Otherwise, only a leaf certificate is returned.
+// The returned URL can be used to re-fetch the certificate using FetchCert.
+//
+// This method is only supported by CAs implementing RFC 8555. See CreateCert for pre-RFC CAs.
+//
+// CreateOrderCert returns an error if the CA's response is unreasonably large.
+// Callers are encouraged to parse the returned value to ensure the certificate is valid and has the expected features.
+func (c *Client) CreateOrderCert(ctx context.Context, url string, csr []byte, bundle bool) (der [][]byte, certURL string, err error) {
+	if _, err := c.Discover(ctx); err != nil { // required by c.accountKID
+		return nil, "", err
+	}
+
+	// RFC describes this as "finalize order" request.
+	req := struct {
+		CSR string `json:"csr"`
+	}{
+		CSR: base64.RawURLEncoding.EncodeToString(csr),
+	}
+	res, err := c.post(ctx, nil, url, req, wantStatus(http.StatusOK))
+	if err != nil {
+		return nil, "", err
+	}
+	defer res.Body.Close()
+	o, err := responseOrder(res)
+	if err != nil {
+		return nil, "", err
+	}
+
+	// Wait for CA to issue the cert if they haven't.
+	if o.Status != StatusValid {
+		o, err = c.WaitOrder(ctx, o.URI)
+	}
+	if err != nil {
+		return nil, "", err
+	}
+	// The only acceptable status post finalize and WaitOrder is "valid".
+	if o.Status != StatusValid {
+		return nil, "", &OrderError{OrderURL: o.URI, Status: o.Status}
+	}
+	crt, err := c.fetchCertRFC(ctx, o.CertURL, bundle)
+	return crt, o.CertURL, err
+}
+
+// fetchCertRFC downloads issued certificate from the given URL.
+// It expects the CA to respond with PEM-encoded certificate chain.
+//
+// The URL argument is the CertURL field of Order.
+func (c *Client) fetchCertRFC(ctx context.Context, url string, bundle bool) ([][]byte, error) {
+	res, err := c.postAsGet(ctx, url, wantStatus(http.StatusOK))
+	if err != nil {
+		return nil, err
+	}
+	defer res.Body.Close()
+
+	// Get all the bytes up to a sane maximum.
+	// Account very roughly for base64 overhead.
+	const max = maxCertChainSize + maxCertChainSize/33
+	b, err := ioutil.ReadAll(io.LimitReader(res.Body, max+1))
+	if err != nil {
+		return nil, fmt.Errorf("acme: fetch cert response stream: %v", err)
+	}
+	if len(b) > max {
+		return nil, errors.New("acme: certificate chain is too big")
+	}
+
+	// Decode PEM chain.
+	var chain [][]byte
+	for {
+		var p *pem.Block
+		p, b = pem.Decode(b)
+		if p == nil {
+			break
+		}
+		if p.Type != "CERTIFICATE" {
+			return nil, fmt.Errorf("acme: invalid PEM cert type %q", p.Type)
+		}
+
+		chain = append(chain, p.Bytes)
+		if !bundle {
+			return chain, nil
+		}
+		if len(chain) > maxChainLen {
+			return nil, errors.New("acme: certificate chain is too long")
+		}
+	}
+	if len(chain) == 0 {
+		return nil, errors.New("acme: certificate chain is empty")
+	}
+	return chain, nil
+}
+
+// sends a cert revocation request in either JWK form when key is non-nil or KID form otherwise.
+func (c *Client) revokeCertRFC(ctx context.Context, key crypto.Signer, cert []byte, reason CRLReasonCode) error {
+	req := &struct {
+		Cert   string `json:"certificate"`
+		Reason int    `json:"reason"`
+	}{
+		Cert:   base64.RawURLEncoding.EncodeToString(cert),
+		Reason: int(reason),
+	}
+	res, err := c.post(ctx, key, c.dir.RevokeURL, req, wantStatus(http.StatusOK))
+	if err != nil {
+		if isAlreadyRevoked(err) {
+			// Assume it is not an error to revoke an already revoked cert.
+			return nil
+		}
+		return err
+	}
+	defer res.Body.Close()
+	return nil
+}
+
+func isAlreadyRevoked(err error) bool {
+	e, ok := err.(*Error)
+	return ok && e.ProblemType == "urn:ietf:params:acme:error:alreadyRevoked"
+}
+
+// ListCertAlternates retrieves any alternate certificate chain URLs for the
+// given certificate chain URL. These alternate URLs can be passed to FetchCert
+// in order to retrieve the alternate certificate chains.
+//
+// If there are no alternate issuer certificate chains, a nil slice will be
+// returned.
+func (c *Client) ListCertAlternates(ctx context.Context, url string) ([]string, error) {
+	if _, err := c.Discover(ctx); err != nil { // required by c.accountKID
+		return nil, err
+	}
+
+	res, err := c.postAsGet(ctx, url, wantStatus(http.StatusOK))
+	if err != nil {
+		return nil, err
+	}
+	defer res.Body.Close()
+
+	// We don't need the body but we need to discard it so we don't end up
+	// preventing keep-alive
+	if _, err := io.Copy(ioutil.Discard, res.Body); err != nil {
+		return nil, fmt.Errorf("acme: cert alternates response stream: %v", err)
+	}
+	alts := linkHeader(res.Header, "alternate")
+	return alts, nil
+}
diff --git a/vendor/golang.org/x/crypto/acme/types.go b/vendor/golang.org/x/crypto/acme/types.go
new file mode 100644
index 0000000000..67b825201e
--- /dev/null
+++ b/vendor/golang.org/x/crypto/acme/types.go
@@ -0,0 +1,614 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package acme
+
+import (
+	"crypto"
+	"crypto/x509"
+	"errors"
+	"fmt"
+	"net/http"
+	"strings"
+	"time"
+)
+
+// ACME status values of Account, Order, Authorization and Challenge objects.
+// See https://tools.ietf.org/html/rfc8555#section-7.1.6 for details.
+const (
+	StatusDeactivated = "deactivated"
+	StatusExpired     = "expired"
+	StatusInvalid     = "invalid"
+	StatusPending     = "pending"
+	StatusProcessing  = "processing"
+	StatusReady       = "ready"
+	StatusRevoked     = "revoked"
+	StatusUnknown     = "unknown"
+	StatusValid       = "valid"
+)
+
+// CRLReasonCode identifies the reason for a certificate revocation.
+type CRLReasonCode int
+
+// CRL reason codes as defined in RFC 5280.
+const (
+	CRLReasonUnspecified          CRLReasonCode = 0
+	CRLReasonKeyCompromise        CRLReasonCode = 1
+	CRLReasonCACompromise         CRLReasonCode = 2
+	CRLReasonAffiliationChanged   CRLReasonCode = 3
+	CRLReasonSuperseded           CRLReasonCode = 4
+	CRLReasonCessationOfOperation CRLReasonCode = 5
+	CRLReasonCertificateHold      CRLReasonCode = 6
+	CRLReasonRemoveFromCRL        CRLReasonCode = 8
+	CRLReasonPrivilegeWithdrawn   CRLReasonCode = 9
+	CRLReasonAACompromise         CRLReasonCode = 10
+)
+
+var (
+	// ErrUnsupportedKey is returned when an unsupported key type is encountered.
+	ErrUnsupportedKey = errors.New("acme: unknown key type; only RSA and ECDSA are supported")
+
+	// ErrAccountAlreadyExists indicates that the Client's key has already been registered
+	// with the CA. It is returned by Register method.
+	ErrAccountAlreadyExists = errors.New("acme: account already exists")
+
+	// ErrNoAccount indicates that the Client's key has not been registered with the CA.
+	ErrNoAccount = errors.New("acme: account does not exist")
+)
+
+// A Subproblem describes an ACME subproblem as reported in an Error.
+type Subproblem struct {
+	// Type is a URI reference that identifies the problem type,
+	// typically in a "urn:acme:error:xxx" form.
+	Type string
+	// Detail is a human-readable explanation specific to this occurrence of the problem.
+	Detail string
+	// Instance indicates a URL that the client should direct a human user to visit
+	// in order for instructions on how to agree to the updated Terms of Service.
+	// In such an event CA sets StatusCode to 403, Type to
+	// "urn:ietf:params:acme:error:userActionRequired", and adds a Link header with relation
+	// "terms-of-service" containing the latest TOS URL.
+	Instance string
+	// Identifier may contain the ACME identifier that the error is for.
+	Identifier *AuthzID
+}
+
+func (sp Subproblem) String() string {
+	str := fmt.Sprintf("%s: ", sp.Type)
+	if sp.Identifier != nil {
+		str += fmt.Sprintf("[%s: %s] ", sp.Identifier.Type, sp.Identifier.Value)
+	}
+	str += sp.Detail
+	return str
+}
+
+// Error is an ACME error, defined in Problem Details for HTTP APIs doc
+// http://tools.ietf.org/html/draft-ietf-appsawg-http-problem.
+type Error struct {
+	// StatusCode is The HTTP status code generated by the origin server.
+	StatusCode int
+	// ProblemType is a URI reference that identifies the problem type,
+	// typically in a "urn:acme:error:xxx" form.
+	ProblemType string
+	// Detail is a human-readable explanation specific to this occurrence of the problem.
+	Detail string
+	// Instance indicates a URL that the client should direct a human user to visit
+	// in order for instructions on how to agree to the updated Terms of Service.
+	// In such an event CA sets StatusCode to 403, ProblemType to
+	// "urn:ietf:params:acme:error:userActionRequired" and a Link header with relation
+	// "terms-of-service" containing the latest TOS URL.
+	Instance string
+	// Header is the original server error response headers.
+	// It may be nil.
+	Header http.Header
+	// Subproblems may contain more detailed information about the individual problems
+	// that caused the error. This field is only sent by RFC 8555 compatible ACME
+	// servers. Defined in RFC 8555 Section 6.7.1.
+	Subproblems []Subproblem
+}
+
+func (e *Error) Error() string {
+	str := fmt.Sprintf("%d %s: %s", e.StatusCode, e.ProblemType, e.Detail)
+	if len(e.Subproblems) > 0 {
+		str += fmt.Sprintf("; subproblems:")
+		for _, sp := range e.Subproblems {
+			str += fmt.Sprintf("\n\t%s", sp)
+		}
+	}
+	return str
+}
+
+// AuthorizationError indicates that an authorization for an identifier
+// did not succeed.
+// It contains all errors from Challenge items of the failed Authorization.
+type AuthorizationError struct {
+	// URI uniquely identifies the failed Authorization.
+	URI string
+
+	// Identifier is an AuthzID.Value of the failed Authorization.
+	Identifier string
+
+	// Errors is a collection of non-nil error values of Challenge items
+	// of the failed Authorization.
+	Errors []error
+}
+
+func (a *AuthorizationError) Error() string {
+	e := make([]string, len(a.Errors))
+	for i, err := range a.Errors {
+		e[i] = err.Error()
+	}
+
+	if a.Identifier != "" {
+		return fmt.Sprintf("acme: authorization error for %s: %s", a.Identifier, strings.Join(e, "; "))
+	}
+
+	return fmt.Sprintf("acme: authorization error: %s", strings.Join(e, "; "))
+}
+
+// OrderError is returned from Client's order related methods.
+// It indicates the order is unusable and the clients should start over with
+// AuthorizeOrder.
+//
+// The clients can still fetch the order object from CA using GetOrder
+// to inspect its state.
+type OrderError struct {
+	OrderURL string
+	Status   string
+}
+
+func (oe *OrderError) Error() string {
+	return fmt.Sprintf("acme: order %s status: %s", oe.OrderURL, oe.Status)
+}
+
+// RateLimit reports whether err represents a rate limit error and
+// any Retry-After duration returned by the server.
+//
+// See the following for more details on rate limiting:
+// https://tools.ietf.org/html/draft-ietf-acme-acme-05#section-5.6
+func RateLimit(err error) (time.Duration, bool) {
+	e, ok := err.(*Error)
+	if !ok {
+		return 0, false
+	}
+	// Some CA implementations may return incorrect values.
+	// Use case-insensitive comparison.
+	if !strings.HasSuffix(strings.ToLower(e.ProblemType), ":ratelimited") {
+		return 0, false
+	}
+	if e.Header == nil {
+		return 0, true
+	}
+	return retryAfter(e.Header.Get("Retry-After")), true
+}
+
+// Account is a user account. It is associated with a private key.
+// Non-RFC 8555 fields are empty when interfacing with a compliant CA.
+type Account struct {
+	// URI is the account unique ID, which is also a URL used to retrieve
+	// account data from the CA.
+	// When interfacing with RFC 8555-compliant CAs, URI is the "kid" field
+	// value in JWS signed requests.
+	URI string
+
+	// Contact is a slice of contact info used during registration.
+	// See https://tools.ietf.org/html/rfc8555#section-7.3 for supported
+	// formats.
+	Contact []string
+
+	// Status indicates current account status as returned by the CA.
+	// Possible values are StatusValid, StatusDeactivated, and StatusRevoked.
+	Status string
+
+	// OrdersURL is a URL from which a list of orders submitted by this account
+	// can be fetched.
+	OrdersURL string
+
+	// The terms user has agreed to.
+	// A value not matching CurrentTerms indicates that the user hasn't agreed
+	// to the actual Terms of Service of the CA.
+	//
+	// It is non-RFC 8555 compliant. Package users can store the ToS they agree to
+	// during Client's Register call in the prompt callback function.
+	AgreedTerms string
+
+	// Actual terms of a CA.
+	//
+	// It is non-RFC 8555 compliant. Use Directory's Terms field.
+	// When a CA updates their terms and requires an account agreement,
+	// a URL at which instructions to do so is available in Error's Instance field.
+	CurrentTerms string
+
+	// Authz is the authorization URL used to initiate a new authz flow.
+	//
+	// It is non-RFC 8555 compliant. Use Directory's AuthzURL or OrderURL.
+	Authz string
+
+	// Authorizations is a URI from which a list of authorizations
+	// granted to this account can be fetched via a GET request.
+	//
+	// It is non-RFC 8555 compliant and is obsoleted by OrdersURL.
+	Authorizations string
+
+	// Certificates is a URI from which a list of certificates
+	// issued for this account can be fetched via a GET request.
+	//
+	// It is non-RFC 8555 compliant and is obsoleted by OrdersURL.
+	Certificates string
+
+	// ExternalAccountBinding represents an arbitrary binding to an account of
+	// the CA which the ACME server is tied to.
+	// See https://tools.ietf.org/html/rfc8555#section-7.3.4 for more details.
+	ExternalAccountBinding *ExternalAccountBinding
+}
+
+// ExternalAccountBinding contains the data needed to form a request with
+// an external account binding.
+// See https://tools.ietf.org/html/rfc8555#section-7.3.4 for more details.
+type ExternalAccountBinding struct {
+	// KID is the Key ID of the symmetric MAC key that the CA provides to
+	// identify an external account from ACME.
+	KID string
+
+	// Key is the bytes of the symmetric key that the CA provides to identify
+	// the account. Key must correspond to the KID.
+	Key []byte
+}
+
+func (e *ExternalAccountBinding) String() string {
+	return fmt.Sprintf("&{KID: %q, Key: redacted}", e.KID)
+}
+
+// Directory is ACME server discovery data.
+// See https://tools.ietf.org/html/rfc8555#section-7.1.1 for more details.
+type Directory struct {
+	// NonceURL indicates an endpoint where to fetch fresh nonce values from.
+	NonceURL string
+
+	// RegURL is an account endpoint URL, allowing for creating new accounts.
+	// Pre-RFC 8555 CAs also allow modifying existing accounts at this URL.
+	RegURL string
+
+	// OrderURL is used to initiate the certificate issuance flow
+	// as described in RFC 8555.
+	OrderURL string
+
+	// AuthzURL is used to initiate identifier pre-authorization flow.
+	// Empty string indicates the flow is unsupported by the CA.
+	AuthzURL string
+
+	// CertURL is a new certificate issuance endpoint URL.
+	// It is non-RFC 8555 compliant and is obsoleted by OrderURL.
+	CertURL string
+
+	// RevokeURL is used to initiate a certificate revocation flow.
+	RevokeURL string
+
+	// KeyChangeURL allows to perform account key rollover flow.
+	KeyChangeURL string
+
+	// Term is a URI identifying the current terms of service.
+	Terms string
+
+	// Website is an HTTP or HTTPS URL locating a website
+	// providing more information about the ACME server.
+	Website string
+
+	// CAA consists of lowercase hostname elements, which the ACME server
+	// recognises as referring to itself for the purposes of CAA record validation
+	// as defined in RFC6844.
+	CAA []string
+
+	// ExternalAccountRequired indicates that the CA requires for all account-related
+	// requests to include external account binding information.
+	ExternalAccountRequired bool
+}
+
+// Order represents a client's request for a certificate.
+// It tracks the request flow progress through to issuance.
+type Order struct {
+	// URI uniquely identifies an order.
+	URI string
+
+	// Status represents the current status of the order.
+	// It indicates which action the client should take.
+	//
+	// Possible values are StatusPending, StatusReady, StatusProcessing, StatusValid and StatusInvalid.
+	// Pending means the CA does not believe that the client has fulfilled the requirements.
+	// Ready indicates that the client has fulfilled all the requirements and can submit a CSR
+	// to obtain a certificate. This is done with Client's CreateOrderCert.
+	// Processing means the certificate is being issued.
+	// Valid indicates the CA has issued the certificate. It can be downloaded
+	// from the Order's CertURL. This is done with Client's FetchCert.
+	// Invalid means the certificate will not be issued. Users should consider this order
+	// abandoned.
+	Status string
+
+	// Expires is the timestamp after which CA considers this order invalid.
+	Expires time.Time
+
+	// Identifiers contains all identifier objects which the order pertains to.
+	Identifiers []AuthzID
+
+	// NotBefore is the requested value of the notBefore field in the certificate.
+	NotBefore time.Time
+
+	// NotAfter is the requested value of the notAfter field in the certificate.
+	NotAfter time.Time
+
+	// AuthzURLs represents authorizations to complete before a certificate
+	// for identifiers specified in the order can be issued.
+	// It also contains unexpired authorizations that the client has completed
+	// in the past.
+	//
+	// Authorization objects can be fetched using Client's GetAuthorization method.
+	//
+	// The required authorizations are dictated by CA policies.
+	// There may not be a 1:1 relationship between the identifiers and required authorizations.
+	// Required authorizations can be identified by their StatusPending status.
+	//
+	// For orders in the StatusValid or StatusInvalid state these are the authorizations
+	// which were completed.
+	AuthzURLs []string
+
+	// FinalizeURL is the endpoint at which a CSR is submitted to obtain a certificate
+	// once all the authorizations are satisfied.
+	FinalizeURL string
+
+	// CertURL points to the certificate that has been issued in response to this order.
+	CertURL string
+
+	// The error that occurred while processing the order as received from a CA, if any.
+	Error *Error
+}
+
+// OrderOption allows customizing Client.AuthorizeOrder call.
+type OrderOption interface {
+	privateOrderOpt()
+}
+
+// WithOrderNotBefore sets order's NotBefore field.
+func WithOrderNotBefore(t time.Time) OrderOption {
+	return orderNotBeforeOpt(t)
+}
+
+// WithOrderNotAfter sets order's NotAfter field.
+func WithOrderNotAfter(t time.Time) OrderOption {
+	return orderNotAfterOpt(t)
+}
+
+type orderNotBeforeOpt time.Time
+
+func (orderNotBeforeOpt) privateOrderOpt() {}
+
+type orderNotAfterOpt time.Time
+
+func (orderNotAfterOpt) privateOrderOpt() {}
+
+// Authorization encodes an authorization response.
+type Authorization struct {
+	// URI uniquely identifies a authorization.
+	URI string
+
+	// Status is the current status of an authorization.
+	// Possible values are StatusPending, StatusValid, StatusInvalid, StatusDeactivated,
+	// StatusExpired and StatusRevoked.
+	Status string
+
+	// Identifier is what the account is authorized to represent.
+	Identifier AuthzID
+
+	// The timestamp after which the CA considers the authorization invalid.
+	Expires time.Time
+
+	// Wildcard is true for authorizations of a wildcard domain name.
+	Wildcard bool
+
+	// Challenges that the client needs to fulfill in order to prove possession
+	// of the identifier (for pending authorizations).
+	// For valid authorizations, the challenge that was validated.
+	// For invalid authorizations, the challenge that was attempted and failed.
+	//
+	// RFC 8555 compatible CAs require users to fuflfill only one of the challenges.
+	Challenges []*Challenge
+
+	// A collection of sets of challenges, each of which would be sufficient
+	// to prove possession of the identifier.
+	// Clients must complete a set of challenges that covers at least one set.
+	// Challenges are identified by their indices in the challenges array.
+	// If this field is empty, the client needs to complete all challenges.
+	//
+	// This field is unused in RFC 8555.
+	Combinations [][]int
+}
+
+// AuthzID is an identifier that an account is authorized to represent.
+type AuthzID struct {
+	Type  string // The type of identifier, "dns" or "ip".
+	Value string // The identifier itself, e.g. "example.org".
+}
+
+// DomainIDs creates a slice of AuthzID with "dns" identifier type.
+func DomainIDs(names ...string) []AuthzID {
+	a := make([]AuthzID, len(names))
+	for i, v := range names {
+		a[i] = AuthzID{Type: "dns", Value: v}
+	}
+	return a
+}
+
+// IPIDs creates a slice of AuthzID with "ip" identifier type.
+// Each element of addr is textual form of an address as defined
+// in RFC1123 Section 2.1 for IPv4 and in RFC5952 Section 4 for IPv6.
+func IPIDs(addr ...string) []AuthzID {
+	a := make([]AuthzID, len(addr))
+	for i, v := range addr {
+		a[i] = AuthzID{Type: "ip", Value: v}
+	}
+	return a
+}
+
+// wireAuthzID is ACME JSON representation of authorization identifier objects.
+type wireAuthzID struct {
+	Type  string `json:"type"`
+	Value string `json:"value"`
+}
+
+// wireAuthz is ACME JSON representation of Authorization objects.
+type wireAuthz struct {
+	Identifier   wireAuthzID
+	Status       string
+	Expires      time.Time
+	Wildcard     bool
+	Challenges   []wireChallenge
+	Combinations [][]int
+	Error        *wireError
+}
+
+func (z *wireAuthz) authorization(uri string) *Authorization {
+	a := &Authorization{
+		URI:          uri,
+		Status:       z.Status,
+		Identifier:   AuthzID{Type: z.Identifier.Type, Value: z.Identifier.Value},
+		Expires:      z.Expires,
+		Wildcard:     z.Wildcard,
+		Challenges:   make([]*Challenge, len(z.Challenges)),
+		Combinations: z.Combinations, // shallow copy
+	}
+	for i, v := range z.Challenges {
+		a.Challenges[i] = v.challenge()
+	}
+	return a
+}
+
+func (z *wireAuthz) error(uri string) *AuthorizationError {
+	err := &AuthorizationError{
+		URI:        uri,
+		Identifier: z.Identifier.Value,
+	}
+
+	if z.Error != nil {
+		err.Errors = append(err.Errors, z.Error.error(nil))
+	}
+
+	for _, raw := range z.Challenges {
+		if raw.Error != nil {
+			err.Errors = append(err.Errors, raw.Error.error(nil))
+		}
+	}
+
+	return err
+}
+
+// Challenge encodes a returned CA challenge.
+// Its Error field may be non-nil if the challenge is part of an Authorization
+// with StatusInvalid.
+type Challenge struct {
+	// Type is the challenge type, e.g. "http-01", "tls-alpn-01", "dns-01".
+	Type string
+
+	// URI is where a challenge response can be posted to.
+	URI string
+
+	// Token is a random value that uniquely identifies the challenge.
+	Token string
+
+	// Status identifies the status of this challenge.
+	// In RFC 8555, possible values are StatusPending, StatusProcessing, StatusValid,
+	// and StatusInvalid.
+	Status string
+
+	// Validated is the time at which the CA validated this challenge.
+	// Always zero value in pre-RFC 8555.
+	Validated time.Time
+
+	// Error indicates the reason for an authorization failure
+	// when this challenge was used.
+	// The type of a non-nil value is *Error.
+	Error error
+}
+
+// wireChallenge is ACME JSON challenge representation.
+type wireChallenge struct {
+	URL       string `json:"url"` // RFC
+	URI       string `json:"uri"` // pre-RFC
+	Type      string
+	Token     string
+	Status    string
+	Validated time.Time
+	Error     *wireError
+}
+
+func (c *wireChallenge) challenge() *Challenge {
+	v := &Challenge{
+		URI:    c.URL,
+		Type:   c.Type,
+		Token:  c.Token,
+		Status: c.Status,
+	}
+	if v.URI == "" {
+		v.URI = c.URI // c.URL was empty; use legacy
+	}
+	if v.Status == "" {
+		v.Status = StatusPending
+	}
+	if c.Error != nil {
+		v.Error = c.Error.error(nil)
+	}
+	return v
+}
+
+// wireError is a subset of fields of the Problem Details object
+// as described in https://tools.ietf.org/html/rfc7807#section-3.1.
+type wireError struct {
+	Status      int
+	Type        string
+	Detail      string
+	Instance    string
+	Subproblems []Subproblem
+}
+
+func (e *wireError) error(h http.Header) *Error {
+	err := &Error{
+		StatusCode:  e.Status,
+		ProblemType: e.Type,
+		Detail:      e.Detail,
+		Instance:    e.Instance,
+		Header:      h,
+		Subproblems: e.Subproblems,
+	}
+	return err
+}
+
+// CertOption is an optional argument type for the TLS ChallengeCert methods for
+// customizing a temporary certificate for TLS-based challenges.
+type CertOption interface {
+	privateCertOpt()
+}
+
+// WithKey creates an option holding a private/public key pair.
+// The private part signs a certificate, and the public part represents the signee.
+func WithKey(key crypto.Signer) CertOption {
+	return &certOptKey{key}
+}
+
+type certOptKey struct {
+	key crypto.Signer
+}
+
+func (*certOptKey) privateCertOpt() {}
+
+// WithTemplate creates an option for specifying a certificate template.
+// See x509.CreateCertificate for template usage details.
+//
+// In TLS ChallengeCert methods, the template is also used as parent,
+// resulting in a self-signed certificate.
+// The DNSNames field of t is always overwritten for tls-sni challenge certs.
+func WithTemplate(t *x509.Certificate) CertOption {
+	return (*certOptTemplate)(t)
+}
+
+type certOptTemplate x509.Certificate
+
+func (*certOptTemplate) privateCertOpt() {}
diff --git a/vendor/golang.org/x/crypto/acme/version_go112.go b/vendor/golang.org/x/crypto/acme/version_go112.go
new file mode 100644
index 0000000000..b9efdb59e5
--- /dev/null
+++ b/vendor/golang.org/x/crypto/acme/version_go112.go
@@ -0,0 +1,28 @@
+// Copyright 2019 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.
+
+//go:build go1.12
+// +build go1.12
+
+package acme
+
+import "runtime/debug"
+
+func init() {
+	// Set packageVersion if the binary was built in modules mode and x/crypto
+	// was not replaced with a different module.
+	info, ok := debug.ReadBuildInfo()
+	if !ok {
+		return
+	}
+	for _, m := range info.Deps {
+		if m.Path != "golang.org/x/crypto" {
+			continue
+		}
+		if m.Replace == nil {
+			packageVersion = m.Version
+		}
+		break
+	}
+}
diff --git a/vendor/golang.org/x/crypto/argon2/argon2.go b/vendor/golang.org/x/crypto/argon2/argon2.go
new file mode 100644
index 0000000000..b423feaea9
--- /dev/null
+++ b/vendor/golang.org/x/crypto/argon2/argon2.go
@@ -0,0 +1,285 @@
+// Copyright 2017 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 argon2 implements the key derivation function Argon2.
+// Argon2 was selected as the winner of the Password Hashing Competition and can
+// be used to derive cryptographic keys from passwords.
+//
+// For a detailed specification of Argon2 see [1].
+//
+// If you aren't sure which function you need, use Argon2id (IDKey) and
+// the parameter recommendations for your scenario.
+//
+//
+// Argon2i
+//
+// Argon2i (implemented by Key) is the side-channel resistant version of Argon2.
+// It uses data-independent memory access, which is preferred for password
+// hashing and password-based key derivation. Argon2i requires more passes over
+// memory than Argon2id to protect from trade-off attacks. The recommended
+// parameters (taken from [2]) for non-interactive operations are time=3 and to
+// use the maximum available memory.
+//
+//
+// Argon2id
+//
+// Argon2id (implemented by IDKey) is a hybrid version of Argon2 combining
+// Argon2i and Argon2d. It uses data-independent memory access for the first
+// half of the first iteration over the memory and data-dependent memory access
+// for the rest. Argon2id is side-channel resistant and provides better brute-
+// force cost savings due to time-memory tradeoffs than Argon2i. The recommended
+// parameters for non-interactive operations (taken from [2]) are time=1 and to
+// use the maximum available memory.
+//
+// [1] https://github.com/P-H-C/phc-winner-argon2/blob/master/argon2-specs.pdf
+// [2] https://tools.ietf.org/html/draft-irtf-cfrg-argon2-03#section-9.3
+package argon2
+
+import (
+	"encoding/binary"
+	"sync"
+
+	"golang.org/x/crypto/blake2b"
+)
+
+// The Argon2 version implemented by this package.
+const Version = 0x13
+
+const (
+	argon2d = iota
+	argon2i
+	argon2id
+)
+
+// Key derives a key from the password, salt, and cost parameters using Argon2i
+// returning a byte slice of length keyLen that can be used as cryptographic
+// key. The CPU cost and parallelism degree must be greater than zero.
+//
+// For example, you can get a derived key for e.g. AES-256 (which needs a
+// 32-byte key) by doing:
+//
+//      key := argon2.Key([]byte("some password"), salt, 3, 32*1024, 4, 32)
+//
+// The draft RFC recommends[2] time=3, and memory=32*1024 is a sensible number.
+// If using that amount of memory (32 MB) is not possible in some contexts then
+// the time parameter can be increased to compensate.
+//
+// The time parameter specifies the number of passes over the memory and the
+// memory parameter specifies the size of the memory in KiB. For example
+// memory=32*1024 sets the memory cost to ~32 MB. The number of threads can be
+// adjusted to the number of available CPUs. The cost parameters should be
+// increased as memory latency and CPU parallelism increases. Remember to get a
+// good random salt.
+func Key(password, salt []byte, time, memory uint32, threads uint8, keyLen uint32) []byte {
+	return deriveKey(argon2i, password, salt, nil, nil, time, memory, threads, keyLen)
+}
+
+// IDKey derives a key from the password, salt, and cost parameters using
+// Argon2id returning a byte slice of length keyLen that can be used as
+// cryptographic key. The CPU cost and parallelism degree must be greater than
+// zero.
+//
+// For example, you can get a derived key for e.g. AES-256 (which needs a
+// 32-byte key) by doing:
+//
+//      key := argon2.IDKey([]byte("some password"), salt, 1, 64*1024, 4, 32)
+//
+// The draft RFC recommends[2] time=1, and memory=64*1024 is a sensible number.
+// If using that amount of memory (64 MB) is not possible in some contexts then
+// the time parameter can be increased to compensate.
+//
+// The time parameter specifies the number of passes over the memory and the
+// memory parameter specifies the size of the memory in KiB. For example
+// memory=64*1024 sets the memory cost to ~64 MB. The number of threads can be
+// adjusted to the numbers of available CPUs. The cost parameters should be
+// increased as memory latency and CPU parallelism increases. Remember to get a
+// good random salt.
+func IDKey(password, salt []byte, time, memory uint32, threads uint8, keyLen uint32) []byte {
+	return deriveKey(argon2id, password, salt, nil, nil, time, memory, threads, keyLen)
+}
+
+func deriveKey(mode int, password, salt, secret, data []byte, time, memory uint32, threads uint8, keyLen uint32) []byte {
+	if time < 1 {
+		panic("argon2: number of rounds too small")
+	}
+	if threads < 1 {
+		panic("argon2: parallelism degree too low")
+	}
+	h0 := initHash(password, salt, secret, data, time, memory, uint32(threads), keyLen, mode)
+
+	memory = memory / (syncPoints * uint32(threads)) * (syncPoints * uint32(threads))
+	if memory < 2*syncPoints*uint32(threads) {
+		memory = 2 * syncPoints * uint32(threads)
+	}
+	B := initBlocks(&h0, memory, uint32(threads))
+	processBlocks(B, time, memory, uint32(threads), mode)
+	return extractKey(B, memory, uint32(threads), keyLen)
+}
+
+const (
+	blockLength = 128
+	syncPoints  = 4
+)
+
+type block [blockLength]uint64
+
+func initHash(password, salt, key, data []byte, time, memory, threads, keyLen uint32, mode int) [blake2b.Size + 8]byte {
+	var (
+		h0     [blake2b.Size + 8]byte
+		params [24]byte
+		tmp    [4]byte
+	)
+
+	b2, _ := blake2b.New512(nil)
+	binary.LittleEndian.PutUint32(params[0:4], threads)
+	binary.LittleEndian.PutUint32(params[4:8], keyLen)
+	binary.LittleEndian.PutUint32(params[8:12], memory)
+	binary.LittleEndian.PutUint32(params[12:16], time)
+	binary.LittleEndian.PutUint32(params[16:20], uint32(Version))
+	binary.LittleEndian.PutUint32(params[20:24], uint32(mode))
+	b2.Write(params[:])
+	binary.LittleEndian.PutUint32(tmp[:], uint32(len(password)))
+	b2.Write(tmp[:])
+	b2.Write(password)
+	binary.LittleEndian.PutUint32(tmp[:], uint32(len(salt)))
+	b2.Write(tmp[:])
+	b2.Write(salt)
+	binary.LittleEndian.PutUint32(tmp[:], uint32(len(key)))
+	b2.Write(tmp[:])
+	b2.Write(key)
+	binary.LittleEndian.PutUint32(tmp[:], uint32(len(data)))
+	b2.Write(tmp[:])
+	b2.Write(data)
+	b2.Sum(h0[:0])
+	return h0
+}
+
+func initBlocks(h0 *[blake2b.Size + 8]byte, memory, threads uint32) []block {
+	var block0 [1024]byte
+	B := make([]block, memory)
+	for lane := uint32(0); lane < threads; lane++ {
+		j := lane * (memory / threads)
+		binary.LittleEndian.PutUint32(h0[blake2b.Size+4:], lane)
+
+		binary.LittleEndian.PutUint32(h0[blake2b.Size:], 0)
+		blake2bHash(block0[:], h0[:])
+		for i := range B[j+0] {
+			B[j+0][i] = binary.LittleEndian.Uint64(block0[i*8:])
+		}
+
+		binary.LittleEndian.PutUint32(h0[blake2b.Size:], 1)
+		blake2bHash(block0[:], h0[:])
+		for i := range B[j+1] {
+			B[j+1][i] = binary.LittleEndian.Uint64(block0[i*8:])
+		}
+	}
+	return B
+}
+
+func processBlocks(B []block, time, memory, threads uint32, mode int) {
+	lanes := memory / threads
+	segments := lanes / syncPoints
+
+	processSegment := func(n, slice, lane uint32, wg *sync.WaitGroup) {
+		var addresses, in, zero block
+		if mode == argon2i || (mode == argon2id && n == 0 && slice < syncPoints/2) {
+			in[0] = uint64(n)
+			in[1] = uint64(lane)
+			in[2] = uint64(slice)
+			in[3] = uint64(memory)
+			in[4] = uint64(time)
+			in[5] = uint64(mode)
+		}
+
+		index := uint32(0)
+		if n == 0 && slice == 0 {
+			index = 2 // we have already generated the first two blocks
+			if mode == argon2i || mode == argon2id {
+				in[6]++
+				processBlock(&addresses, &in, &zero)
+				processBlock(&addresses, &addresses, &zero)
+			}
+		}
+
+		offset := lane*lanes + slice*segments + index
+		var random uint64
+		for index < segments {
+			prev := offset - 1
+			if index == 0 && slice == 0 {
+				prev += lanes // last block in lane
+			}
+			if mode == argon2i || (mode == argon2id && n == 0 && slice < syncPoints/2) {
+				if index%blockLength == 0 {
+					in[6]++
+					processBlock(&addresses, &in, &zero)
+					processBlock(&addresses, &addresses, &zero)
+				}
+				random = addresses[index%blockLength]
+			} else {
+				random = B[prev][0]
+			}
+			newOffset := indexAlpha(random, lanes, segments, threads, n, slice, lane, index)
+			processBlockXOR(&B[offset], &B[prev], &B[newOffset])
+			index, offset = index+1, offset+1
+		}
+		wg.Done()
+	}
+
+	for n := uint32(0); n < time; n++ {
+		for slice := uint32(0); slice < syncPoints; slice++ {
+			var wg sync.WaitGroup
+			for lane := uint32(0); lane < threads; lane++ {
+				wg.Add(1)
+				go processSegment(n, slice, lane, &wg)
+			}
+			wg.Wait()
+		}
+	}
+
+}
+
+func extractKey(B []block, memory, threads, keyLen uint32) []byte {
+	lanes := memory / threads
+	for lane := uint32(0); lane < threads-1; lane++ {
+		for i, v := range B[(lane*lanes)+lanes-1] {
+			B[memory-1][i] ^= v
+		}
+	}
+
+	var block [1024]byte
+	for i, v := range B[memory-1] {
+		binary.LittleEndian.PutUint64(block[i*8:], v)
+	}
+	key := make([]byte, keyLen)
+	blake2bHash(key, block[:])
+	return key
+}
+
+func indexAlpha(rand uint64, lanes, segments, threads, n, slice, lane, index uint32) uint32 {
+	refLane := uint32(rand>>32) % threads
+	if n == 0 && slice == 0 {
+		refLane = lane
+	}
+	m, s := 3*segments, ((slice+1)%syncPoints)*segments
+	if lane == refLane {
+		m += index
+	}
+	if n == 0 {
+		m, s = slice*segments, 0
+		if slice == 0 || lane == refLane {
+			m += index
+		}
+	}
+	if index == 0 || lane == refLane {
+		m--
+	}
+	return phi(rand, uint64(m), uint64(s), refLane, lanes)
+}
+
+func phi(rand, m, s uint64, lane, lanes uint32) uint32 {
+	p := rand & 0xFFFFFFFF
+	p = (p * p) >> 32
+	p = (p * m) >> 32
+	return lane*lanes + uint32((s+m-(p+1))%uint64(lanes))
+}
diff --git a/vendor/golang.org/x/crypto/argon2/blake2b.go b/vendor/golang.org/x/crypto/argon2/blake2b.go
new file mode 100644
index 0000000000..10f46948dc
--- /dev/null
+++ b/vendor/golang.org/x/crypto/argon2/blake2b.go
@@ -0,0 +1,53 @@
+// Copyright 2017 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 argon2
+
+import (
+	"encoding/binary"
+	"hash"
+
+	"golang.org/x/crypto/blake2b"
+)
+
+// blake2bHash computes an arbitrary long hash value of in
+// and writes the hash to out.
+func blake2bHash(out []byte, in []byte) {
+	var b2 hash.Hash
+	if n := len(out); n < blake2b.Size {
+		b2, _ = blake2b.New(n, nil)
+	} else {
+		b2, _ = blake2b.New512(nil)
+	}
+
+	var buffer [blake2b.Size]byte
+	binary.LittleEndian.PutUint32(buffer[:4], uint32(len(out)))
+	b2.Write(buffer[:4])
+	b2.Write(in)
+
+	if len(out) <= blake2b.Size {
+		b2.Sum(out[:0])
+		return
+	}
+
+	outLen := len(out)
+	b2.Sum(buffer[:0])
+	b2.Reset()
+	copy(out, buffer[:32])
+	out = out[32:]
+	for len(out) > blake2b.Size {
+		b2.Write(buffer[:])
+		b2.Sum(buffer[:0])
+		copy(out, buffer[:32])
+		out = out[32:]
+		b2.Reset()
+	}
+
+	if outLen%blake2b.Size > 0 { // outLen > 64
+		r := ((outLen + 31) / 32) - 2 // ⌈τ /32⌉-2
+		b2, _ = blake2b.New(outLen-32*r, nil)
+	}
+	b2.Write(buffer[:])
+	b2.Sum(out[:0])
+}
diff --git a/vendor/golang.org/x/crypto/argon2/blamka_amd64.go b/vendor/golang.org/x/crypto/argon2/blamka_amd64.go
new file mode 100644
index 0000000000..a014ac92aa
--- /dev/null
+++ b/vendor/golang.org/x/crypto/argon2/blamka_amd64.go
@@ -0,0 +1,61 @@
+// Copyright 2017 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.
+
+//go:build amd64 && gc && !purego
+// +build amd64,gc,!purego
+
+package argon2
+
+import "golang.org/x/sys/cpu"
+
+func init() {
+	useSSE4 = cpu.X86.HasSSE41
+}
+
+//go:noescape
+func mixBlocksSSE2(out, a, b, c *block)
+
+//go:noescape
+func xorBlocksSSE2(out, a, b, c *block)
+
+//go:noescape
+func blamkaSSE4(b *block)
+
+func processBlockSSE(out, in1, in2 *block, xor bool) {
+	var t block
+	mixBlocksSSE2(&t, in1, in2, &t)
+	if useSSE4 {
+		blamkaSSE4(&t)
+	} else {
+		for i := 0; i < blockLength; i += 16 {
+			blamkaGeneric(
+				&t[i+0], &t[i+1], &t[i+2], &t[i+3],
+				&t[i+4], &t[i+5], &t[i+6], &t[i+7],
+				&t[i+8], &t[i+9], &t[i+10], &t[i+11],
+				&t[i+12], &t[i+13], &t[i+14], &t[i+15],
+			)
+		}
+		for i := 0; i < blockLength/8; i += 2 {
+			blamkaGeneric(
+				&t[i], &t[i+1], &t[16+i], &t[16+i+1],
+				&t[32+i], &t[32+i+1], &t[48+i], &t[48+i+1],
+				&t[64+i], &t[64+i+1], &t[80+i], &t[80+i+1],
+				&t[96+i], &t[96+i+1], &t[112+i], &t[112+i+1],
+			)
+		}
+	}
+	if xor {
+		xorBlocksSSE2(out, in1, in2, &t)
+	} else {
+		mixBlocksSSE2(out, in1, in2, &t)
+	}
+}
+
+func processBlock(out, in1, in2 *block) {
+	processBlockSSE(out, in1, in2, false)
+}
+
+func processBlockXOR(out, in1, in2 *block) {
+	processBlockSSE(out, in1, in2, true)
+}
diff --git a/vendor/golang.org/x/crypto/argon2/blamka_amd64.s b/vendor/golang.org/x/crypto/argon2/blamka_amd64.s
new file mode 100644
index 0000000000..b2cc051504
--- /dev/null
+++ b/vendor/golang.org/x/crypto/argon2/blamka_amd64.s
@@ -0,0 +1,244 @@
+// Copyright 2017 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.
+
+//go:build amd64 && gc && !purego
+// +build amd64,gc,!purego
+
+#include "textflag.h"
+
+DATA ·c40<>+0x00(SB)/8, $0x0201000706050403
+DATA ·c40<>+0x08(SB)/8, $0x0a09080f0e0d0c0b
+GLOBL ·c40<>(SB), (NOPTR+RODATA), $16
+
+DATA ·c48<>+0x00(SB)/8, $0x0100070605040302
+DATA ·c48<>+0x08(SB)/8, $0x09080f0e0d0c0b0a
+GLOBL ·c48<>(SB), (NOPTR+RODATA), $16
+
+#define SHUFFLE(v2, v3, v4, v5, v6, v7, t1, t2) \
+	MOVO       v4, t1; \
+	MOVO       v5, v4; \
+	MOVO       t1, v5; \
+	MOVO       v6, t1; \
+	PUNPCKLQDQ v6, t2; \
+	PUNPCKHQDQ v7, v6; \
+	PUNPCKHQDQ t2, v6; \
+	PUNPCKLQDQ v7, t2; \
+	MOVO       t1, v7; \
+	MOVO       v2, t1; \
+	PUNPCKHQDQ t2, v7; \
+	PUNPCKLQDQ v3, t2; \
+	PUNPCKHQDQ t2, v2; \
+	PUNPCKLQDQ t1, t2; \
+	PUNPCKHQDQ t2, v3
+
+#define SHUFFLE_INV(v2, v3, v4, v5, v6, v7, t1, t2) \
+	MOVO       v4, t1; \
+	MOVO       v5, v4; \
+	MOVO       t1, v5; \
+	MOVO       v2, t1; \
+	PUNPCKLQDQ v2, t2; \
+	PUNPCKHQDQ v3, v2; \
+	PUNPCKHQDQ t2, v2; \
+	PUNPCKLQDQ v3, t2; \
+	MOVO       t1, v3; \
+	MOVO       v6, t1; \
+	PUNPCKHQDQ t2, v3; \
+	PUNPCKLQDQ v7, t2; \
+	PUNPCKHQDQ t2, v6; \
+	PUNPCKLQDQ t1, t2; \
+	PUNPCKHQDQ t2, v7
+
+#define HALF_ROUND(v0, v1, v2, v3, v4, v5, v6, v7, t0, c40, c48) \
+	MOVO    v0, t0;        \
+	PMULULQ v2, t0;        \
+	PADDQ   v2, v0;        \
+	PADDQ   t0, v0;        \
+	PADDQ   t0, v0;        \
+	PXOR    v0, v6;        \
+	PSHUFD  $0xB1, v6, v6; \
+	MOVO    v4, t0;        \
+	PMULULQ v6, t0;        \
+	PADDQ   v6, v4;        \
+	PADDQ   t0, v4;        \
+	PADDQ   t0, v4;        \
+	PXOR    v4, v2;        \
+	PSHUFB  c40, v2;       \
+	MOVO    v0, t0;        \
+	PMULULQ v2, t0;        \
+	PADDQ   v2, v0;        \
+	PADDQ   t0, v0;        \
+	PADDQ   t0, v0;        \
+	PXOR    v0, v6;        \
+	PSHUFB  c48, v6;       \
+	MOVO    v4, t0;        \
+	PMULULQ v6, t0;        \
+	PADDQ   v6, v4;        \
+	PADDQ   t0, v4;        \
+	PADDQ   t0, v4;        \
+	PXOR    v4, v2;        \
+	MOVO    v2, t0;        \
+	PADDQ   v2, t0;        \
+	PSRLQ   $63, v2;       \
+	PXOR    t0, v2;        \
+	MOVO    v1, t0;        \
+	PMULULQ v3, t0;        \
+	PADDQ   v3, v1;        \
+	PADDQ   t0, v1;        \
+	PADDQ   t0, v1;        \
+	PXOR    v1, v7;        \
+	PSHUFD  $0xB1, v7, v7; \
+	MOVO    v5, t0;        \
+	PMULULQ v7, t0;        \
+	PADDQ   v7, v5;        \
+	PADDQ   t0, v5;        \
+	PADDQ   t0, v5;        \
+	PXOR    v5, v3;        \
+	PSHUFB  c40, v3;       \
+	MOVO    v1, t0;        \
+	PMULULQ v3, t0;        \
+	PADDQ   v3, v1;        \
+	PADDQ   t0, v1;        \
+	PADDQ   t0, v1;        \
+	PXOR    v1, v7;        \
+	PSHUFB  c48, v7;       \
+	MOVO    v5, t0;        \
+	PMULULQ v7, t0;        \
+	PADDQ   v7, v5;        \
+	PADDQ   t0, v5;        \
+	PADDQ   t0, v5;        \
+	PXOR    v5, v3;        \
+	MOVO    v3, t0;        \
+	PADDQ   v3, t0;        \
+	PSRLQ   $63, v3;       \
+	PXOR    t0, v3
+
+#define LOAD_MSG_0(block, off) \
+	MOVOU 8*(off+0)(block), X0;  \
+	MOVOU 8*(off+2)(block), X1;  \
+	MOVOU 8*(off+4)(block), X2;  \
+	MOVOU 8*(off+6)(block), X3;  \
+	MOVOU 8*(off+8)(block), X4;  \
+	MOVOU 8*(off+10)(block), X5; \
+	MOVOU 8*(off+12)(block), X6; \
+	MOVOU 8*(off+14)(block), X7
+
+#define STORE_MSG_0(block, off) \
+	MOVOU X0, 8*(off+0)(block);  \
+	MOVOU X1, 8*(off+2)(block);  \
+	MOVOU X2, 8*(off+4)(block);  \
+	MOVOU X3, 8*(off+6)(block);  \
+	MOVOU X4, 8*(off+8)(block);  \
+	MOVOU X5, 8*(off+10)(block); \
+	MOVOU X6, 8*(off+12)(block); \
+	MOVOU X7, 8*(off+14)(block)
+
+#define LOAD_MSG_1(block, off) \
+	MOVOU 8*off+0*8(block), X0;  \
+	MOVOU 8*off+16*8(block), X1; \
+	MOVOU 8*off+32*8(block), X2; \
+	MOVOU 8*off+48*8(block), X3; \
+	MOVOU 8*off+64*8(block), X4; \
+	MOVOU 8*off+80*8(block), X5; \
+	MOVOU 8*off+96*8(block), X6; \
+	MOVOU 8*off+112*8(block), X7
+
+#define STORE_MSG_1(block, off) \
+	MOVOU X0, 8*off+0*8(block);  \
+	MOVOU X1, 8*off+16*8(block); \
+	MOVOU X2, 8*off+32*8(block); \
+	MOVOU X3, 8*off+48*8(block); \
+	MOVOU X4, 8*off+64*8(block); \
+	MOVOU X5, 8*off+80*8(block); \
+	MOVOU X6, 8*off+96*8(block); \
+	MOVOU X7, 8*off+112*8(block)
+
+#define BLAMKA_ROUND_0(block, off, t0, t1, c40, c48) \
+	LOAD_MSG_0(block, off);                                   \
+	HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, t0, c40, c48); \
+	SHUFFLE(X2, X3, X4, X5, X6, X7, t0, t1);                  \
+	HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, t0, c40, c48); \
+	SHUFFLE_INV(X2, X3, X4, X5, X6, X7, t0, t1);              \
+	STORE_MSG_0(block, off)
+
+#define BLAMKA_ROUND_1(block, off, t0, t1, c40, c48) \
+	LOAD_MSG_1(block, off);                                   \
+	HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, t0, c40, c48); \
+	SHUFFLE(X2, X3, X4, X5, X6, X7, t0, t1);                  \
+	HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, t0, c40, c48); \
+	SHUFFLE_INV(X2, X3, X4, X5, X6, X7, t0, t1);              \
+	STORE_MSG_1(block, off)
+
+// func blamkaSSE4(b *block)
+TEXT ·blamkaSSE4(SB), 4, $0-8
+	MOVQ b+0(FP), AX
+
+	MOVOU ·c40<>(SB), X10
+	MOVOU ·c48<>(SB), X11
+
+	BLAMKA_ROUND_0(AX, 0, X8, X9, X10, X11)
+	BLAMKA_ROUND_0(AX, 16, X8, X9, X10, X11)
+	BLAMKA_ROUND_0(AX, 32, X8, X9, X10, X11)
+	BLAMKA_ROUND_0(AX, 48, X8, X9, X10, X11)
+	BLAMKA_ROUND_0(AX, 64, X8, X9, X10, X11)
+	BLAMKA_ROUND_0(AX, 80, X8, X9, X10, X11)
+	BLAMKA_ROUND_0(AX, 96, X8, X9, X10, X11)
+	BLAMKA_ROUND_0(AX, 112, X8, X9, X10, X11)
+
+	BLAMKA_ROUND_1(AX, 0, X8, X9, X10, X11)
+	BLAMKA_ROUND_1(AX, 2, X8, X9, X10, X11)
+	BLAMKA_ROUND_1(AX, 4, X8, X9, X10, X11)
+	BLAMKA_ROUND_1(AX, 6, X8, X9, X10, X11)
+	BLAMKA_ROUND_1(AX, 8, X8, X9, X10, X11)
+	BLAMKA_ROUND_1(AX, 10, X8, X9, X10, X11)
+	BLAMKA_ROUND_1(AX, 12, X8, X9, X10, X11)
+	BLAMKA_ROUND_1(AX, 14, X8, X9, X10, X11)
+	RET
+
+// func mixBlocksSSE2(out, a, b, c *block)
+TEXT ·mixBlocksSSE2(SB), 4, $0-32
+	MOVQ out+0(FP), DX
+	MOVQ a+8(FP), AX
+	MOVQ b+16(FP), BX
+	MOVQ a+24(FP), CX
+	MOVQ $128, BP
+
+loop:
+	MOVOU 0(AX), X0
+	MOVOU 0(BX), X1
+	MOVOU 0(CX), X2
+	PXOR  X1, X0
+	PXOR  X2, X0
+	MOVOU X0, 0(DX)
+	ADDQ  $16, AX
+	ADDQ  $16, BX
+	ADDQ  $16, CX
+	ADDQ  $16, DX
+	SUBQ  $2, BP
+	JA    loop
+	RET
+
+// func xorBlocksSSE2(out, a, b, c *block)
+TEXT ·xorBlocksSSE2(SB), 4, $0-32
+	MOVQ out+0(FP), DX
+	MOVQ a+8(FP), AX
+	MOVQ b+16(FP), BX
+	MOVQ a+24(FP), CX
+	MOVQ $128, BP
+
+loop:
+	MOVOU 0(AX), X0
+	MOVOU 0(BX), X1
+	MOVOU 0(CX), X2
+	MOVOU 0(DX), X3
+	PXOR  X1, X0
+	PXOR  X2, X0
+	PXOR  X3, X0
+	MOVOU X0, 0(DX)
+	ADDQ  $16, AX
+	ADDQ  $16, BX
+	ADDQ  $16, CX
+	ADDQ  $16, DX
+	SUBQ  $2, BP
+	JA    loop
+	RET
diff --git a/vendor/golang.org/x/crypto/argon2/blamka_generic.go b/vendor/golang.org/x/crypto/argon2/blamka_generic.go
new file mode 100644
index 0000000000..a481b2243f
--- /dev/null
+++ b/vendor/golang.org/x/crypto/argon2/blamka_generic.go
@@ -0,0 +1,163 @@
+// Copyright 2017 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 argon2
+
+var useSSE4 bool
+
+func processBlockGeneric(out, in1, in2 *block, xor bool) {
+	var t block
+	for i := range t {
+		t[i] = in1[i] ^ in2[i]
+	}
+	for i := 0; i < blockLength; i += 16 {
+		blamkaGeneric(
+			&t[i+0], &t[i+1], &t[i+2], &t[i+3],
+			&t[i+4], &t[i+5], &t[i+6], &t[i+7],
+			&t[i+8], &t[i+9], &t[i+10], &t[i+11],
+			&t[i+12], &t[i+13], &t[i+14], &t[i+15],
+		)
+	}
+	for i := 0; i < blockLength/8; i += 2 {
+		blamkaGeneric(
+			&t[i], &t[i+1], &t[16+i], &t[16+i+1],
+			&t[32+i], &t[32+i+1], &t[48+i], &t[48+i+1],
+			&t[64+i], &t[64+i+1], &t[80+i], &t[80+i+1],
+			&t[96+i], &t[96+i+1], &t[112+i], &t[112+i+1],
+		)
+	}
+	if xor {
+		for i := range t {
+			out[i] ^= in1[i] ^ in2[i] ^ t[i]
+		}
+	} else {
+		for i := range t {
+			out[i] = in1[i] ^ in2[i] ^ t[i]
+		}
+	}
+}
+
+func blamkaGeneric(t00, t01, t02, t03, t04, t05, t06, t07, t08, t09, t10, t11, t12, t13, t14, t15 *uint64) {
+	v00, v01, v02, v03 := *t00, *t01, *t02, *t03
+	v04, v05, v06, v07 := *t04, *t05, *t06, *t07
+	v08, v09, v10, v11 := *t08, *t09, *t10, *t11
+	v12, v13, v14, v15 := *t12, *t13, *t14, *t15
+
+	v00 += v04 + 2*uint64(uint32(v00))*uint64(uint32(v04))
+	v12 ^= v00
+	v12 = v12>>32 | v12<<32
+	v08 += v12 + 2*uint64(uint32(v08))*uint64(uint32(v12))
+	v04 ^= v08
+	v04 = v04>>24 | v04<<40
+
+	v00 += v04 + 2*uint64(uint32(v00))*uint64(uint32(v04))
+	v12 ^= v00
+	v12 = v12>>16 | v12<<48
+	v08 += v12 + 2*uint64(uint32(v08))*uint64(uint32(v12))
+	v04 ^= v08
+	v04 = v04>>63 | v04<<1
+
+	v01 += v05 + 2*uint64(uint32(v01))*uint64(uint32(v05))
+	v13 ^= v01
+	v13 = v13>>32 | v13<<32
+	v09 += v13 + 2*uint64(uint32(v09))*uint64(uint32(v13))
+	v05 ^= v09
+	v05 = v05>>24 | v05<<40
+
+	v01 += v05 + 2*uint64(uint32(v01))*uint64(uint32(v05))
+	v13 ^= v01
+	v13 = v13>>16 | v13<<48
+	v09 += v13 + 2*uint64(uint32(v09))*uint64(uint32(v13))
+	v05 ^= v09
+	v05 = v05>>63 | v05<<1
+
+	v02 += v06 + 2*uint64(uint32(v02))*uint64(uint32(v06))
+	v14 ^= v02
+	v14 = v14>>32 | v14<<32
+	v10 += v14 + 2*uint64(uint32(v10))*uint64(uint32(v14))
+	v06 ^= v10
+	v06 = v06>>24 | v06<<40
+
+	v02 += v06 + 2*uint64(uint32(v02))*uint64(uint32(v06))
+	v14 ^= v02
+	v14 = v14>>16 | v14<<48
+	v10 += v14 + 2*uint64(uint32(v10))*uint64(uint32(v14))
+	v06 ^= v10
+	v06 = v06>>63 | v06<<1
+
+	v03 += v07 + 2*uint64(uint32(v03))*uint64(uint32(v07))
+	v15 ^= v03
+	v15 = v15>>32 | v15<<32
+	v11 += v15 + 2*uint64(uint32(v11))*uint64(uint32(v15))
+	v07 ^= v11
+	v07 = v07>>24 | v07<<40
+
+	v03 += v07 + 2*uint64(uint32(v03))*uint64(uint32(v07))
+	v15 ^= v03
+	v15 = v15>>16 | v15<<48
+	v11 += v15 + 2*uint64(uint32(v11))*uint64(uint32(v15))
+	v07 ^= v11
+	v07 = v07>>63 | v07<<1
+
+	v00 += v05 + 2*uint64(uint32(v00))*uint64(uint32(v05))
+	v15 ^= v00
+	v15 = v15>>32 | v15<<32
+	v10 += v15 + 2*uint64(uint32(v10))*uint64(uint32(v15))
+	v05 ^= v10
+	v05 = v05>>24 | v05<<40
+
+	v00 += v05 + 2*uint64(uint32(v00))*uint64(uint32(v05))
+	v15 ^= v00
+	v15 = v15>>16 | v15<<48
+	v10 += v15 + 2*uint64(uint32(v10))*uint64(uint32(v15))
+	v05 ^= v10
+	v05 = v05>>63 | v05<<1
+
+	v01 += v06 + 2*uint64(uint32(v01))*uint64(uint32(v06))
+	v12 ^= v01
+	v12 = v12>>32 | v12<<32
+	v11 += v12 + 2*uint64(uint32(v11))*uint64(uint32(v12))
+	v06 ^= v11
+	v06 = v06>>24 | v06<<40
+
+	v01 += v06 + 2*uint64(uint32(v01))*uint64(uint32(v06))
+	v12 ^= v01
+	v12 = v12>>16 | v12<<48
+	v11 += v12 + 2*uint64(uint32(v11))*uint64(uint32(v12))
+	v06 ^= v11
+	v06 = v06>>63 | v06<<1
+
+	v02 += v07 + 2*uint64(uint32(v02))*uint64(uint32(v07))
+	v13 ^= v02
+	v13 = v13>>32 | v13<<32
+	v08 += v13 + 2*uint64(uint32(v08))*uint64(uint32(v13))
+	v07 ^= v08
+	v07 = v07>>24 | v07<<40
+
+	v02 += v07 + 2*uint64(uint32(v02))*uint64(uint32(v07))
+	v13 ^= v02
+	v13 = v13>>16 | v13<<48
+	v08 += v13 + 2*uint64(uint32(v08))*uint64(uint32(v13))
+	v07 ^= v08
+	v07 = v07>>63 | v07<<1
+
+	v03 += v04 + 2*uint64(uint32(v03))*uint64(uint32(v04))
+	v14 ^= v03
+	v14 = v14>>32 | v14<<32
+	v09 += v14 + 2*uint64(uint32(v09))*uint64(uint32(v14))
+	v04 ^= v09
+	v04 = v04>>24 | v04<<40
+
+	v03 += v04 + 2*uint64(uint32(v03))*uint64(uint32(v04))
+	v14 ^= v03
+	v14 = v14>>16 | v14<<48
+	v09 += v14 + 2*uint64(uint32(v09))*uint64(uint32(v14))
+	v04 ^= v09
+	v04 = v04>>63 | v04<<1
+
+	*t00, *t01, *t02, *t03 = v00, v01, v02, v03
+	*t04, *t05, *t06, *t07 = v04, v05, v06, v07
+	*t08, *t09, *t10, *t11 = v08, v09, v10, v11
+	*t12, *t13, *t14, *t15 = v12, v13, v14, v15
+}
diff --git a/vendor/golang.org/x/crypto/argon2/blamka_ref.go b/vendor/golang.org/x/crypto/argon2/blamka_ref.go
new file mode 100644
index 0000000000..167c59d2d5
--- /dev/null
+++ b/vendor/golang.org/x/crypto/argon2/blamka_ref.go
@@ -0,0 +1,16 @@
+// Copyright 2017 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.
+
+//go:build !amd64 || purego || !gc
+// +build !amd64 purego !gc
+
+package argon2
+
+func processBlock(out, in1, in2 *block) {
+	processBlockGeneric(out, in1, in2, false)
+}
+
+func processBlockXOR(out, in1, in2 *block) {
+	processBlockGeneric(out, in1, in2, true)
+}
diff --git a/vendor/golang.org/x/crypto/bcrypt/base64.go b/vendor/golang.org/x/crypto/bcrypt/base64.go
new file mode 100644
index 0000000000..fc31160908
--- /dev/null
+++ b/vendor/golang.org/x/crypto/bcrypt/base64.go
@@ -0,0 +1,35 @@
+// Copyright 2011 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 bcrypt
+
+import "encoding/base64"
+
+const alphabet = "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
+
+var bcEncoding = base64.NewEncoding(alphabet)
+
+func base64Encode(src []byte) []byte {
+	n := bcEncoding.EncodedLen(len(src))
+	dst := make([]byte, n)
+	bcEncoding.Encode(dst, src)
+	for dst[n-1] == '=' {
+		n--
+	}
+	return dst[:n]
+}
+
+func base64Decode(src []byte) ([]byte, error) {
+	numOfEquals := 4 - (len(src) % 4)
+	for i := 0; i < numOfEquals; i++ {
+		src = append(src, '=')
+	}
+
+	dst := make([]byte, bcEncoding.DecodedLen(len(src)))
+	n, err := bcEncoding.Decode(dst, src)
+	if err != nil {
+		return nil, err
+	}
+	return dst[:n], nil
+}
diff --git a/vendor/golang.org/x/crypto/bcrypt/bcrypt.go b/vendor/golang.org/x/crypto/bcrypt/bcrypt.go
new file mode 100644
index 0000000000..aeb73f81a1
--- /dev/null
+++ b/vendor/golang.org/x/crypto/bcrypt/bcrypt.go
@@ -0,0 +1,295 @@
+// Copyright 2011 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 bcrypt implements Provos and Mazières's bcrypt adaptive hashing
+// algorithm. See http://www.usenix.org/event/usenix99/provos/provos.pdf
+package bcrypt // import "golang.org/x/crypto/bcrypt"
+
+// The code is a port of Provos and Mazières's C implementation.
+import (
+	"crypto/rand"
+	"crypto/subtle"
+	"errors"
+	"fmt"
+	"io"
+	"strconv"
+
+	"golang.org/x/crypto/blowfish"
+)
+
+const (
+	MinCost     int = 4  // the minimum allowable cost as passed in to GenerateFromPassword
+	MaxCost     int = 31 // the maximum allowable cost as passed in to GenerateFromPassword
+	DefaultCost int = 10 // the cost that will actually be set if a cost below MinCost is passed into GenerateFromPassword
+)
+
+// The error returned from CompareHashAndPassword when a password and hash do
+// not match.
+var ErrMismatchedHashAndPassword = errors.New("crypto/bcrypt: hashedPassword is not the hash of the given password")
+
+// The error returned from CompareHashAndPassword when a hash is too short to
+// be a bcrypt hash.
+var ErrHashTooShort = errors.New("crypto/bcrypt: hashedSecret too short to be a bcrypted password")
+
+// The error returned from CompareHashAndPassword when a hash was created with
+// a bcrypt algorithm newer than this implementation.
+type HashVersionTooNewError byte
+
+func (hv HashVersionTooNewError) Error() string {
+	return fmt.Sprintf("crypto/bcrypt: bcrypt algorithm version '%c' requested is newer than current version '%c'", byte(hv), majorVersion)
+}
+
+// The error returned from CompareHashAndPassword when a hash starts with something other than '$'
+type InvalidHashPrefixError byte
+
+func (ih InvalidHashPrefixError) Error() string {
+	return fmt.Sprintf("crypto/bcrypt: bcrypt hashes must start with '$', but hashedSecret started with '%c'", byte(ih))
+}
+
+type InvalidCostError int
+
+func (ic InvalidCostError) Error() string {
+	return fmt.Sprintf("crypto/bcrypt: cost %d is outside allowed range (%d,%d)", int(ic), int(MinCost), int(MaxCost))
+}
+
+const (
+	majorVersion       = '2'
+	minorVersion       = 'a'
+	maxSaltSize        = 16
+	maxCryptedHashSize = 23
+	encodedSaltSize    = 22
+	encodedHashSize    = 31
+	minHashSize        = 59
+)
+
+// magicCipherData is an IV for the 64 Blowfish encryption calls in
+// bcrypt(). It's the string "OrpheanBeholderScryDoubt" in big-endian bytes.
+var magicCipherData = []byte{
+	0x4f, 0x72, 0x70, 0x68,
+	0x65, 0x61, 0x6e, 0x42,
+	0x65, 0x68, 0x6f, 0x6c,
+	0x64, 0x65, 0x72, 0x53,
+	0x63, 0x72, 0x79, 0x44,
+	0x6f, 0x75, 0x62, 0x74,
+}
+
+type hashed struct {
+	hash  []byte
+	salt  []byte
+	cost  int // allowed range is MinCost to MaxCost
+	major byte
+	minor byte
+}
+
+// GenerateFromPassword returns the bcrypt hash of the password at the given
+// cost. If the cost given is less than MinCost, the cost will be set to
+// DefaultCost, instead. Use CompareHashAndPassword, as defined in this package,
+// to compare the returned hashed password with its cleartext version.
+func GenerateFromPassword(password []byte, cost int) ([]byte, error) {
+	p, err := newFromPassword(password, cost)
+	if err != nil {
+		return nil, err
+	}
+	return p.Hash(), nil
+}
+
+// CompareHashAndPassword compares a bcrypt hashed password with its possible
+// plaintext equivalent. Returns nil on success, or an error on failure.
+func CompareHashAndPassword(hashedPassword, password []byte) error {
+	p, err := newFromHash(hashedPassword)
+	if err != nil {
+		return err
+	}
+
+	otherHash, err := bcrypt(password, p.cost, p.salt)
+	if err != nil {
+		return err
+	}
+
+	otherP := &hashed{otherHash, p.salt, p.cost, p.major, p.minor}
+	if subtle.ConstantTimeCompare(p.Hash(), otherP.Hash()) == 1 {
+		return nil
+	}
+
+	return ErrMismatchedHashAndPassword
+}
+
+// Cost returns the hashing cost used to create the given hashed
+// password. When, in the future, the hashing cost of a password system needs
+// to be increased in order to adjust for greater computational power, this
+// function allows one to establish which passwords need to be updated.
+func Cost(hashedPassword []byte) (int, error) {
+	p, err := newFromHash(hashedPassword)
+	if err != nil {
+		return 0, err
+	}
+	return p.cost, nil
+}
+
+func newFromPassword(password []byte, cost int) (*hashed, error) {
+	if cost < MinCost {
+		cost = DefaultCost
+	}
+	p := new(hashed)
+	p.major = majorVersion
+	p.minor = minorVersion
+
+	err := checkCost(cost)
+	if err != nil {
+		return nil, err
+	}
+	p.cost = cost
+
+	unencodedSalt := make([]byte, maxSaltSize)
+	_, err = io.ReadFull(rand.Reader, unencodedSalt)
+	if err != nil {
+		return nil, err
+	}
+
+	p.salt = base64Encode(unencodedSalt)
+	hash, err := bcrypt(password, p.cost, p.salt)
+	if err != nil {
+		return nil, err
+	}
+	p.hash = hash
+	return p, err
+}
+
+func newFromHash(hashedSecret []byte) (*hashed, error) {
+	if len(hashedSecret) < minHashSize {
+		return nil, ErrHashTooShort
+	}
+	p := new(hashed)
+	n, err := p.decodeVersion(hashedSecret)
+	if err != nil {
+		return nil, err
+	}
+	hashedSecret = hashedSecret[n:]
+	n, err = p.decodeCost(hashedSecret)
+	if err != nil {
+		return nil, err
+	}
+	hashedSecret = hashedSecret[n:]
+
+	// The "+2" is here because we'll have to append at most 2 '=' to the salt
+	// when base64 decoding it in expensiveBlowfishSetup().
+	p.salt = make([]byte, encodedSaltSize, encodedSaltSize+2)
+	copy(p.salt, hashedSecret[:encodedSaltSize])
+
+	hashedSecret = hashedSecret[encodedSaltSize:]
+	p.hash = make([]byte, len(hashedSecret))
+	copy(p.hash, hashedSecret)
+
+	return p, nil
+}
+
+func bcrypt(password []byte, cost int, salt []byte) ([]byte, error) {
+	cipherData := make([]byte, len(magicCipherData))
+	copy(cipherData, magicCipherData)
+
+	c, err := expensiveBlowfishSetup(password, uint32(cost), salt)
+	if err != nil {
+		return nil, err
+	}
+
+	for i := 0; i < 24; i += 8 {
+		for j := 0; j < 64; j++ {
+			c.Encrypt(cipherData[i:i+8], cipherData[i:i+8])
+		}
+	}
+
+	// Bug compatibility with C bcrypt implementations. We only encode 23 of
+	// the 24 bytes encrypted.
+	hsh := base64Encode(cipherData[:maxCryptedHashSize])
+	return hsh, nil
+}
+
+func expensiveBlowfishSetup(key []byte, cost uint32, salt []byte) (*blowfish.Cipher, error) {
+	csalt, err := base64Decode(salt)
+	if err != nil {
+		return nil, err
+	}
+
+	// Bug compatibility with C bcrypt implementations. They use the trailing
+	// NULL in the key string during expansion.
+	// We copy the key to prevent changing the underlying array.
+	ckey := append(key[:len(key):len(key)], 0)
+
+	c, err := blowfish.NewSaltedCipher(ckey, csalt)
+	if err != nil {
+		return nil, err
+	}
+
+	var i, rounds uint64
+	rounds = 1 << cost
+	for i = 0; i < rounds; i++ {
+		blowfish.ExpandKey(ckey, c)
+		blowfish.ExpandKey(csalt, c)
+	}
+
+	return c, nil
+}
+
+func (p *hashed) Hash() []byte {
+	arr := make([]byte, 60)
+	arr[0] = '$'
+	arr[1] = p.major
+	n := 2
+	if p.minor != 0 {
+		arr[2] = p.minor
+		n = 3
+	}
+	arr[n] = '$'
+	n++
+	copy(arr[n:], []byte(fmt.Sprintf("%02d", p.cost)))
+	n += 2
+	arr[n] = '$'
+	n++
+	copy(arr[n:], p.salt)
+	n += encodedSaltSize
+	copy(arr[n:], p.hash)
+	n += encodedHashSize
+	return arr[:n]
+}
+
+func (p *hashed) decodeVersion(sbytes []byte) (int, error) {
+	if sbytes[0] != '$' {
+		return -1, InvalidHashPrefixError(sbytes[0])
+	}
+	if sbytes[1] > majorVersion {
+		return -1, HashVersionTooNewError(sbytes[1])
+	}
+	p.major = sbytes[1]
+	n := 3
+	if sbytes[2] != '$' {
+		p.minor = sbytes[2]
+		n++
+	}
+	return n, nil
+}
+
+// sbytes should begin where decodeVersion left off.
+func (p *hashed) decodeCost(sbytes []byte) (int, error) {
+	cost, err := strconv.Atoi(string(sbytes[0:2]))
+	if err != nil {
+		return -1, err
+	}
+	err = checkCost(cost)
+	if err != nil {
+		return -1, err
+	}
+	p.cost = cost
+	return 3, nil
+}
+
+func (p *hashed) String() string {
+	return fmt.Sprintf("&{hash: %#v, salt: %#v, cost: %d, major: %c, minor: %c}", string(p.hash), p.salt, p.cost, p.major, p.minor)
+}
+
+func checkCost(cost int) error {
+	if cost < MinCost || cost > MaxCost {
+		return InvalidCostError(cost)
+	}
+	return nil
+}
diff --git a/vendor/golang.org/x/crypto/blake2b/blake2b.go b/vendor/golang.org/x/crypto/blake2b/blake2b.go
new file mode 100644
index 0000000000..d2e98d4295
--- /dev/null
+++ b/vendor/golang.org/x/crypto/blake2b/blake2b.go
@@ -0,0 +1,291 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package blake2b implements the BLAKE2b hash algorithm defined by RFC 7693
+// and the extendable output function (XOF) BLAKE2Xb.
+//
+// BLAKE2b is optimized for 64-bit platforms—including NEON-enabled ARMs—and
+// produces digests of any size between 1 and 64 bytes.
+// For a detailed specification of BLAKE2b see https://blake2.net/blake2.pdf
+// and for BLAKE2Xb see https://blake2.net/blake2x.pdf
+//
+// If you aren't sure which function you need, use BLAKE2b (Sum512 or New512).
+// If you need a secret-key MAC (message authentication code), use the New512
+// function with a non-nil key.
+//
+// BLAKE2X is a construction to compute hash values larger than 64 bytes. It
+// can produce hash values between 0 and 4 GiB.
+package blake2b
+
+import (
+	"encoding/binary"
+	"errors"
+	"hash"
+)
+
+const (
+	// The blocksize of BLAKE2b in bytes.
+	BlockSize = 128
+	// The hash size of BLAKE2b-512 in bytes.
+	Size = 64
+	// The hash size of BLAKE2b-384 in bytes.
+	Size384 = 48
+	// The hash size of BLAKE2b-256 in bytes.
+	Size256 = 32
+)
+
+var (
+	useAVX2 bool
+	useAVX  bool
+	useSSE4 bool
+)
+
+var (
+	errKeySize  = errors.New("blake2b: invalid key size")
+	errHashSize = errors.New("blake2b: invalid hash size")
+)
+
+var iv = [8]uint64{
+	0x6a09e667f3bcc908, 0xbb67ae8584caa73b, 0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1,
+	0x510e527fade682d1, 0x9b05688c2b3e6c1f, 0x1f83d9abfb41bd6b, 0x5be0cd19137e2179,
+}
+
+// Sum512 returns the BLAKE2b-512 checksum of the data.
+func Sum512(data []byte) [Size]byte {
+	var sum [Size]byte
+	checkSum(&sum, Size, data)
+	return sum
+}
+
+// Sum384 returns the BLAKE2b-384 checksum of the data.
+func Sum384(data []byte) [Size384]byte {
+	var sum [Size]byte
+	var sum384 [Size384]byte
+	checkSum(&sum, Size384, data)
+	copy(sum384[:], sum[:Size384])
+	return sum384
+}
+
+// Sum256 returns the BLAKE2b-256 checksum of the data.
+func Sum256(data []byte) [Size256]byte {
+	var sum [Size]byte
+	var sum256 [Size256]byte
+	checkSum(&sum, Size256, data)
+	copy(sum256[:], sum[:Size256])
+	return sum256
+}
+
+// New512 returns a new hash.Hash computing the BLAKE2b-512 checksum. A non-nil
+// key turns the hash into a MAC. The key must be between zero and 64 bytes long.
+func New512(key []byte) (hash.Hash, error) { return newDigest(Size, key) }
+
+// New384 returns a new hash.Hash computing the BLAKE2b-384 checksum. A non-nil
+// key turns the hash into a MAC. The key must be between zero and 64 bytes long.
+func New384(key []byte) (hash.Hash, error) { return newDigest(Size384, key) }
+
+// New256 returns a new hash.Hash computing the BLAKE2b-256 checksum. A non-nil
+// key turns the hash into a MAC. The key must be between zero and 64 bytes long.
+func New256(key []byte) (hash.Hash, error) { return newDigest(Size256, key) }
+
+// New returns a new hash.Hash computing the BLAKE2b checksum with a custom length.
+// A non-nil key turns the hash into a MAC. The key must be between zero and 64 bytes long.
+// The hash size can be a value between 1 and 64 but it is highly recommended to use
+// values equal or greater than:
+// - 32 if BLAKE2b is used as a hash function (The key is zero bytes long).
+// - 16 if BLAKE2b is used as a MAC function (The key is at least 16 bytes long).
+// When the key is nil, the returned hash.Hash implements BinaryMarshaler
+// and BinaryUnmarshaler for state (de)serialization as documented by hash.Hash.
+func New(size int, key []byte) (hash.Hash, error) { return newDigest(size, key) }
+
+func newDigest(hashSize int, key []byte) (*digest, error) {
+	if hashSize < 1 || hashSize > Size {
+		return nil, errHashSize
+	}
+	if len(key) > Size {
+		return nil, errKeySize
+	}
+	d := &digest{
+		size:   hashSize,
+		keyLen: len(key),
+	}
+	copy(d.key[:], key)
+	d.Reset()
+	return d, nil
+}
+
+func checkSum(sum *[Size]byte, hashSize int, data []byte) {
+	h := iv
+	h[0] ^= uint64(hashSize) | (1 << 16) | (1 << 24)
+	var c [2]uint64
+
+	if length := len(data); length > BlockSize {
+		n := length &^ (BlockSize - 1)
+		if length == n {
+			n -= BlockSize
+		}
+		hashBlocks(&h, &c, 0, data[:n])
+		data = data[n:]
+	}
+
+	var block [BlockSize]byte
+	offset := copy(block[:], data)
+	remaining := uint64(BlockSize - offset)
+	if c[0] < remaining {
+		c[1]--
+	}
+	c[0] -= remaining
+
+	hashBlocks(&h, &c, 0xFFFFFFFFFFFFFFFF, block[:])
+
+	for i, v := range h[:(hashSize+7)/8] {
+		binary.LittleEndian.PutUint64(sum[8*i:], v)
+	}
+}
+
+type digest struct {
+	h      [8]uint64
+	c      [2]uint64
+	size   int
+	block  [BlockSize]byte
+	offset int
+
+	key    [BlockSize]byte
+	keyLen int
+}
+
+const (
+	magic         = "b2b"
+	marshaledSize = len(magic) + 8*8 + 2*8 + 1 + BlockSize + 1
+)
+
+func (d *digest) MarshalBinary() ([]byte, error) {
+	if d.keyLen != 0 {
+		return nil, errors.New("crypto/blake2b: cannot marshal MACs")
+	}
+	b := make([]byte, 0, marshaledSize)
+	b = append(b, magic...)
+	for i := 0; i < 8; i++ {
+		b = appendUint64(b, d.h[i])
+	}
+	b = appendUint64(b, d.c[0])
+	b = appendUint64(b, d.c[1])
+	// Maximum value for size is 64
+	b = append(b, byte(d.size))
+	b = append(b, d.block[:]...)
+	b = append(b, byte(d.offset))
+	return b, nil
+}
+
+func (d *digest) UnmarshalBinary(b []byte) error {
+	if len(b) < len(magic) || string(b[:len(magic)]) != magic {
+		return errors.New("crypto/blake2b: invalid hash state identifier")
+	}
+	if len(b) != marshaledSize {
+		return errors.New("crypto/blake2b: invalid hash state size")
+	}
+	b = b[len(magic):]
+	for i := 0; i < 8; i++ {
+		b, d.h[i] = consumeUint64(b)
+	}
+	b, d.c[0] = consumeUint64(b)
+	b, d.c[1] = consumeUint64(b)
+	d.size = int(b[0])
+	b = b[1:]
+	copy(d.block[:], b[:BlockSize])
+	b = b[BlockSize:]
+	d.offset = int(b[0])
+	return nil
+}
+
+func (d *digest) BlockSize() int { return BlockSize }
+
+func (d *digest) Size() int { return d.size }
+
+func (d *digest) Reset() {
+	d.h = iv
+	d.h[0] ^= uint64(d.size) | (uint64(d.keyLen) << 8) | (1 << 16) | (1 << 24)
+	d.offset, d.c[0], d.c[1] = 0, 0, 0
+	if d.keyLen > 0 {
+		d.block = d.key
+		d.offset = BlockSize
+	}
+}
+
+func (d *digest) Write(p []byte) (n int, err error) {
+	n = len(p)
+
+	if d.offset > 0 {
+		remaining := BlockSize - d.offset
+		if n <= remaining {
+			d.offset += copy(d.block[d.offset:], p)
+			return
+		}
+		copy(d.block[d.offset:], p[:remaining])
+		hashBlocks(&d.h, &d.c, 0, d.block[:])
+		d.offset = 0
+		p = p[remaining:]
+	}
+
+	if length := len(p); length > BlockSize {
+		nn := length &^ (BlockSize - 1)
+		if length == nn {
+			nn -= BlockSize
+		}
+		hashBlocks(&d.h, &d.c, 0, p[:nn])
+		p = p[nn:]
+	}
+
+	if len(p) > 0 {
+		d.offset += copy(d.block[:], p)
+	}
+
+	return
+}
+
+func (d *digest) Sum(sum []byte) []byte {
+	var hash [Size]byte
+	d.finalize(&hash)
+	return append(sum, hash[:d.size]...)
+}
+
+func (d *digest) finalize(hash *[Size]byte) {
+	var block [BlockSize]byte
+	copy(block[:], d.block[:d.offset])
+	remaining := uint64(BlockSize - d.offset)
+
+	c := d.c
+	if c[0] < remaining {
+		c[1]--
+	}
+	c[0] -= remaining
+
+	h := d.h
+	hashBlocks(&h, &c, 0xFFFFFFFFFFFFFFFF, block[:])
+
+	for i, v := range h {
+		binary.LittleEndian.PutUint64(hash[8*i:], v)
+	}
+}
+
+func appendUint64(b []byte, x uint64) []byte {
+	var a [8]byte
+	binary.BigEndian.PutUint64(a[:], x)
+	return append(b, a[:]...)
+}
+
+func appendUint32(b []byte, x uint32) []byte {
+	var a [4]byte
+	binary.BigEndian.PutUint32(a[:], x)
+	return append(b, a[:]...)
+}
+
+func consumeUint64(b []byte) ([]byte, uint64) {
+	x := binary.BigEndian.Uint64(b)
+	return b[8:], x
+}
+
+func consumeUint32(b []byte) ([]byte, uint32) {
+	x := binary.BigEndian.Uint32(b)
+	return b[4:], x
+}
diff --git a/vendor/golang.org/x/crypto/blake2b/blake2bAVX2_amd64.go b/vendor/golang.org/x/crypto/blake2b/blake2bAVX2_amd64.go
new file mode 100644
index 0000000000..56bfaaa17d
--- /dev/null
+++ b/vendor/golang.org/x/crypto/blake2b/blake2bAVX2_amd64.go
@@ -0,0 +1,38 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build go1.7 && amd64 && gc && !purego
+// +build go1.7,amd64,gc,!purego
+
+package blake2b
+
+import "golang.org/x/sys/cpu"
+
+func init() {
+	useAVX2 = cpu.X86.HasAVX2
+	useAVX = cpu.X86.HasAVX
+	useSSE4 = cpu.X86.HasSSE41
+}
+
+//go:noescape
+func hashBlocksAVX2(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte)
+
+//go:noescape
+func hashBlocksAVX(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte)
+
+//go:noescape
+func hashBlocksSSE4(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte)
+
+func hashBlocks(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte) {
+	switch {
+	case useAVX2:
+		hashBlocksAVX2(h, c, flag, blocks)
+	case useAVX:
+		hashBlocksAVX(h, c, flag, blocks)
+	case useSSE4:
+		hashBlocksSSE4(h, c, flag, blocks)
+	default:
+		hashBlocksGeneric(h, c, flag, blocks)
+	}
+}
diff --git a/vendor/golang.org/x/crypto/blake2b/blake2bAVX2_amd64.s b/vendor/golang.org/x/crypto/blake2b/blake2bAVX2_amd64.s
new file mode 100644
index 0000000000..4b9daa18d9
--- /dev/null
+++ b/vendor/golang.org/x/crypto/blake2b/blake2bAVX2_amd64.s
@@ -0,0 +1,745 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build go1.7 && amd64 && gc && !purego
+// +build go1.7,amd64,gc,!purego
+
+#include "textflag.h"
+
+DATA ·AVX2_iv0<>+0x00(SB)/8, $0x6a09e667f3bcc908
+DATA ·AVX2_iv0<>+0x08(SB)/8, $0xbb67ae8584caa73b
+DATA ·AVX2_iv0<>+0x10(SB)/8, $0x3c6ef372fe94f82b
+DATA ·AVX2_iv0<>+0x18(SB)/8, $0xa54ff53a5f1d36f1
+GLOBL ·AVX2_iv0<>(SB), (NOPTR+RODATA), $32
+
+DATA ·AVX2_iv1<>+0x00(SB)/8, $0x510e527fade682d1
+DATA ·AVX2_iv1<>+0x08(SB)/8, $0x9b05688c2b3e6c1f
+DATA ·AVX2_iv1<>+0x10(SB)/8, $0x1f83d9abfb41bd6b
+DATA ·AVX2_iv1<>+0x18(SB)/8, $0x5be0cd19137e2179
+GLOBL ·AVX2_iv1<>(SB), (NOPTR+RODATA), $32
+
+DATA ·AVX2_c40<>+0x00(SB)/8, $0x0201000706050403
+DATA ·AVX2_c40<>+0x08(SB)/8, $0x0a09080f0e0d0c0b
+DATA ·AVX2_c40<>+0x10(SB)/8, $0x0201000706050403
+DATA ·AVX2_c40<>+0x18(SB)/8, $0x0a09080f0e0d0c0b
+GLOBL ·AVX2_c40<>(SB), (NOPTR+RODATA), $32
+
+DATA ·AVX2_c48<>+0x00(SB)/8, $0x0100070605040302
+DATA ·AVX2_c48<>+0x08(SB)/8, $0x09080f0e0d0c0b0a
+DATA ·AVX2_c48<>+0x10(SB)/8, $0x0100070605040302
+DATA ·AVX2_c48<>+0x18(SB)/8, $0x09080f0e0d0c0b0a
+GLOBL ·AVX2_c48<>(SB), (NOPTR+RODATA), $32
+
+DATA ·AVX_iv0<>+0x00(SB)/8, $0x6a09e667f3bcc908
+DATA ·AVX_iv0<>+0x08(SB)/8, $0xbb67ae8584caa73b
+GLOBL ·AVX_iv0<>(SB), (NOPTR+RODATA), $16
+
+DATA ·AVX_iv1<>+0x00(SB)/8, $0x3c6ef372fe94f82b
+DATA ·AVX_iv1<>+0x08(SB)/8, $0xa54ff53a5f1d36f1
+GLOBL ·AVX_iv1<>(SB), (NOPTR+RODATA), $16
+
+DATA ·AVX_iv2<>+0x00(SB)/8, $0x510e527fade682d1
+DATA ·AVX_iv2<>+0x08(SB)/8, $0x9b05688c2b3e6c1f
+GLOBL ·AVX_iv2<>(SB), (NOPTR+RODATA), $16
+
+DATA ·AVX_iv3<>+0x00(SB)/8, $0x1f83d9abfb41bd6b
+DATA ·AVX_iv3<>+0x08(SB)/8, $0x5be0cd19137e2179
+GLOBL ·AVX_iv3<>(SB), (NOPTR+RODATA), $16
+
+DATA ·AVX_c40<>+0x00(SB)/8, $0x0201000706050403
+DATA ·AVX_c40<>+0x08(SB)/8, $0x0a09080f0e0d0c0b
+GLOBL ·AVX_c40<>(SB), (NOPTR+RODATA), $16
+
+DATA ·AVX_c48<>+0x00(SB)/8, $0x0100070605040302
+DATA ·AVX_c48<>+0x08(SB)/8, $0x09080f0e0d0c0b0a
+GLOBL ·AVX_c48<>(SB), (NOPTR+RODATA), $16
+
+#define VPERMQ_0x39_Y1_Y1 BYTE $0xc4; BYTE $0xe3; BYTE $0xfd; BYTE $0x00; BYTE $0xc9; BYTE $0x39
+#define VPERMQ_0x93_Y1_Y1 BYTE $0xc4; BYTE $0xe3; BYTE $0xfd; BYTE $0x00; BYTE $0xc9; BYTE $0x93
+#define VPERMQ_0x4E_Y2_Y2 BYTE $0xc4; BYTE $0xe3; BYTE $0xfd; BYTE $0x00; BYTE $0xd2; BYTE $0x4e
+#define VPERMQ_0x93_Y3_Y3 BYTE $0xc4; BYTE $0xe3; BYTE $0xfd; BYTE $0x00; BYTE $0xdb; BYTE $0x93
+#define VPERMQ_0x39_Y3_Y3 BYTE $0xc4; BYTE $0xe3; BYTE $0xfd; BYTE $0x00; BYTE $0xdb; BYTE $0x39
+
+#define ROUND_AVX2(m0, m1, m2, m3, t, c40, c48) \
+	VPADDQ  m0, Y0, Y0;   \
+	VPADDQ  Y1, Y0, Y0;   \
+	VPXOR   Y0, Y3, Y3;   \
+	VPSHUFD $-79, Y3, Y3; \
+	VPADDQ  Y3, Y2, Y2;   \
+	VPXOR   Y2, Y1, Y1;   \
+	VPSHUFB c40, Y1, Y1;  \
+	VPADDQ  m1, Y0, Y0;   \
+	VPADDQ  Y1, Y0, Y0;   \
+	VPXOR   Y0, Y3, Y3;   \
+	VPSHUFB c48, Y3, Y3;  \
+	VPADDQ  Y3, Y2, Y2;   \
+	VPXOR   Y2, Y1, Y1;   \
+	VPADDQ  Y1, Y1, t;    \
+	VPSRLQ  $63, Y1, Y1;  \
+	VPXOR   t, Y1, Y1;    \
+	VPERMQ_0x39_Y1_Y1;    \
+	VPERMQ_0x4E_Y2_Y2;    \
+	VPERMQ_0x93_Y3_Y3;    \
+	VPADDQ  m2, Y0, Y0;   \
+	VPADDQ  Y1, Y0, Y0;   \
+	VPXOR   Y0, Y3, Y3;   \
+	VPSHUFD $-79, Y3, Y3; \
+	VPADDQ  Y3, Y2, Y2;   \
+	VPXOR   Y2, Y1, Y1;   \
+	VPSHUFB c40, Y1, Y1;  \
+	VPADDQ  m3, Y0, Y0;   \
+	VPADDQ  Y1, Y0, Y0;   \
+	VPXOR   Y0, Y3, Y3;   \
+	VPSHUFB c48, Y3, Y3;  \
+	VPADDQ  Y3, Y2, Y2;   \
+	VPXOR   Y2, Y1, Y1;   \
+	VPADDQ  Y1, Y1, t;    \
+	VPSRLQ  $63, Y1, Y1;  \
+	VPXOR   t, Y1, Y1;    \
+	VPERMQ_0x39_Y3_Y3;    \
+	VPERMQ_0x4E_Y2_Y2;    \
+	VPERMQ_0x93_Y1_Y1
+
+#define VMOVQ_SI_X11_0 BYTE $0xC5; BYTE $0x7A; BYTE $0x7E; BYTE $0x1E
+#define VMOVQ_SI_X12_0 BYTE $0xC5; BYTE $0x7A; BYTE $0x7E; BYTE $0x26
+#define VMOVQ_SI_X13_0 BYTE $0xC5; BYTE $0x7A; BYTE $0x7E; BYTE $0x2E
+#define VMOVQ_SI_X14_0 BYTE $0xC5; BYTE $0x7A; BYTE $0x7E; BYTE $0x36
+#define VMOVQ_SI_X15_0 BYTE $0xC5; BYTE $0x7A; BYTE $0x7E; BYTE $0x3E
+
+#define VMOVQ_SI_X11(n) BYTE $0xC5; BYTE $0x7A; BYTE $0x7E; BYTE $0x5E; BYTE $n
+#define VMOVQ_SI_X12(n) BYTE $0xC5; BYTE $0x7A; BYTE $0x7E; BYTE $0x66; BYTE $n
+#define VMOVQ_SI_X13(n) BYTE $0xC5; BYTE $0x7A; BYTE $0x7E; BYTE $0x6E; BYTE $n
+#define VMOVQ_SI_X14(n) BYTE $0xC5; BYTE $0x7A; BYTE $0x7E; BYTE $0x76; BYTE $n
+#define VMOVQ_SI_X15(n) BYTE $0xC5; BYTE $0x7A; BYTE $0x7E; BYTE $0x7E; BYTE $n
+
+#define VPINSRQ_1_SI_X11_0 BYTE $0xC4; BYTE $0x63; BYTE $0xA1; BYTE $0x22; BYTE $0x1E; BYTE $0x01
+#define VPINSRQ_1_SI_X12_0 BYTE $0xC4; BYTE $0x63; BYTE $0x99; BYTE $0x22; BYTE $0x26; BYTE $0x01
+#define VPINSRQ_1_SI_X13_0 BYTE $0xC4; BYTE $0x63; BYTE $0x91; BYTE $0x22; BYTE $0x2E; BYTE $0x01
+#define VPINSRQ_1_SI_X14_0 BYTE $0xC4; BYTE $0x63; BYTE $0x89; BYTE $0x22; BYTE $0x36; BYTE $0x01
+#define VPINSRQ_1_SI_X15_0 BYTE $0xC4; BYTE $0x63; BYTE $0x81; BYTE $0x22; BYTE $0x3E; BYTE $0x01
+
+#define VPINSRQ_1_SI_X11(n) BYTE $0xC4; BYTE $0x63; BYTE $0xA1; BYTE $0x22; BYTE $0x5E; BYTE $n; BYTE $0x01
+#define VPINSRQ_1_SI_X12(n) BYTE $0xC4; BYTE $0x63; BYTE $0x99; BYTE $0x22; BYTE $0x66; BYTE $n; BYTE $0x01
+#define VPINSRQ_1_SI_X13(n) BYTE $0xC4; BYTE $0x63; BYTE $0x91; BYTE $0x22; BYTE $0x6E; BYTE $n; BYTE $0x01
+#define VPINSRQ_1_SI_X14(n) BYTE $0xC4; BYTE $0x63; BYTE $0x89; BYTE $0x22; BYTE $0x76; BYTE $n; BYTE $0x01
+#define VPINSRQ_1_SI_X15(n) BYTE $0xC4; BYTE $0x63; BYTE $0x81; BYTE $0x22; BYTE $0x7E; BYTE $n; BYTE $0x01
+
+#define VMOVQ_R8_X15 BYTE $0xC4; BYTE $0x41; BYTE $0xF9; BYTE $0x6E; BYTE $0xF8
+#define VPINSRQ_1_R9_X15 BYTE $0xC4; BYTE $0x43; BYTE $0x81; BYTE $0x22; BYTE $0xF9; BYTE $0x01
+
+// load msg: Y12 = (i0, i1, i2, i3)
+// i0, i1, i2, i3 must not be 0
+#define LOAD_MSG_AVX2_Y12(i0, i1, i2, i3) \
+	VMOVQ_SI_X12(i0*8);           \
+	VMOVQ_SI_X11(i2*8);           \
+	VPINSRQ_1_SI_X12(i1*8);       \
+	VPINSRQ_1_SI_X11(i3*8);       \
+	VINSERTI128 $1, X11, Y12, Y12
+
+// load msg: Y13 = (i0, i1, i2, i3)
+// i0, i1, i2, i3 must not be 0
+#define LOAD_MSG_AVX2_Y13(i0, i1, i2, i3) \
+	VMOVQ_SI_X13(i0*8);           \
+	VMOVQ_SI_X11(i2*8);           \
+	VPINSRQ_1_SI_X13(i1*8);       \
+	VPINSRQ_1_SI_X11(i3*8);       \
+	VINSERTI128 $1, X11, Y13, Y13
+
+// load msg: Y14 = (i0, i1, i2, i3)
+// i0, i1, i2, i3 must not be 0
+#define LOAD_MSG_AVX2_Y14(i0, i1, i2, i3) \
+	VMOVQ_SI_X14(i0*8);           \
+	VMOVQ_SI_X11(i2*8);           \
+	VPINSRQ_1_SI_X14(i1*8);       \
+	VPINSRQ_1_SI_X11(i3*8);       \
+	VINSERTI128 $1, X11, Y14, Y14
+
+// load msg: Y15 = (i0, i1, i2, i3)
+// i0, i1, i2, i3 must not be 0
+#define LOAD_MSG_AVX2_Y15(i0, i1, i2, i3) \
+	VMOVQ_SI_X15(i0*8);           \
+	VMOVQ_SI_X11(i2*8);           \
+	VPINSRQ_1_SI_X15(i1*8);       \
+	VPINSRQ_1_SI_X11(i3*8);       \
+	VINSERTI128 $1, X11, Y15, Y15
+
+#define LOAD_MSG_AVX2_0_2_4_6_1_3_5_7_8_10_12_14_9_11_13_15() \
+	VMOVQ_SI_X12_0;                   \
+	VMOVQ_SI_X11(4*8);                \
+	VPINSRQ_1_SI_X12(2*8);            \
+	VPINSRQ_1_SI_X11(6*8);            \
+	VINSERTI128 $1, X11, Y12, Y12;    \
+	LOAD_MSG_AVX2_Y13(1, 3, 5, 7);    \
+	LOAD_MSG_AVX2_Y14(8, 10, 12, 14); \
+	LOAD_MSG_AVX2_Y15(9, 11, 13, 15)
+
+#define LOAD_MSG_AVX2_14_4_9_13_10_8_15_6_1_0_11_5_12_2_7_3() \
+	LOAD_MSG_AVX2_Y12(14, 4, 9, 13); \
+	LOAD_MSG_AVX2_Y13(10, 8, 15, 6); \
+	VMOVQ_SI_X11(11*8);              \
+	VPSHUFD     $0x4E, 0*8(SI), X14; \
+	VPINSRQ_1_SI_X11(5*8);           \
+	VINSERTI128 $1, X11, Y14, Y14;   \
+	LOAD_MSG_AVX2_Y15(12, 2, 7, 3)
+
+#define LOAD_MSG_AVX2_11_12_5_15_8_0_2_13_10_3_7_9_14_6_1_4() \
+	VMOVQ_SI_X11(5*8);              \
+	VMOVDQU     11*8(SI), X12;      \
+	VPINSRQ_1_SI_X11(15*8);         \
+	VINSERTI128 $1, X11, Y12, Y12;  \
+	VMOVQ_SI_X13(8*8);              \
+	VMOVQ_SI_X11(2*8);              \
+	VPINSRQ_1_SI_X13_0;             \
+	VPINSRQ_1_SI_X11(13*8);         \
+	VINSERTI128 $1, X11, Y13, Y13;  \
+	LOAD_MSG_AVX2_Y14(10, 3, 7, 9); \
+	LOAD_MSG_AVX2_Y15(14, 6, 1, 4)
+
+#define LOAD_MSG_AVX2_7_3_13_11_9_1_12_14_2_5_4_15_6_10_0_8() \
+	LOAD_MSG_AVX2_Y12(7, 3, 13, 11); \
+	LOAD_MSG_AVX2_Y13(9, 1, 12, 14); \
+	LOAD_MSG_AVX2_Y14(2, 5, 4, 15);  \
+	VMOVQ_SI_X15(6*8);               \
+	VMOVQ_SI_X11_0;                  \
+	VPINSRQ_1_SI_X15(10*8);          \
+	VPINSRQ_1_SI_X11(8*8);           \
+	VINSERTI128 $1, X11, Y15, Y15
+
+#define LOAD_MSG_AVX2_9_5_2_10_0_7_4_15_14_11_6_3_1_12_8_13() \
+	LOAD_MSG_AVX2_Y12(9, 5, 2, 10);  \
+	VMOVQ_SI_X13_0;                  \
+	VMOVQ_SI_X11(4*8);               \
+	VPINSRQ_1_SI_X13(7*8);           \
+	VPINSRQ_1_SI_X11(15*8);          \
+	VINSERTI128 $1, X11, Y13, Y13;   \
+	LOAD_MSG_AVX2_Y14(14, 11, 6, 3); \
+	LOAD_MSG_AVX2_Y15(1, 12, 8, 13)
+
+#define LOAD_MSG_AVX2_2_6_0_8_12_10_11_3_4_7_15_1_13_5_14_9() \
+	VMOVQ_SI_X12(2*8);                \
+	VMOVQ_SI_X11_0;                   \
+	VPINSRQ_1_SI_X12(6*8);            \
+	VPINSRQ_1_SI_X11(8*8);            \
+	VINSERTI128 $1, X11, Y12, Y12;    \
+	LOAD_MSG_AVX2_Y13(12, 10, 11, 3); \
+	LOAD_MSG_AVX2_Y14(4, 7, 15, 1);   \
+	LOAD_MSG_AVX2_Y15(13, 5, 14, 9)
+
+#define LOAD_MSG_AVX2_12_1_14_4_5_15_13_10_0_6_9_8_7_3_2_11() \
+	LOAD_MSG_AVX2_Y12(12, 1, 14, 4);  \
+	LOAD_MSG_AVX2_Y13(5, 15, 13, 10); \
+	VMOVQ_SI_X14_0;                   \
+	VPSHUFD     $0x4E, 8*8(SI), X11;  \
+	VPINSRQ_1_SI_X14(6*8);            \
+	VINSERTI128 $1, X11, Y14, Y14;    \
+	LOAD_MSG_AVX2_Y15(7, 3, 2, 11)
+
+#define LOAD_MSG_AVX2_13_7_12_3_11_14_1_9_5_15_8_2_0_4_6_10() \
+	LOAD_MSG_AVX2_Y12(13, 7, 12, 3); \
+	LOAD_MSG_AVX2_Y13(11, 14, 1, 9); \
+	LOAD_MSG_AVX2_Y14(5, 15, 8, 2);  \
+	VMOVQ_SI_X15_0;                  \
+	VMOVQ_SI_X11(6*8);               \
+	VPINSRQ_1_SI_X15(4*8);           \
+	VPINSRQ_1_SI_X11(10*8);          \
+	VINSERTI128 $1, X11, Y15, Y15
+
+#define LOAD_MSG_AVX2_6_14_11_0_15_9_3_8_12_13_1_10_2_7_4_5() \
+	VMOVQ_SI_X12(6*8);              \
+	VMOVQ_SI_X11(11*8);             \
+	VPINSRQ_1_SI_X12(14*8);         \
+	VPINSRQ_1_SI_X11_0;             \
+	VINSERTI128 $1, X11, Y12, Y12;  \
+	LOAD_MSG_AVX2_Y13(15, 9, 3, 8); \
+	VMOVQ_SI_X11(1*8);              \
+	VMOVDQU     12*8(SI), X14;      \
+	VPINSRQ_1_SI_X11(10*8);         \
+	VINSERTI128 $1, X11, Y14, Y14;  \
+	VMOVQ_SI_X15(2*8);              \
+	VMOVDQU     4*8(SI), X11;       \
+	VPINSRQ_1_SI_X15(7*8);          \
+	VINSERTI128 $1, X11, Y15, Y15
+
+#define LOAD_MSG_AVX2_10_8_7_1_2_4_6_5_15_9_3_13_11_14_12_0() \
+	LOAD_MSG_AVX2_Y12(10, 8, 7, 1);  \
+	VMOVQ_SI_X13(2*8);               \
+	VPSHUFD     $0x4E, 5*8(SI), X11; \
+	VPINSRQ_1_SI_X13(4*8);           \
+	VINSERTI128 $1, X11, Y13, Y13;   \
+	LOAD_MSG_AVX2_Y14(15, 9, 3, 13); \
+	VMOVQ_SI_X15(11*8);              \
+	VMOVQ_SI_X11(12*8);              \
+	VPINSRQ_1_SI_X15(14*8);          \
+	VPINSRQ_1_SI_X11_0;              \
+	VINSERTI128 $1, X11, Y15, Y15
+
+// func hashBlocksAVX2(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte)
+TEXT ·hashBlocksAVX2(SB), 4, $320-48 // frame size = 288 + 32 byte alignment
+	MOVQ h+0(FP), AX
+	MOVQ c+8(FP), BX
+	MOVQ flag+16(FP), CX
+	MOVQ blocks_base+24(FP), SI
+	MOVQ blocks_len+32(FP), DI
+
+	MOVQ SP, DX
+	ADDQ $31, DX
+	ANDQ $~31, DX
+
+	MOVQ CX, 16(DX)
+	XORQ CX, CX
+	MOVQ CX, 24(DX)
+
+	VMOVDQU ·AVX2_c40<>(SB), Y4
+	VMOVDQU ·AVX2_c48<>(SB), Y5
+
+	VMOVDQU 0(AX), Y8
+	VMOVDQU 32(AX), Y9
+	VMOVDQU ·AVX2_iv0<>(SB), Y6
+	VMOVDQU ·AVX2_iv1<>(SB), Y7
+
+	MOVQ 0(BX), R8
+	MOVQ 8(BX), R9
+	MOVQ R9, 8(DX)
+
+loop:
+	ADDQ $128, R8
+	MOVQ R8, 0(DX)
+	CMPQ R8, $128
+	JGE  noinc
+	INCQ R9
+	MOVQ R9, 8(DX)
+
+noinc:
+	VMOVDQA Y8, Y0
+	VMOVDQA Y9, Y1
+	VMOVDQA Y6, Y2
+	VPXOR   0(DX), Y7, Y3
+
+	LOAD_MSG_AVX2_0_2_4_6_1_3_5_7_8_10_12_14_9_11_13_15()
+	VMOVDQA Y12, 32(DX)
+	VMOVDQA Y13, 64(DX)
+	VMOVDQA Y14, 96(DX)
+	VMOVDQA Y15, 128(DX)
+	ROUND_AVX2(Y12, Y13, Y14, Y15, Y10, Y4, Y5)
+	LOAD_MSG_AVX2_14_4_9_13_10_8_15_6_1_0_11_5_12_2_7_3()
+	VMOVDQA Y12, 160(DX)
+	VMOVDQA Y13, 192(DX)
+	VMOVDQA Y14, 224(DX)
+	VMOVDQA Y15, 256(DX)
+
+	ROUND_AVX2(Y12, Y13, Y14, Y15, Y10, Y4, Y5)
+	LOAD_MSG_AVX2_11_12_5_15_8_0_2_13_10_3_7_9_14_6_1_4()
+	ROUND_AVX2(Y12, Y13, Y14, Y15, Y10, Y4, Y5)
+	LOAD_MSG_AVX2_7_3_13_11_9_1_12_14_2_5_4_15_6_10_0_8()
+	ROUND_AVX2(Y12, Y13, Y14, Y15, Y10, Y4, Y5)
+	LOAD_MSG_AVX2_9_5_2_10_0_7_4_15_14_11_6_3_1_12_8_13()
+	ROUND_AVX2(Y12, Y13, Y14, Y15, Y10, Y4, Y5)
+	LOAD_MSG_AVX2_2_6_0_8_12_10_11_3_4_7_15_1_13_5_14_9()
+	ROUND_AVX2(Y12, Y13, Y14, Y15, Y10, Y4, Y5)
+	LOAD_MSG_AVX2_12_1_14_4_5_15_13_10_0_6_9_8_7_3_2_11()
+	ROUND_AVX2(Y12, Y13, Y14, Y15, Y10, Y4, Y5)
+	LOAD_MSG_AVX2_13_7_12_3_11_14_1_9_5_15_8_2_0_4_6_10()
+	ROUND_AVX2(Y12, Y13, Y14, Y15, Y10, Y4, Y5)
+	LOAD_MSG_AVX2_6_14_11_0_15_9_3_8_12_13_1_10_2_7_4_5()
+	ROUND_AVX2(Y12, Y13, Y14, Y15, Y10, Y4, Y5)
+	LOAD_MSG_AVX2_10_8_7_1_2_4_6_5_15_9_3_13_11_14_12_0()
+	ROUND_AVX2(Y12, Y13, Y14, Y15, Y10, Y4, Y5)
+
+	ROUND_AVX2(32(DX), 64(DX), 96(DX), 128(DX), Y10, Y4, Y5)
+	ROUND_AVX2(160(DX), 192(DX), 224(DX), 256(DX), Y10, Y4, Y5)
+
+	VPXOR Y0, Y8, Y8
+	VPXOR Y1, Y9, Y9
+	VPXOR Y2, Y8, Y8
+	VPXOR Y3, Y9, Y9
+
+	LEAQ 128(SI), SI
+	SUBQ $128, DI
+	JNE  loop
+
+	MOVQ R8, 0(BX)
+	MOVQ R9, 8(BX)
+
+	VMOVDQU Y8, 0(AX)
+	VMOVDQU Y9, 32(AX)
+	VZEROUPPER
+
+	RET
+
+#define VPUNPCKLQDQ_X2_X2_X15 BYTE $0xC5; BYTE $0x69; BYTE $0x6C; BYTE $0xFA
+#define VPUNPCKLQDQ_X3_X3_X15 BYTE $0xC5; BYTE $0x61; BYTE $0x6C; BYTE $0xFB
+#define VPUNPCKLQDQ_X7_X7_X15 BYTE $0xC5; BYTE $0x41; BYTE $0x6C; BYTE $0xFF
+#define VPUNPCKLQDQ_X13_X13_X15 BYTE $0xC4; BYTE $0x41; BYTE $0x11; BYTE $0x6C; BYTE $0xFD
+#define VPUNPCKLQDQ_X14_X14_X15 BYTE $0xC4; BYTE $0x41; BYTE $0x09; BYTE $0x6C; BYTE $0xFE
+
+#define VPUNPCKHQDQ_X15_X2_X2 BYTE $0xC4; BYTE $0xC1; BYTE $0x69; BYTE $0x6D; BYTE $0xD7
+#define VPUNPCKHQDQ_X15_X3_X3 BYTE $0xC4; BYTE $0xC1; BYTE $0x61; BYTE $0x6D; BYTE $0xDF
+#define VPUNPCKHQDQ_X15_X6_X6 BYTE $0xC4; BYTE $0xC1; BYTE $0x49; BYTE $0x6D; BYTE $0xF7
+#define VPUNPCKHQDQ_X15_X7_X7 BYTE $0xC4; BYTE $0xC1; BYTE $0x41; BYTE $0x6D; BYTE $0xFF
+#define VPUNPCKHQDQ_X15_X3_X2 BYTE $0xC4; BYTE $0xC1; BYTE $0x61; BYTE $0x6D; BYTE $0xD7
+#define VPUNPCKHQDQ_X15_X7_X6 BYTE $0xC4; BYTE $0xC1; BYTE $0x41; BYTE $0x6D; BYTE $0xF7
+#define VPUNPCKHQDQ_X15_X13_X3 BYTE $0xC4; BYTE $0xC1; BYTE $0x11; BYTE $0x6D; BYTE $0xDF
+#define VPUNPCKHQDQ_X15_X13_X7 BYTE $0xC4; BYTE $0xC1; BYTE $0x11; BYTE $0x6D; BYTE $0xFF
+
+#define SHUFFLE_AVX() \
+	VMOVDQA X6, X13;         \
+	VMOVDQA X2, X14;         \
+	VMOVDQA X4, X6;          \
+	VPUNPCKLQDQ_X13_X13_X15; \
+	VMOVDQA X5, X4;          \
+	VMOVDQA X6, X5;          \
+	VPUNPCKHQDQ_X15_X7_X6;   \
+	VPUNPCKLQDQ_X7_X7_X15;   \
+	VPUNPCKHQDQ_X15_X13_X7;  \
+	VPUNPCKLQDQ_X3_X3_X15;   \
+	VPUNPCKHQDQ_X15_X2_X2;   \
+	VPUNPCKLQDQ_X14_X14_X15; \
+	VPUNPCKHQDQ_X15_X3_X3;   \
+
+#define SHUFFLE_AVX_INV() \
+	VMOVDQA X2, X13;         \
+	VMOVDQA X4, X14;         \
+	VPUNPCKLQDQ_X2_X2_X15;   \
+	VMOVDQA X5, X4;          \
+	VPUNPCKHQDQ_X15_X3_X2;   \
+	VMOVDQA X14, X5;         \
+	VPUNPCKLQDQ_X3_X3_X15;   \
+	VMOVDQA X6, X14;         \
+	VPUNPCKHQDQ_X15_X13_X3;  \
+	VPUNPCKLQDQ_X7_X7_X15;   \
+	VPUNPCKHQDQ_X15_X6_X6;   \
+	VPUNPCKLQDQ_X14_X14_X15; \
+	VPUNPCKHQDQ_X15_X7_X7;   \
+
+#define HALF_ROUND_AVX(v0, v1, v2, v3, v4, v5, v6, v7, m0, m1, m2, m3, t0, c40, c48) \
+	VPADDQ  m0, v0, v0;   \
+	VPADDQ  v2, v0, v0;   \
+	VPADDQ  m1, v1, v1;   \
+	VPADDQ  v3, v1, v1;   \
+	VPXOR   v0, v6, v6;   \
+	VPXOR   v1, v7, v7;   \
+	VPSHUFD $-79, v6, v6; \
+	VPSHUFD $-79, v7, v7; \
+	VPADDQ  v6, v4, v4;   \
+	VPADDQ  v7, v5, v5;   \
+	VPXOR   v4, v2, v2;   \
+	VPXOR   v5, v3, v3;   \
+	VPSHUFB c40, v2, v2;  \
+	VPSHUFB c40, v3, v3;  \
+	VPADDQ  m2, v0, v0;   \
+	VPADDQ  v2, v0, v0;   \
+	VPADDQ  m3, v1, v1;   \
+	VPADDQ  v3, v1, v1;   \
+	VPXOR   v0, v6, v6;   \
+	VPXOR   v1, v7, v7;   \
+	VPSHUFB c48, v6, v6;  \
+	VPSHUFB c48, v7, v7;  \
+	VPADDQ  v6, v4, v4;   \
+	VPADDQ  v7, v5, v5;   \
+	VPXOR   v4, v2, v2;   \
+	VPXOR   v5, v3, v3;   \
+	VPADDQ  v2, v2, t0;   \
+	VPSRLQ  $63, v2, v2;  \
+	VPXOR   t0, v2, v2;   \
+	VPADDQ  v3, v3, t0;   \
+	VPSRLQ  $63, v3, v3;  \
+	VPXOR   t0, v3, v3
+
+// load msg: X12 = (i0, i1), X13 = (i2, i3), X14 = (i4, i5), X15 = (i6, i7)
+// i0, i1, i2, i3, i4, i5, i6, i7 must not be 0
+#define LOAD_MSG_AVX(i0, i1, i2, i3, i4, i5, i6, i7) \
+	VMOVQ_SI_X12(i0*8);     \
+	VMOVQ_SI_X13(i2*8);     \
+	VMOVQ_SI_X14(i4*8);     \
+	VMOVQ_SI_X15(i6*8);     \
+	VPINSRQ_1_SI_X12(i1*8); \
+	VPINSRQ_1_SI_X13(i3*8); \
+	VPINSRQ_1_SI_X14(i5*8); \
+	VPINSRQ_1_SI_X15(i7*8)
+
+// load msg: X12 = (0, 2), X13 = (4, 6), X14 = (1, 3), X15 = (5, 7)
+#define LOAD_MSG_AVX_0_2_4_6_1_3_5_7() \
+	VMOVQ_SI_X12_0;        \
+	VMOVQ_SI_X13(4*8);     \
+	VMOVQ_SI_X14(1*8);     \
+	VMOVQ_SI_X15(5*8);     \
+	VPINSRQ_1_SI_X12(2*8); \
+	VPINSRQ_1_SI_X13(6*8); \
+	VPINSRQ_1_SI_X14(3*8); \
+	VPINSRQ_1_SI_X15(7*8)
+
+// load msg: X12 = (1, 0), X13 = (11, 5), X14 = (12, 2), X15 = (7, 3)
+#define LOAD_MSG_AVX_1_0_11_5_12_2_7_3() \
+	VPSHUFD $0x4E, 0*8(SI), X12; \
+	VMOVQ_SI_X13(11*8);          \
+	VMOVQ_SI_X14(12*8);          \
+	VMOVQ_SI_X15(7*8);           \
+	VPINSRQ_1_SI_X13(5*8);       \
+	VPINSRQ_1_SI_X14(2*8);       \
+	VPINSRQ_1_SI_X15(3*8)
+
+// load msg: X12 = (11, 12), X13 = (5, 15), X14 = (8, 0), X15 = (2, 13)
+#define LOAD_MSG_AVX_11_12_5_15_8_0_2_13() \
+	VMOVDQU 11*8(SI), X12;  \
+	VMOVQ_SI_X13(5*8);      \
+	VMOVQ_SI_X14(8*8);      \
+	VMOVQ_SI_X15(2*8);      \
+	VPINSRQ_1_SI_X13(15*8); \
+	VPINSRQ_1_SI_X14_0;     \
+	VPINSRQ_1_SI_X15(13*8)
+
+// load msg: X12 = (2, 5), X13 = (4, 15), X14 = (6, 10), X15 = (0, 8)
+#define LOAD_MSG_AVX_2_5_4_15_6_10_0_8() \
+	VMOVQ_SI_X12(2*8);      \
+	VMOVQ_SI_X13(4*8);      \
+	VMOVQ_SI_X14(6*8);      \
+	VMOVQ_SI_X15_0;         \
+	VPINSRQ_1_SI_X12(5*8);  \
+	VPINSRQ_1_SI_X13(15*8); \
+	VPINSRQ_1_SI_X14(10*8); \
+	VPINSRQ_1_SI_X15(8*8)
+
+// load msg: X12 = (9, 5), X13 = (2, 10), X14 = (0, 7), X15 = (4, 15)
+#define LOAD_MSG_AVX_9_5_2_10_0_7_4_15() \
+	VMOVQ_SI_X12(9*8);      \
+	VMOVQ_SI_X13(2*8);      \
+	VMOVQ_SI_X14_0;         \
+	VMOVQ_SI_X15(4*8);      \
+	VPINSRQ_1_SI_X12(5*8);  \
+	VPINSRQ_1_SI_X13(10*8); \
+	VPINSRQ_1_SI_X14(7*8);  \
+	VPINSRQ_1_SI_X15(15*8)
+
+// load msg: X12 = (2, 6), X13 = (0, 8), X14 = (12, 10), X15 = (11, 3)
+#define LOAD_MSG_AVX_2_6_0_8_12_10_11_3() \
+	VMOVQ_SI_X12(2*8);      \
+	VMOVQ_SI_X13_0;         \
+	VMOVQ_SI_X14(12*8);     \
+	VMOVQ_SI_X15(11*8);     \
+	VPINSRQ_1_SI_X12(6*8);  \
+	VPINSRQ_1_SI_X13(8*8);  \
+	VPINSRQ_1_SI_X14(10*8); \
+	VPINSRQ_1_SI_X15(3*8)
+
+// load msg: X12 = (0, 6), X13 = (9, 8), X14 = (7, 3), X15 = (2, 11)
+#define LOAD_MSG_AVX_0_6_9_8_7_3_2_11() \
+	MOVQ    0*8(SI), X12;        \
+	VPSHUFD $0x4E, 8*8(SI), X13; \
+	MOVQ    7*8(SI), X14;        \
+	MOVQ    2*8(SI), X15;        \
+	VPINSRQ_1_SI_X12(6*8);       \
+	VPINSRQ_1_SI_X14(3*8);       \
+	VPINSRQ_1_SI_X15(11*8)
+
+// load msg: X12 = (6, 14), X13 = (11, 0), X14 = (15, 9), X15 = (3, 8)
+#define LOAD_MSG_AVX_6_14_11_0_15_9_3_8() \
+	MOVQ 6*8(SI), X12;      \
+	MOVQ 11*8(SI), X13;     \
+	MOVQ 15*8(SI), X14;     \
+	MOVQ 3*8(SI), X15;      \
+	VPINSRQ_1_SI_X12(14*8); \
+	VPINSRQ_1_SI_X13_0;     \
+	VPINSRQ_1_SI_X14(9*8);  \
+	VPINSRQ_1_SI_X15(8*8)
+
+// load msg: X12 = (5, 15), X13 = (8, 2), X14 = (0, 4), X15 = (6, 10)
+#define LOAD_MSG_AVX_5_15_8_2_0_4_6_10() \
+	MOVQ 5*8(SI), X12;      \
+	MOVQ 8*8(SI), X13;      \
+	MOVQ 0*8(SI), X14;      \
+	MOVQ 6*8(SI), X15;      \
+	VPINSRQ_1_SI_X12(15*8); \
+	VPINSRQ_1_SI_X13(2*8);  \
+	VPINSRQ_1_SI_X14(4*8);  \
+	VPINSRQ_1_SI_X15(10*8)
+
+// load msg: X12 = (12, 13), X13 = (1, 10), X14 = (2, 7), X15 = (4, 5)
+#define LOAD_MSG_AVX_12_13_1_10_2_7_4_5() \
+	VMOVDQU 12*8(SI), X12;  \
+	MOVQ    1*8(SI), X13;   \
+	MOVQ    2*8(SI), X14;   \
+	VPINSRQ_1_SI_X13(10*8); \
+	VPINSRQ_1_SI_X14(7*8);  \
+	VMOVDQU 4*8(SI), X15
+
+// load msg: X12 = (15, 9), X13 = (3, 13), X14 = (11, 14), X15 = (12, 0)
+#define LOAD_MSG_AVX_15_9_3_13_11_14_12_0() \
+	MOVQ 15*8(SI), X12;     \
+	MOVQ 3*8(SI), X13;      \
+	MOVQ 11*8(SI), X14;     \
+	MOVQ 12*8(SI), X15;     \
+	VPINSRQ_1_SI_X12(9*8);  \
+	VPINSRQ_1_SI_X13(13*8); \
+	VPINSRQ_1_SI_X14(14*8); \
+	VPINSRQ_1_SI_X15_0
+
+// func hashBlocksAVX(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte)
+TEXT ·hashBlocksAVX(SB), 4, $288-48 // frame size = 272 + 16 byte alignment
+	MOVQ h+0(FP), AX
+	MOVQ c+8(FP), BX
+	MOVQ flag+16(FP), CX
+	MOVQ blocks_base+24(FP), SI
+	MOVQ blocks_len+32(FP), DI
+
+	MOVQ SP, R10
+	ADDQ $15, R10
+	ANDQ $~15, R10
+
+	VMOVDQU ·AVX_c40<>(SB), X0
+	VMOVDQU ·AVX_c48<>(SB), X1
+	VMOVDQA X0, X8
+	VMOVDQA X1, X9
+
+	VMOVDQU ·AVX_iv3<>(SB), X0
+	VMOVDQA X0, 0(R10)
+	XORQ    CX, 0(R10)          // 0(R10) = ·AVX_iv3 ^ (CX || 0)
+
+	VMOVDQU 0(AX), X10
+	VMOVDQU 16(AX), X11
+	VMOVDQU 32(AX), X2
+	VMOVDQU 48(AX), X3
+
+	MOVQ 0(BX), R8
+	MOVQ 8(BX), R9
+
+loop:
+	ADDQ $128, R8
+	CMPQ R8, $128
+	JGE  noinc
+	INCQ R9
+
+noinc:
+	VMOVQ_R8_X15
+	VPINSRQ_1_R9_X15
+
+	VMOVDQA X10, X0
+	VMOVDQA X11, X1
+	VMOVDQU ·AVX_iv0<>(SB), X4
+	VMOVDQU ·AVX_iv1<>(SB), X5
+	VMOVDQU ·AVX_iv2<>(SB), X6
+
+	VPXOR   X15, X6, X6
+	VMOVDQA 0(R10), X7
+
+	LOAD_MSG_AVX_0_2_4_6_1_3_5_7()
+	VMOVDQA X12, 16(R10)
+	VMOVDQA X13, 32(R10)
+	VMOVDQA X14, 48(R10)
+	VMOVDQA X15, 64(R10)
+	HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
+	SHUFFLE_AVX()
+	LOAD_MSG_AVX(8, 10, 12, 14, 9, 11, 13, 15)
+	VMOVDQA X12, 80(R10)
+	VMOVDQA X13, 96(R10)
+	VMOVDQA X14, 112(R10)
+	VMOVDQA X15, 128(R10)
+	HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
+	SHUFFLE_AVX_INV()
+
+	LOAD_MSG_AVX(14, 4, 9, 13, 10, 8, 15, 6)
+	VMOVDQA X12, 144(R10)
+	VMOVDQA X13, 160(R10)
+	VMOVDQA X14, 176(R10)
+	VMOVDQA X15, 192(R10)
+	HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
+	SHUFFLE_AVX()
+	LOAD_MSG_AVX_1_0_11_5_12_2_7_3()
+	VMOVDQA X12, 208(R10)
+	VMOVDQA X13, 224(R10)
+	VMOVDQA X14, 240(R10)
+	VMOVDQA X15, 256(R10)
+	HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
+	SHUFFLE_AVX_INV()
+
+	LOAD_MSG_AVX_11_12_5_15_8_0_2_13()
+	HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
+	SHUFFLE_AVX()
+	LOAD_MSG_AVX(10, 3, 7, 9, 14, 6, 1, 4)
+	HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
+	SHUFFLE_AVX_INV()
+
+	LOAD_MSG_AVX(7, 3, 13, 11, 9, 1, 12, 14)
+	HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
+	SHUFFLE_AVX()
+	LOAD_MSG_AVX_2_5_4_15_6_10_0_8()
+	HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
+	SHUFFLE_AVX_INV()
+
+	LOAD_MSG_AVX_9_5_2_10_0_7_4_15()
+	HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
+	SHUFFLE_AVX()
+	LOAD_MSG_AVX(14, 11, 6, 3, 1, 12, 8, 13)
+	HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
+	SHUFFLE_AVX_INV()
+
+	LOAD_MSG_AVX_2_6_0_8_12_10_11_3()
+	HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
+	SHUFFLE_AVX()
+	LOAD_MSG_AVX(4, 7, 15, 1, 13, 5, 14, 9)
+	HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
+	SHUFFLE_AVX_INV()
+
+	LOAD_MSG_AVX(12, 1, 14, 4, 5, 15, 13, 10)
+	HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
+	SHUFFLE_AVX()
+	LOAD_MSG_AVX_0_6_9_8_7_3_2_11()
+	HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
+	SHUFFLE_AVX_INV()
+
+	LOAD_MSG_AVX(13, 7, 12, 3, 11, 14, 1, 9)
+	HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
+	SHUFFLE_AVX()
+	LOAD_MSG_AVX_5_15_8_2_0_4_6_10()
+	HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
+	SHUFFLE_AVX_INV()
+
+	LOAD_MSG_AVX_6_14_11_0_15_9_3_8()
+	HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
+	SHUFFLE_AVX()
+	LOAD_MSG_AVX_12_13_1_10_2_7_4_5()
+	HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
+	SHUFFLE_AVX_INV()
+
+	LOAD_MSG_AVX(10, 8, 7, 1, 2, 4, 6, 5)
+	HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
+	SHUFFLE_AVX()
+	LOAD_MSG_AVX_15_9_3_13_11_14_12_0()
+	HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
+	SHUFFLE_AVX_INV()
+
+	HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, 16(R10), 32(R10), 48(R10), 64(R10), X15, X8, X9)
+	SHUFFLE_AVX()
+	HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, 80(R10), 96(R10), 112(R10), 128(R10), X15, X8, X9)
+	SHUFFLE_AVX_INV()
+
+	HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, 144(R10), 160(R10), 176(R10), 192(R10), X15, X8, X9)
+	SHUFFLE_AVX()
+	HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, 208(R10), 224(R10), 240(R10), 256(R10), X15, X8, X9)
+	SHUFFLE_AVX_INV()
+
+	VMOVDQU 32(AX), X14
+	VMOVDQU 48(AX), X15
+	VPXOR   X0, X10, X10
+	VPXOR   X1, X11, X11
+	VPXOR   X2, X14, X14
+	VPXOR   X3, X15, X15
+	VPXOR   X4, X10, X10
+	VPXOR   X5, X11, X11
+	VPXOR   X6, X14, X2
+	VPXOR   X7, X15, X3
+	VMOVDQU X2, 32(AX)
+	VMOVDQU X3, 48(AX)
+
+	LEAQ 128(SI), SI
+	SUBQ $128, DI
+	JNE  loop
+
+	VMOVDQU X10, 0(AX)
+	VMOVDQU X11, 16(AX)
+
+	MOVQ R8, 0(BX)
+	MOVQ R9, 8(BX)
+	VZEROUPPER
+
+	RET
diff --git a/vendor/golang.org/x/crypto/blake2b/blake2b_amd64.go b/vendor/golang.org/x/crypto/blake2b/blake2b_amd64.go
new file mode 100644
index 0000000000..5fa1b32841
--- /dev/null
+++ b/vendor/golang.org/x/crypto/blake2b/blake2b_amd64.go
@@ -0,0 +1,25 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !go1.7 && amd64 && gc && !purego
+// +build !go1.7,amd64,gc,!purego
+
+package blake2b
+
+import "golang.org/x/sys/cpu"
+
+func init() {
+	useSSE4 = cpu.X86.HasSSE41
+}
+
+//go:noescape
+func hashBlocksSSE4(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte)
+
+func hashBlocks(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte) {
+	if useSSE4 {
+		hashBlocksSSE4(h, c, flag, blocks)
+	} else {
+		hashBlocksGeneric(h, c, flag, blocks)
+	}
+}
diff --git a/vendor/golang.org/x/crypto/blake2b/blake2b_amd64.s b/vendor/golang.org/x/crypto/blake2b/blake2b_amd64.s
new file mode 100644
index 0000000000..ae75eb9afc
--- /dev/null
+++ b/vendor/golang.org/x/crypto/blake2b/blake2b_amd64.s
@@ -0,0 +1,279 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build amd64 && gc && !purego
+// +build amd64,gc,!purego
+
+#include "textflag.h"
+
+DATA ·iv0<>+0x00(SB)/8, $0x6a09e667f3bcc908
+DATA ·iv0<>+0x08(SB)/8, $0xbb67ae8584caa73b
+GLOBL ·iv0<>(SB), (NOPTR+RODATA), $16
+
+DATA ·iv1<>+0x00(SB)/8, $0x3c6ef372fe94f82b
+DATA ·iv1<>+0x08(SB)/8, $0xa54ff53a5f1d36f1
+GLOBL ·iv1<>(SB), (NOPTR+RODATA), $16
+
+DATA ·iv2<>+0x00(SB)/8, $0x510e527fade682d1
+DATA ·iv2<>+0x08(SB)/8, $0x9b05688c2b3e6c1f
+GLOBL ·iv2<>(SB), (NOPTR+RODATA), $16
+
+DATA ·iv3<>+0x00(SB)/8, $0x1f83d9abfb41bd6b
+DATA ·iv3<>+0x08(SB)/8, $0x5be0cd19137e2179
+GLOBL ·iv3<>(SB), (NOPTR+RODATA), $16
+
+DATA ·c40<>+0x00(SB)/8, $0x0201000706050403
+DATA ·c40<>+0x08(SB)/8, $0x0a09080f0e0d0c0b
+GLOBL ·c40<>(SB), (NOPTR+RODATA), $16
+
+DATA ·c48<>+0x00(SB)/8, $0x0100070605040302
+DATA ·c48<>+0x08(SB)/8, $0x09080f0e0d0c0b0a
+GLOBL ·c48<>(SB), (NOPTR+RODATA), $16
+
+#define SHUFFLE(v2, v3, v4, v5, v6, v7, t1, t2) \
+	MOVO       v4, t1; \
+	MOVO       v5, v4; \
+	MOVO       t1, v5; \
+	MOVO       v6, t1; \
+	PUNPCKLQDQ v6, t2; \
+	PUNPCKHQDQ v7, v6; \
+	PUNPCKHQDQ t2, v6; \
+	PUNPCKLQDQ v7, t2; \
+	MOVO       t1, v7; \
+	MOVO       v2, t1; \
+	PUNPCKHQDQ t2, v7; \
+	PUNPCKLQDQ v3, t2; \
+	PUNPCKHQDQ t2, v2; \
+	PUNPCKLQDQ t1, t2; \
+	PUNPCKHQDQ t2, v3
+
+#define SHUFFLE_INV(v2, v3, v4, v5, v6, v7, t1, t2) \
+	MOVO       v4, t1; \
+	MOVO       v5, v4; \
+	MOVO       t1, v5; \
+	MOVO       v2, t1; \
+	PUNPCKLQDQ v2, t2; \
+	PUNPCKHQDQ v3, v2; \
+	PUNPCKHQDQ t2, v2; \
+	PUNPCKLQDQ v3, t2; \
+	MOVO       t1, v3; \
+	MOVO       v6, t1; \
+	PUNPCKHQDQ t2, v3; \
+	PUNPCKLQDQ v7, t2; \
+	PUNPCKHQDQ t2, v6; \
+	PUNPCKLQDQ t1, t2; \
+	PUNPCKHQDQ t2, v7
+
+#define HALF_ROUND(v0, v1, v2, v3, v4, v5, v6, v7, m0, m1, m2, m3, t0, c40, c48) \
+	PADDQ  m0, v0;        \
+	PADDQ  m1, v1;        \
+	PADDQ  v2, v0;        \
+	PADDQ  v3, v1;        \
+	PXOR   v0, v6;        \
+	PXOR   v1, v7;        \
+	PSHUFD $0xB1, v6, v6; \
+	PSHUFD $0xB1, v7, v7; \
+	PADDQ  v6, v4;        \
+	PADDQ  v7, v5;        \
+	PXOR   v4, v2;        \
+	PXOR   v5, v3;        \
+	PSHUFB c40, v2;       \
+	PSHUFB c40, v3;       \
+	PADDQ  m2, v0;        \
+	PADDQ  m3, v1;        \
+	PADDQ  v2, v0;        \
+	PADDQ  v3, v1;        \
+	PXOR   v0, v6;        \
+	PXOR   v1, v7;        \
+	PSHUFB c48, v6;       \
+	PSHUFB c48, v7;       \
+	PADDQ  v6, v4;        \
+	PADDQ  v7, v5;        \
+	PXOR   v4, v2;        \
+	PXOR   v5, v3;        \
+	MOVOU  v2, t0;        \
+	PADDQ  v2, t0;        \
+	PSRLQ  $63, v2;       \
+	PXOR   t0, v2;        \
+	MOVOU  v3, t0;        \
+	PADDQ  v3, t0;        \
+	PSRLQ  $63, v3;       \
+	PXOR   t0, v3
+
+#define LOAD_MSG(m0, m1, m2, m3, src, i0, i1, i2, i3, i4, i5, i6, i7) \
+	MOVQ   i0*8(src), m0;     \
+	PINSRQ $1, i1*8(src), m0; \
+	MOVQ   i2*8(src), m1;     \
+	PINSRQ $1, i3*8(src), m1; \
+	MOVQ   i4*8(src), m2;     \
+	PINSRQ $1, i5*8(src), m2; \
+	MOVQ   i6*8(src), m3;     \
+	PINSRQ $1, i7*8(src), m3
+
+// func hashBlocksSSE4(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte)
+TEXT ·hashBlocksSSE4(SB), 4, $288-48 // frame size = 272 + 16 byte alignment
+	MOVQ h+0(FP), AX
+	MOVQ c+8(FP), BX
+	MOVQ flag+16(FP), CX
+	MOVQ blocks_base+24(FP), SI
+	MOVQ blocks_len+32(FP), DI
+
+	MOVQ SP, R10
+	ADDQ $15, R10
+	ANDQ $~15, R10
+
+	MOVOU ·iv3<>(SB), X0
+	MOVO  X0, 0(R10)
+	XORQ  CX, 0(R10)     // 0(R10) = ·iv3 ^ (CX || 0)
+
+	MOVOU ·c40<>(SB), X13
+	MOVOU ·c48<>(SB), X14
+
+	MOVOU 0(AX), X12
+	MOVOU 16(AX), X15
+
+	MOVQ 0(BX), R8
+	MOVQ 8(BX), R9
+
+loop:
+	ADDQ $128, R8
+	CMPQ R8, $128
+	JGE  noinc
+	INCQ R9
+
+noinc:
+	MOVQ R8, X8
+	PINSRQ $1, R9, X8
+
+	MOVO X12, X0
+	MOVO X15, X1
+	MOVOU 32(AX), X2
+	MOVOU 48(AX), X3
+	MOVOU ·iv0<>(SB), X4
+	MOVOU ·iv1<>(SB), X5
+	MOVOU ·iv2<>(SB), X6
+
+	PXOR X8, X6
+	MOVO 0(R10), X7
+
+	LOAD_MSG(X8, X9, X10, X11, SI, 0, 2, 4, 6, 1, 3, 5, 7)
+	MOVO X8, 16(R10)
+	MOVO X9, 32(R10)
+	MOVO X10, 48(R10)
+	MOVO X11, 64(R10)
+	HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
+	SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9)
+	LOAD_MSG(X8, X9, X10, X11, SI, 8, 10, 12, 14, 9, 11, 13, 15)
+	MOVO X8, 80(R10)
+	MOVO X9, 96(R10)
+	MOVO X10, 112(R10)
+	MOVO X11, 128(R10)
+	HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
+	SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9)
+
+	LOAD_MSG(X8, X9, X10, X11, SI, 14, 4, 9, 13, 10, 8, 15, 6)
+	MOVO X8, 144(R10)
+	MOVO X9, 160(R10)
+	MOVO X10, 176(R10)
+	MOVO X11, 192(R10)
+	HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
+	SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9)
+	LOAD_MSG(X8, X9, X10, X11, SI, 1, 0, 11, 5, 12, 2, 7, 3)
+	MOVO X8, 208(R10)
+	MOVO X9, 224(R10)
+	MOVO X10, 240(R10)
+	MOVO X11, 256(R10)
+	HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
+	SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9)
+
+	LOAD_MSG(X8, X9, X10, X11, SI, 11, 12, 5, 15, 8, 0, 2, 13)
+	HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
+	SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9)
+	LOAD_MSG(X8, X9, X10, X11, SI, 10, 3, 7, 9, 14, 6, 1, 4)
+	HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
+	SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9)
+
+	LOAD_MSG(X8, X9, X10, X11, SI, 7, 3, 13, 11, 9, 1, 12, 14)
+	HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
+	SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9)
+	LOAD_MSG(X8, X9, X10, X11, SI, 2, 5, 4, 15, 6, 10, 0, 8)
+	HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
+	SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9)
+
+	LOAD_MSG(X8, X9, X10, X11, SI, 9, 5, 2, 10, 0, 7, 4, 15)
+	HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
+	SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9)
+	LOAD_MSG(X8, X9, X10, X11, SI, 14, 11, 6, 3, 1, 12, 8, 13)
+	HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
+	SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9)
+
+	LOAD_MSG(X8, X9, X10, X11, SI, 2, 6, 0, 8, 12, 10, 11, 3)
+	HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
+	SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9)
+	LOAD_MSG(X8, X9, X10, X11, SI, 4, 7, 15, 1, 13, 5, 14, 9)
+	HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
+	SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9)
+
+	LOAD_MSG(X8, X9, X10, X11, SI, 12, 1, 14, 4, 5, 15, 13, 10)
+	HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
+	SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9)
+	LOAD_MSG(X8, X9, X10, X11, SI, 0, 6, 9, 8, 7, 3, 2, 11)
+	HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
+	SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9)
+
+	LOAD_MSG(X8, X9, X10, X11, SI, 13, 7, 12, 3, 11, 14, 1, 9)
+	HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
+	SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9)
+	LOAD_MSG(X8, X9, X10, X11, SI, 5, 15, 8, 2, 0, 4, 6, 10)
+	HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
+	SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9)
+
+	LOAD_MSG(X8, X9, X10, X11, SI, 6, 14, 11, 0, 15, 9, 3, 8)
+	HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
+	SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9)
+	LOAD_MSG(X8, X9, X10, X11, SI, 12, 13, 1, 10, 2, 7, 4, 5)
+	HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
+	SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9)
+
+	LOAD_MSG(X8, X9, X10, X11, SI, 10, 8, 7, 1, 2, 4, 6, 5)
+	HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
+	SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9)
+	LOAD_MSG(X8, X9, X10, X11, SI, 15, 9, 3, 13, 11, 14, 12, 0)
+	HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
+	SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9)
+
+	HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, 16(R10), 32(R10), 48(R10), 64(R10), X11, X13, X14)
+	SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9)
+	HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, 80(R10), 96(R10), 112(R10), 128(R10), X11, X13, X14)
+	SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9)
+
+	HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, 144(R10), 160(R10), 176(R10), 192(R10), X11, X13, X14)
+	SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9)
+	HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, 208(R10), 224(R10), 240(R10), 256(R10), X11, X13, X14)
+	SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9)
+
+	MOVOU 32(AX), X10
+	MOVOU 48(AX), X11
+	PXOR  X0, X12
+	PXOR  X1, X15
+	PXOR  X2, X10
+	PXOR  X3, X11
+	PXOR  X4, X12
+	PXOR  X5, X15
+	PXOR  X6, X10
+	PXOR  X7, X11
+	MOVOU X10, 32(AX)
+	MOVOU X11, 48(AX)
+
+	LEAQ 128(SI), SI
+	SUBQ $128, DI
+	JNE  loop
+
+	MOVOU X12, 0(AX)
+	MOVOU X15, 16(AX)
+
+	MOVQ R8, 0(BX)
+	MOVQ R9, 8(BX)
+
+	RET
diff --git a/vendor/golang.org/x/crypto/blake2b/blake2b_generic.go b/vendor/golang.org/x/crypto/blake2b/blake2b_generic.go
new file mode 100644
index 0000000000..3168a8aa3c
--- /dev/null
+++ b/vendor/golang.org/x/crypto/blake2b/blake2b_generic.go
@@ -0,0 +1,182 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package blake2b
+
+import (
+	"encoding/binary"
+	"math/bits"
+)
+
+// the precomputed values for BLAKE2b
+// there are 12 16-byte arrays - one for each round
+// the entries are calculated from the sigma constants.
+var precomputed = [12][16]byte{
+	{0, 2, 4, 6, 1, 3, 5, 7, 8, 10, 12, 14, 9, 11, 13, 15},
+	{14, 4, 9, 13, 10, 8, 15, 6, 1, 0, 11, 5, 12, 2, 7, 3},
+	{11, 12, 5, 15, 8, 0, 2, 13, 10, 3, 7, 9, 14, 6, 1, 4},
+	{7, 3, 13, 11, 9, 1, 12, 14, 2, 5, 4, 15, 6, 10, 0, 8},
+	{9, 5, 2, 10, 0, 7, 4, 15, 14, 11, 6, 3, 1, 12, 8, 13},
+	{2, 6, 0, 8, 12, 10, 11, 3, 4, 7, 15, 1, 13, 5, 14, 9},
+	{12, 1, 14, 4, 5, 15, 13, 10, 0, 6, 9, 8, 7, 3, 2, 11},
+	{13, 7, 12, 3, 11, 14, 1, 9, 5, 15, 8, 2, 0, 4, 6, 10},
+	{6, 14, 11, 0, 15, 9, 3, 8, 12, 13, 1, 10, 2, 7, 4, 5},
+	{10, 8, 7, 1, 2, 4, 6, 5, 15, 9, 3, 13, 11, 14, 12, 0},
+	{0, 2, 4, 6, 1, 3, 5, 7, 8, 10, 12, 14, 9, 11, 13, 15}, // equal to the first
+	{14, 4, 9, 13, 10, 8, 15, 6, 1, 0, 11, 5, 12, 2, 7, 3}, // equal to the second
+}
+
+func hashBlocksGeneric(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte) {
+	var m [16]uint64
+	c0, c1 := c[0], c[1]
+
+	for i := 0; i < len(blocks); {
+		c0 += BlockSize
+		if c0 < BlockSize {
+			c1++
+		}
+
+		v0, v1, v2, v3, v4, v5, v6, v7 := h[0], h[1], h[2], h[3], h[4], h[5], h[6], h[7]
+		v8, v9, v10, v11, v12, v13, v14, v15 := iv[0], iv[1], iv[2], iv[3], iv[4], iv[5], iv[6], iv[7]
+		v12 ^= c0
+		v13 ^= c1
+		v14 ^= flag
+
+		for j := range m {
+			m[j] = binary.LittleEndian.Uint64(blocks[i:])
+			i += 8
+		}
+
+		for j := range precomputed {
+			s := &(precomputed[j])
+
+			v0 += m[s[0]]
+			v0 += v4
+			v12 ^= v0
+			v12 = bits.RotateLeft64(v12, -32)
+			v8 += v12
+			v4 ^= v8
+			v4 = bits.RotateLeft64(v4, -24)
+			v1 += m[s[1]]
+			v1 += v5
+			v13 ^= v1
+			v13 = bits.RotateLeft64(v13, -32)
+			v9 += v13
+			v5 ^= v9
+			v5 = bits.RotateLeft64(v5, -24)
+			v2 += m[s[2]]
+			v2 += v6
+			v14 ^= v2
+			v14 = bits.RotateLeft64(v14, -32)
+			v10 += v14
+			v6 ^= v10
+			v6 = bits.RotateLeft64(v6, -24)
+			v3 += m[s[3]]
+			v3 += v7
+			v15 ^= v3
+			v15 = bits.RotateLeft64(v15, -32)
+			v11 += v15
+			v7 ^= v11
+			v7 = bits.RotateLeft64(v7, -24)
+
+			v0 += m[s[4]]
+			v0 += v4
+			v12 ^= v0
+			v12 = bits.RotateLeft64(v12, -16)
+			v8 += v12
+			v4 ^= v8
+			v4 = bits.RotateLeft64(v4, -63)
+			v1 += m[s[5]]
+			v1 += v5
+			v13 ^= v1
+			v13 = bits.RotateLeft64(v13, -16)
+			v9 += v13
+			v5 ^= v9
+			v5 = bits.RotateLeft64(v5, -63)
+			v2 += m[s[6]]
+			v2 += v6
+			v14 ^= v2
+			v14 = bits.RotateLeft64(v14, -16)
+			v10 += v14
+			v6 ^= v10
+			v6 = bits.RotateLeft64(v6, -63)
+			v3 += m[s[7]]
+			v3 += v7
+			v15 ^= v3
+			v15 = bits.RotateLeft64(v15, -16)
+			v11 += v15
+			v7 ^= v11
+			v7 = bits.RotateLeft64(v7, -63)
+
+			v0 += m[s[8]]
+			v0 += v5
+			v15 ^= v0
+			v15 = bits.RotateLeft64(v15, -32)
+			v10 += v15
+			v5 ^= v10
+			v5 = bits.RotateLeft64(v5, -24)
+			v1 += m[s[9]]
+			v1 += v6
+			v12 ^= v1
+			v12 = bits.RotateLeft64(v12, -32)
+			v11 += v12
+			v6 ^= v11
+			v6 = bits.RotateLeft64(v6, -24)
+			v2 += m[s[10]]
+			v2 += v7
+			v13 ^= v2
+			v13 = bits.RotateLeft64(v13, -32)
+			v8 += v13
+			v7 ^= v8
+			v7 = bits.RotateLeft64(v7, -24)
+			v3 += m[s[11]]
+			v3 += v4
+			v14 ^= v3
+			v14 = bits.RotateLeft64(v14, -32)
+			v9 += v14
+			v4 ^= v9
+			v4 = bits.RotateLeft64(v4, -24)
+
+			v0 += m[s[12]]
+			v0 += v5
+			v15 ^= v0
+			v15 = bits.RotateLeft64(v15, -16)
+			v10 += v15
+			v5 ^= v10
+			v5 = bits.RotateLeft64(v5, -63)
+			v1 += m[s[13]]
+			v1 += v6
+			v12 ^= v1
+			v12 = bits.RotateLeft64(v12, -16)
+			v11 += v12
+			v6 ^= v11
+			v6 = bits.RotateLeft64(v6, -63)
+			v2 += m[s[14]]
+			v2 += v7
+			v13 ^= v2
+			v13 = bits.RotateLeft64(v13, -16)
+			v8 += v13
+			v7 ^= v8
+			v7 = bits.RotateLeft64(v7, -63)
+			v3 += m[s[15]]
+			v3 += v4
+			v14 ^= v3
+			v14 = bits.RotateLeft64(v14, -16)
+			v9 += v14
+			v4 ^= v9
+			v4 = bits.RotateLeft64(v4, -63)
+
+		}
+
+		h[0] ^= v0 ^ v8
+		h[1] ^= v1 ^ v9
+		h[2] ^= v2 ^ v10
+		h[3] ^= v3 ^ v11
+		h[4] ^= v4 ^ v12
+		h[5] ^= v5 ^ v13
+		h[6] ^= v6 ^ v14
+		h[7] ^= v7 ^ v15
+	}
+	c[0], c[1] = c0, c1
+}
diff --git a/vendor/golang.org/x/crypto/blake2b/blake2b_ref.go b/vendor/golang.org/x/crypto/blake2b/blake2b_ref.go
new file mode 100644
index 0000000000..b0137cdf02
--- /dev/null
+++ b/vendor/golang.org/x/crypto/blake2b/blake2b_ref.go
@@ -0,0 +1,12 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !amd64 || purego || !gc
+// +build !amd64 purego !gc
+
+package blake2b
+
+func hashBlocks(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte) {
+	hashBlocksGeneric(h, c, flag, blocks)
+}
diff --git a/vendor/golang.org/x/crypto/blake2b/blake2x.go b/vendor/golang.org/x/crypto/blake2b/blake2x.go
new file mode 100644
index 0000000000..52c414db0e
--- /dev/null
+++ b/vendor/golang.org/x/crypto/blake2b/blake2x.go
@@ -0,0 +1,177 @@
+// Copyright 2017 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 blake2b
+
+import (
+	"encoding/binary"
+	"errors"
+	"io"
+)
+
+// XOF defines the interface to hash functions that
+// support arbitrary-length output.
+type XOF interface {
+	// Write absorbs more data into the hash's state. It panics if called
+	// after Read.
+	io.Writer
+
+	// Read reads more output from the hash. It returns io.EOF if the limit
+	// has been reached.
+	io.Reader
+
+	// Clone returns a copy of the XOF in its current state.
+	Clone() XOF
+
+	// Reset resets the XOF to its initial state.
+	Reset()
+}
+
+// OutputLengthUnknown can be used as the size argument to NewXOF to indicate
+// the length of the output is not known in advance.
+const OutputLengthUnknown = 0
+
+// magicUnknownOutputLength is a magic value for the output size that indicates
+// an unknown number of output bytes.
+const magicUnknownOutputLength = (1 << 32) - 1
+
+// maxOutputLength is the absolute maximum number of bytes to produce when the
+// number of output bytes is unknown.
+const maxOutputLength = (1 << 32) * 64
+
+// NewXOF creates a new variable-output-length hash. The hash either produce a
+// known number of bytes (1 <= size < 2**32-1), or an unknown number of bytes
+// (size == OutputLengthUnknown). In the latter case, an absolute limit of
+// 256GiB applies.
+//
+// A non-nil key turns the hash into a MAC. The key must between
+// zero and 32 bytes long.
+func NewXOF(size uint32, key []byte) (XOF, error) {
+	if len(key) > Size {
+		return nil, errKeySize
+	}
+	if size == magicUnknownOutputLength {
+		// 2^32-1 indicates an unknown number of bytes and thus isn't a
+		// valid length.
+		return nil, errors.New("blake2b: XOF length too large")
+	}
+	if size == OutputLengthUnknown {
+		size = magicUnknownOutputLength
+	}
+	x := &xof{
+		d: digest{
+			size:   Size,
+			keyLen: len(key),
+		},
+		length: size,
+	}
+	copy(x.d.key[:], key)
+	x.Reset()
+	return x, nil
+}
+
+type xof struct {
+	d                digest
+	length           uint32
+	remaining        uint64
+	cfg, root, block [Size]byte
+	offset           int
+	nodeOffset       uint32
+	readMode         bool
+}
+
+func (x *xof) Write(p []byte) (n int, err error) {
+	if x.readMode {
+		panic("blake2b: write to XOF after read")
+	}
+	return x.d.Write(p)
+}
+
+func (x *xof) Clone() XOF {
+	clone := *x
+	return &clone
+}
+
+func (x *xof) Reset() {
+	x.cfg[0] = byte(Size)
+	binary.LittleEndian.PutUint32(x.cfg[4:], uint32(Size)) // leaf length
+	binary.LittleEndian.PutUint32(x.cfg[12:], x.length)    // XOF length
+	x.cfg[17] = byte(Size)                                 // inner hash size
+
+	x.d.Reset()
+	x.d.h[1] ^= uint64(x.length) << 32
+
+	x.remaining = uint64(x.length)
+	if x.remaining == magicUnknownOutputLength {
+		x.remaining = maxOutputLength
+	}
+	x.offset, x.nodeOffset = 0, 0
+	x.readMode = false
+}
+
+func (x *xof) Read(p []byte) (n int, err error) {
+	if !x.readMode {
+		x.d.finalize(&x.root)
+		x.readMode = true
+	}
+
+	if x.remaining == 0 {
+		return 0, io.EOF
+	}
+
+	n = len(p)
+	if uint64(n) > x.remaining {
+		n = int(x.remaining)
+		p = p[:n]
+	}
+
+	if x.offset > 0 {
+		blockRemaining := Size - x.offset
+		if n < blockRemaining {
+			x.offset += copy(p, x.block[x.offset:])
+			x.remaining -= uint64(n)
+			return
+		}
+		copy(p, x.block[x.offset:])
+		p = p[blockRemaining:]
+		x.offset = 0
+		x.remaining -= uint64(blockRemaining)
+	}
+
+	for len(p) >= Size {
+		binary.LittleEndian.PutUint32(x.cfg[8:], x.nodeOffset)
+		x.nodeOffset++
+
+		x.d.initConfig(&x.cfg)
+		x.d.Write(x.root[:])
+		x.d.finalize(&x.block)
+
+		copy(p, x.block[:])
+		p = p[Size:]
+		x.remaining -= uint64(Size)
+	}
+
+	if todo := len(p); todo > 0 {
+		if x.remaining < uint64(Size) {
+			x.cfg[0] = byte(x.remaining)
+		}
+		binary.LittleEndian.PutUint32(x.cfg[8:], x.nodeOffset)
+		x.nodeOffset++
+
+		x.d.initConfig(&x.cfg)
+		x.d.Write(x.root[:])
+		x.d.finalize(&x.block)
+
+		x.offset = copy(p, x.block[:todo])
+		x.remaining -= uint64(todo)
+	}
+	return
+}
+
+func (d *digest) initConfig(cfg *[Size]byte) {
+	d.offset, d.c[0], d.c[1] = 0, 0, 0
+	for i := range d.h {
+		d.h[i] = iv[i] ^ binary.LittleEndian.Uint64(cfg[i*8:])
+	}
+}
diff --git a/vendor/golang.org/x/crypto/blake2b/register.go b/vendor/golang.org/x/crypto/blake2b/register.go
new file mode 100644
index 0000000000..9d8633963c
--- /dev/null
+++ b/vendor/golang.org/x/crypto/blake2b/register.go
@@ -0,0 +1,33 @@
+// Copyright 2017 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.
+
+//go:build go1.9
+// +build go1.9
+
+package blake2b
+
+import (
+	"crypto"
+	"hash"
+)
+
+func init() {
+	newHash256 := func() hash.Hash {
+		h, _ := New256(nil)
+		return h
+	}
+	newHash384 := func() hash.Hash {
+		h, _ := New384(nil)
+		return h
+	}
+
+	newHash512 := func() hash.Hash {
+		h, _ := New512(nil)
+		return h
+	}
+
+	crypto.RegisterHash(crypto.BLAKE2b_256, newHash256)
+	crypto.RegisterHash(crypto.BLAKE2b_384, newHash384)
+	crypto.RegisterHash(crypto.BLAKE2b_512, newHash512)
+}
diff --git a/vendor/golang.org/x/crypto/blake2s/blake2s.go b/vendor/golang.org/x/crypto/blake2s/blake2s.go
new file mode 100644
index 0000000000..e3f46aab3a
--- /dev/null
+++ b/vendor/golang.org/x/crypto/blake2s/blake2s.go
@@ -0,0 +1,246 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package blake2s implements the BLAKE2s hash algorithm defined by RFC 7693
+// and the extendable output function (XOF) BLAKE2Xs.
+//
+// BLAKE2s is optimized for 8- to 32-bit platforms and produces digests of any
+// size between 1 and 32 bytes.
+// For a detailed specification of BLAKE2s see https://blake2.net/blake2.pdf
+// and for BLAKE2Xs see https://blake2.net/blake2x.pdf
+//
+// If you aren't sure which function you need, use BLAKE2s (Sum256 or New256).
+// If you need a secret-key MAC (message authentication code), use the New256
+// function with a non-nil key.
+//
+// BLAKE2X is a construction to compute hash values larger than 32 bytes. It
+// can produce hash values between 0 and 65535 bytes.
+package blake2s // import "golang.org/x/crypto/blake2s"
+
+import (
+	"encoding/binary"
+	"errors"
+	"hash"
+)
+
+const (
+	// The blocksize of BLAKE2s in bytes.
+	BlockSize = 64
+
+	// The hash size of BLAKE2s-256 in bytes.
+	Size = 32
+
+	// The hash size of BLAKE2s-128 in bytes.
+	Size128 = 16
+)
+
+var errKeySize = errors.New("blake2s: invalid key size")
+
+var iv = [8]uint32{
+	0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
+	0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,
+}
+
+// Sum256 returns the BLAKE2s-256 checksum of the data.
+func Sum256(data []byte) [Size]byte {
+	var sum [Size]byte
+	checkSum(&sum, Size, data)
+	return sum
+}
+
+// New256 returns a new hash.Hash computing the BLAKE2s-256 checksum. A non-nil
+// key turns the hash into a MAC. The key must between zero and 32 bytes long.
+// When the key is nil, the returned hash.Hash implements BinaryMarshaler
+// and BinaryUnmarshaler for state (de)serialization as documented by hash.Hash.
+func New256(key []byte) (hash.Hash, error) { return newDigest(Size, key) }
+
+// New128 returns a new hash.Hash computing the BLAKE2s-128 checksum given a
+// non-empty key. Note that a 128-bit digest is too small to be secure as a
+// cryptographic hash and should only be used as a MAC, thus the key argument
+// is not optional.
+func New128(key []byte) (hash.Hash, error) {
+	if len(key) == 0 {
+		return nil, errors.New("blake2s: a key is required for a 128-bit hash")
+	}
+	return newDigest(Size128, key)
+}
+
+func newDigest(hashSize int, key []byte) (*digest, error) {
+	if len(key) > Size {
+		return nil, errKeySize
+	}
+	d := &digest{
+		size:   hashSize,
+		keyLen: len(key),
+	}
+	copy(d.key[:], key)
+	d.Reset()
+	return d, nil
+}
+
+func checkSum(sum *[Size]byte, hashSize int, data []byte) {
+	var (
+		h [8]uint32
+		c [2]uint32
+	)
+
+	h = iv
+	h[0] ^= uint32(hashSize) | (1 << 16) | (1 << 24)
+
+	if length := len(data); length > BlockSize {
+		n := length &^ (BlockSize - 1)
+		if length == n {
+			n -= BlockSize
+		}
+		hashBlocks(&h, &c, 0, data[:n])
+		data = data[n:]
+	}
+
+	var block [BlockSize]byte
+	offset := copy(block[:], data)
+	remaining := uint32(BlockSize - offset)
+
+	if c[0] < remaining {
+		c[1]--
+	}
+	c[0] -= remaining
+
+	hashBlocks(&h, &c, 0xFFFFFFFF, block[:])
+
+	for i, v := range h {
+		binary.LittleEndian.PutUint32(sum[4*i:], v)
+	}
+}
+
+type digest struct {
+	h      [8]uint32
+	c      [2]uint32
+	size   int
+	block  [BlockSize]byte
+	offset int
+
+	key    [BlockSize]byte
+	keyLen int
+}
+
+const (
+	magic         = "b2s"
+	marshaledSize = len(magic) + 8*4 + 2*4 + 1 + BlockSize + 1
+)
+
+func (d *digest) MarshalBinary() ([]byte, error) {
+	if d.keyLen != 0 {
+		return nil, errors.New("crypto/blake2s: cannot marshal MACs")
+	}
+	b := make([]byte, 0, marshaledSize)
+	b = append(b, magic...)
+	for i := 0; i < 8; i++ {
+		b = appendUint32(b, d.h[i])
+	}
+	b = appendUint32(b, d.c[0])
+	b = appendUint32(b, d.c[1])
+	// Maximum value for size is 32
+	b = append(b, byte(d.size))
+	b = append(b, d.block[:]...)
+	b = append(b, byte(d.offset))
+	return b, nil
+}
+
+func (d *digest) UnmarshalBinary(b []byte) error {
+	if len(b) < len(magic) || string(b[:len(magic)]) != magic {
+		return errors.New("crypto/blake2s: invalid hash state identifier")
+	}
+	if len(b) != marshaledSize {
+		return errors.New("crypto/blake2s: invalid hash state size")
+	}
+	b = b[len(magic):]
+	for i := 0; i < 8; i++ {
+		b, d.h[i] = consumeUint32(b)
+	}
+	b, d.c[0] = consumeUint32(b)
+	b, d.c[1] = consumeUint32(b)
+	d.size = int(b[0])
+	b = b[1:]
+	copy(d.block[:], b[:BlockSize])
+	b = b[BlockSize:]
+	d.offset = int(b[0])
+	return nil
+}
+
+func (d *digest) BlockSize() int { return BlockSize }
+
+func (d *digest) Size() int { return d.size }
+
+func (d *digest) Reset() {
+	d.h = iv
+	d.h[0] ^= uint32(d.size) | (uint32(d.keyLen) << 8) | (1 << 16) | (1 << 24)
+	d.offset, d.c[0], d.c[1] = 0, 0, 0
+	if d.keyLen > 0 {
+		d.block = d.key
+		d.offset = BlockSize
+	}
+}
+
+func (d *digest) Write(p []byte) (n int, err error) {
+	n = len(p)
+
+	if d.offset > 0 {
+		remaining := BlockSize - d.offset
+		if n <= remaining {
+			d.offset += copy(d.block[d.offset:], p)
+			return
+		}
+		copy(d.block[d.offset:], p[:remaining])
+		hashBlocks(&d.h, &d.c, 0, d.block[:])
+		d.offset = 0
+		p = p[remaining:]
+	}
+
+	if length := len(p); length > BlockSize {
+		nn := length &^ (BlockSize - 1)
+		if length == nn {
+			nn -= BlockSize
+		}
+		hashBlocks(&d.h, &d.c, 0, p[:nn])
+		p = p[nn:]
+	}
+
+	d.offset += copy(d.block[:], p)
+	return
+}
+
+func (d *digest) Sum(sum []byte) []byte {
+	var hash [Size]byte
+	d.finalize(&hash)
+	return append(sum, hash[:d.size]...)
+}
+
+func (d *digest) finalize(hash *[Size]byte) {
+	var block [BlockSize]byte
+	h := d.h
+	c := d.c
+
+	copy(block[:], d.block[:d.offset])
+	remaining := uint32(BlockSize - d.offset)
+	if c[0] < remaining {
+		c[1]--
+	}
+	c[0] -= remaining
+
+	hashBlocks(&h, &c, 0xFFFFFFFF, block[:])
+	for i, v := range h {
+		binary.LittleEndian.PutUint32(hash[4*i:], v)
+	}
+}
+
+func appendUint32(b []byte, x uint32) []byte {
+	var a [4]byte
+	binary.BigEndian.PutUint32(a[:], x)
+	return append(b, a[:]...)
+}
+
+func consumeUint32(b []byte) ([]byte, uint32) {
+	x := binary.BigEndian.Uint32(b)
+	return b[4:], x
+}
diff --git a/vendor/golang.org/x/crypto/blake2s/blake2s_386.go b/vendor/golang.org/x/crypto/blake2s/blake2s_386.go
new file mode 100644
index 0000000000..b4463fb4dc
--- /dev/null
+++ b/vendor/golang.org/x/crypto/blake2s/blake2s_386.go
@@ -0,0 +1,33 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build 386 && gc && !purego
+// +build 386,gc,!purego
+
+package blake2s
+
+import "golang.org/x/sys/cpu"
+
+var (
+	useSSE4  = false
+	useSSSE3 = cpu.X86.HasSSSE3
+	useSSE2  = cpu.X86.HasSSE2
+)
+
+//go:noescape
+func hashBlocksSSE2(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte)
+
+//go:noescape
+func hashBlocksSSSE3(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte)
+
+func hashBlocks(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte) {
+	switch {
+	case useSSSE3:
+		hashBlocksSSSE3(h, c, flag, blocks)
+	case useSSE2:
+		hashBlocksSSE2(h, c, flag, blocks)
+	default:
+		hashBlocksGeneric(h, c, flag, blocks)
+	}
+}
diff --git a/vendor/golang.org/x/crypto/blake2s/blake2s_386.s b/vendor/golang.org/x/crypto/blake2s/blake2s_386.s
new file mode 100644
index 0000000000..603d00ca32
--- /dev/null
+++ b/vendor/golang.org/x/crypto/blake2s/blake2s_386.s
@@ -0,0 +1,430 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build 386 && gc && !purego
+// +build 386,gc,!purego
+
+#include "textflag.h"
+
+DATA iv0<>+0x00(SB)/4, $0x6a09e667
+DATA iv0<>+0x04(SB)/4, $0xbb67ae85
+DATA iv0<>+0x08(SB)/4, $0x3c6ef372
+DATA iv0<>+0x0c(SB)/4, $0xa54ff53a
+GLOBL iv0<>(SB), (NOPTR+RODATA), $16
+
+DATA iv1<>+0x00(SB)/4, $0x510e527f
+DATA iv1<>+0x04(SB)/4, $0x9b05688c
+DATA iv1<>+0x08(SB)/4, $0x1f83d9ab
+DATA iv1<>+0x0c(SB)/4, $0x5be0cd19
+GLOBL iv1<>(SB), (NOPTR+RODATA), $16
+
+DATA rol16<>+0x00(SB)/8, $0x0504070601000302
+DATA rol16<>+0x08(SB)/8, $0x0D0C0F0E09080B0A
+GLOBL rol16<>(SB), (NOPTR+RODATA), $16
+
+DATA rol8<>+0x00(SB)/8, $0x0407060500030201
+DATA rol8<>+0x08(SB)/8, $0x0C0F0E0D080B0A09
+GLOBL rol8<>(SB), (NOPTR+RODATA), $16
+
+DATA counter<>+0x00(SB)/8, $0x40
+DATA counter<>+0x08(SB)/8, $0x0
+GLOBL counter<>(SB), (NOPTR+RODATA), $16
+
+#define ROTL_SSE2(n, t, v) \
+	MOVO  v, t;       \
+	PSLLL $n, t;      \
+	PSRLL $(32-n), v; \
+	PXOR  t, v
+
+#define ROTL_SSSE3(c, v) \
+	PSHUFB c, v
+
+#define ROUND_SSE2(v0, v1, v2, v3, m0, m1, m2, m3, t) \
+	PADDL  m0, v0;        \
+	PADDL  v1, v0;        \
+	PXOR   v0, v3;        \
+	ROTL_SSE2(16, t, v3); \
+	PADDL  v3, v2;        \
+	PXOR   v2, v1;        \
+	ROTL_SSE2(20, t, v1); \
+	PADDL  m1, v0;        \
+	PADDL  v1, v0;        \
+	PXOR   v0, v3;        \
+	ROTL_SSE2(24, t, v3); \
+	PADDL  v3, v2;        \
+	PXOR   v2, v1;        \
+	ROTL_SSE2(25, t, v1); \
+	PSHUFL $0x39, v1, v1; \
+	PSHUFL $0x4E, v2, v2; \
+	PSHUFL $0x93, v3, v3; \
+	PADDL  m2, v0;        \
+	PADDL  v1, v0;        \
+	PXOR   v0, v3;        \
+	ROTL_SSE2(16, t, v3); \
+	PADDL  v3, v2;        \
+	PXOR   v2, v1;        \
+	ROTL_SSE2(20, t, v1); \
+	PADDL  m3, v0;        \
+	PADDL  v1, v0;        \
+	PXOR   v0, v3;        \
+	ROTL_SSE2(24, t, v3); \
+	PADDL  v3, v2;        \
+	PXOR   v2, v1;        \
+	ROTL_SSE2(25, t, v1); \
+	PSHUFL $0x39, v3, v3; \
+	PSHUFL $0x4E, v2, v2; \
+	PSHUFL $0x93, v1, v1
+
+#define ROUND_SSSE3(v0, v1, v2, v3, m0, m1, m2, m3, t, c16, c8) \
+	PADDL  m0, v0;        \
+	PADDL  v1, v0;        \
+	PXOR   v0, v3;        \
+	ROTL_SSSE3(c16, v3);  \
+	PADDL  v3, v2;        \
+	PXOR   v2, v1;        \
+	ROTL_SSE2(20, t, v1); \
+	PADDL  m1, v0;        \
+	PADDL  v1, v0;        \
+	PXOR   v0, v3;        \
+	ROTL_SSSE3(c8, v3);   \
+	PADDL  v3, v2;        \
+	PXOR   v2, v1;        \
+	ROTL_SSE2(25, t, v1); \
+	PSHUFL $0x39, v1, v1; \
+	PSHUFL $0x4E, v2, v2; \
+	PSHUFL $0x93, v3, v3; \
+	PADDL  m2, v0;        \
+	PADDL  v1, v0;        \
+	PXOR   v0, v3;        \
+	ROTL_SSSE3(c16, v3);  \
+	PADDL  v3, v2;        \
+	PXOR   v2, v1;        \
+	ROTL_SSE2(20, t, v1); \
+	PADDL  m3, v0;        \
+	PADDL  v1, v0;        \
+	PXOR   v0, v3;        \
+	ROTL_SSSE3(c8, v3);   \
+	PADDL  v3, v2;        \
+	PXOR   v2, v1;        \
+	ROTL_SSE2(25, t, v1); \
+	PSHUFL $0x39, v3, v3; \
+	PSHUFL $0x4E, v2, v2; \
+	PSHUFL $0x93, v1, v1
+
+#define PRECOMPUTE(dst, off, src, t) \
+	MOVL 0*4(src), t;          \
+	MOVL t, 0*4+off+0(dst);    \
+	MOVL t, 9*4+off+64(dst);   \
+	MOVL t, 5*4+off+128(dst);  \
+	MOVL t, 14*4+off+192(dst); \
+	MOVL t, 4*4+off+256(dst);  \
+	MOVL t, 2*4+off+320(dst);  \
+	MOVL t, 8*4+off+384(dst);  \
+	MOVL t, 12*4+off+448(dst); \
+	MOVL t, 3*4+off+512(dst);  \
+	MOVL t, 15*4+off+576(dst); \
+	MOVL 1*4(src), t;          \
+	MOVL t, 4*4+off+0(dst);    \
+	MOVL t, 8*4+off+64(dst);   \
+	MOVL t, 14*4+off+128(dst); \
+	MOVL t, 5*4+off+192(dst);  \
+	MOVL t, 12*4+off+256(dst); \
+	MOVL t, 11*4+off+320(dst); \
+	MOVL t, 1*4+off+384(dst);  \
+	MOVL t, 6*4+off+448(dst);  \
+	MOVL t, 10*4+off+512(dst); \
+	MOVL t, 3*4+off+576(dst);  \
+	MOVL 2*4(src), t;          \
+	MOVL t, 1*4+off+0(dst);    \
+	MOVL t, 13*4+off+64(dst);  \
+	MOVL t, 6*4+off+128(dst);  \
+	MOVL t, 8*4+off+192(dst);  \
+	MOVL t, 2*4+off+256(dst);  \
+	MOVL t, 0*4+off+320(dst);  \
+	MOVL t, 14*4+off+384(dst); \
+	MOVL t, 11*4+off+448(dst); \
+	MOVL t, 12*4+off+512(dst); \
+	MOVL t, 4*4+off+576(dst);  \
+	MOVL 3*4(src), t;          \
+	MOVL t, 5*4+off+0(dst);    \
+	MOVL t, 15*4+off+64(dst);  \
+	MOVL t, 9*4+off+128(dst);  \
+	MOVL t, 1*4+off+192(dst);  \
+	MOVL t, 11*4+off+256(dst); \
+	MOVL t, 7*4+off+320(dst);  \
+	MOVL t, 13*4+off+384(dst); \
+	MOVL t, 3*4+off+448(dst);  \
+	MOVL t, 6*4+off+512(dst);  \
+	MOVL t, 10*4+off+576(dst); \
+	MOVL 4*4(src), t;          \
+	MOVL t, 2*4+off+0(dst);    \
+	MOVL t, 1*4+off+64(dst);   \
+	MOVL t, 15*4+off+128(dst); \
+	MOVL t, 10*4+off+192(dst); \
+	MOVL t, 6*4+off+256(dst);  \
+	MOVL t, 8*4+off+320(dst);  \
+	MOVL t, 3*4+off+384(dst);  \
+	MOVL t, 13*4+off+448(dst); \
+	MOVL t, 14*4+off+512(dst); \
+	MOVL t, 5*4+off+576(dst);  \
+	MOVL 5*4(src), t;          \
+	MOVL t, 6*4+off+0(dst);    \
+	MOVL t, 11*4+off+64(dst);  \
+	MOVL t, 2*4+off+128(dst);  \
+	MOVL t, 9*4+off+192(dst);  \
+	MOVL t, 1*4+off+256(dst);  \
+	MOVL t, 13*4+off+320(dst); \
+	MOVL t, 4*4+off+384(dst);  \
+	MOVL t, 8*4+off+448(dst);  \
+	MOVL t, 15*4+off+512(dst); \
+	MOVL t, 7*4+off+576(dst);  \
+	MOVL 6*4(src), t;          \
+	MOVL t, 3*4+off+0(dst);    \
+	MOVL t, 7*4+off+64(dst);   \
+	MOVL t, 13*4+off+128(dst); \
+	MOVL t, 12*4+off+192(dst); \
+	MOVL t, 10*4+off+256(dst); \
+	MOVL t, 1*4+off+320(dst);  \
+	MOVL t, 9*4+off+384(dst);  \
+	MOVL t, 14*4+off+448(dst); \
+	MOVL t, 0*4+off+512(dst);  \
+	MOVL t, 6*4+off+576(dst);  \
+	MOVL 7*4(src), t;          \
+	MOVL t, 7*4+off+0(dst);    \
+	MOVL t, 14*4+off+64(dst);  \
+	MOVL t, 10*4+off+128(dst); \
+	MOVL t, 0*4+off+192(dst);  \
+	MOVL t, 5*4+off+256(dst);  \
+	MOVL t, 9*4+off+320(dst);  \
+	MOVL t, 12*4+off+384(dst); \
+	MOVL t, 1*4+off+448(dst);  \
+	MOVL t, 13*4+off+512(dst); \
+	MOVL t, 2*4+off+576(dst);  \
+	MOVL 8*4(src), t;          \
+	MOVL t, 8*4+off+0(dst);    \
+	MOVL t, 5*4+off+64(dst);   \
+	MOVL t, 4*4+off+128(dst);  \
+	MOVL t, 15*4+off+192(dst); \
+	MOVL t, 14*4+off+256(dst); \
+	MOVL t, 3*4+off+320(dst);  \
+	MOVL t, 11*4+off+384(dst); \
+	MOVL t, 10*4+off+448(dst); \
+	MOVL t, 7*4+off+512(dst);  \
+	MOVL t, 1*4+off+576(dst);  \
+	MOVL 9*4(src), t;          \
+	MOVL t, 12*4+off+0(dst);   \
+	MOVL t, 2*4+off+64(dst);   \
+	MOVL t, 11*4+off+128(dst); \
+	MOVL t, 4*4+off+192(dst);  \
+	MOVL t, 0*4+off+256(dst);  \
+	MOVL t, 15*4+off+320(dst); \
+	MOVL t, 10*4+off+384(dst); \
+	MOVL t, 7*4+off+448(dst);  \
+	MOVL t, 5*4+off+512(dst);  \
+	MOVL t, 9*4+off+576(dst);  \
+	MOVL 10*4(src), t;         \
+	MOVL t, 9*4+off+0(dst);    \
+	MOVL t, 4*4+off+64(dst);   \
+	MOVL t, 8*4+off+128(dst);  \
+	MOVL t, 13*4+off+192(dst); \
+	MOVL t, 3*4+off+256(dst);  \
+	MOVL t, 5*4+off+320(dst);  \
+	MOVL t, 7*4+off+384(dst);  \
+	MOVL t, 15*4+off+448(dst); \
+	MOVL t, 11*4+off+512(dst); \
+	MOVL t, 0*4+off+576(dst);  \
+	MOVL 11*4(src), t;         \
+	MOVL t, 13*4+off+0(dst);   \
+	MOVL t, 10*4+off+64(dst);  \
+	MOVL t, 0*4+off+128(dst);  \
+	MOVL t, 3*4+off+192(dst);  \
+	MOVL t, 9*4+off+256(dst);  \
+	MOVL t, 6*4+off+320(dst);  \
+	MOVL t, 15*4+off+384(dst); \
+	MOVL t, 4*4+off+448(dst);  \
+	MOVL t, 2*4+off+512(dst);  \
+	MOVL t, 12*4+off+576(dst); \
+	MOVL 12*4(src), t;         \
+	MOVL t, 10*4+off+0(dst);   \
+	MOVL t, 12*4+off+64(dst);  \
+	MOVL t, 1*4+off+128(dst);  \
+	MOVL t, 6*4+off+192(dst);  \
+	MOVL t, 13*4+off+256(dst); \
+	MOVL t, 4*4+off+320(dst);  \
+	MOVL t, 0*4+off+384(dst);  \
+	MOVL t, 2*4+off+448(dst);  \
+	MOVL t, 8*4+off+512(dst);  \
+	MOVL t, 14*4+off+576(dst); \
+	MOVL 13*4(src), t;         \
+	MOVL t, 14*4+off+0(dst);   \
+	MOVL t, 3*4+off+64(dst);   \
+	MOVL t, 7*4+off+128(dst);  \
+	MOVL t, 2*4+off+192(dst);  \
+	MOVL t, 15*4+off+256(dst); \
+	MOVL t, 12*4+off+320(dst); \
+	MOVL t, 6*4+off+384(dst);  \
+	MOVL t, 0*4+off+448(dst);  \
+	MOVL t, 9*4+off+512(dst);  \
+	MOVL t, 11*4+off+576(dst); \
+	MOVL 14*4(src), t;         \
+	MOVL t, 11*4+off+0(dst);   \
+	MOVL t, 0*4+off+64(dst);   \
+	MOVL t, 12*4+off+128(dst); \
+	MOVL t, 7*4+off+192(dst);  \
+	MOVL t, 8*4+off+256(dst);  \
+	MOVL t, 14*4+off+320(dst); \
+	MOVL t, 2*4+off+384(dst);  \
+	MOVL t, 5*4+off+448(dst);  \
+	MOVL t, 1*4+off+512(dst);  \
+	MOVL t, 13*4+off+576(dst); \
+	MOVL 15*4(src), t;         \
+	MOVL t, 15*4+off+0(dst);   \
+	MOVL t, 6*4+off+64(dst);   \
+	MOVL t, 3*4+off+128(dst);  \
+	MOVL t, 11*4+off+192(dst); \
+	MOVL t, 7*4+off+256(dst);  \
+	MOVL t, 10*4+off+320(dst); \
+	MOVL t, 5*4+off+384(dst);  \
+	MOVL t, 9*4+off+448(dst);  \
+	MOVL t, 4*4+off+512(dst);  \
+	MOVL t, 8*4+off+576(dst)
+
+// func hashBlocksSSE2(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte)
+TEXT ·hashBlocksSSE2(SB), 0, $672-24 // frame = 656 + 16 byte alignment
+	MOVL h+0(FP), AX
+	MOVL c+4(FP), BX
+	MOVL flag+8(FP), CX
+	MOVL blocks_base+12(FP), SI
+	MOVL blocks_len+16(FP), DX
+
+	MOVL SP, DI
+	ADDL $15, DI
+	ANDL $~15, DI
+
+	MOVL CX, 8(DI)
+	MOVL 0(BX), CX
+	MOVL CX, 0(DI)
+	MOVL 4(BX), CX
+	MOVL CX, 4(DI)
+	XORL CX, CX
+	MOVL CX, 12(DI)
+
+	MOVOU 0(AX), X0
+	MOVOU 16(AX), X1
+	MOVOU counter<>(SB), X2
+
+loop:
+	MOVO  X0, X4
+	MOVO  X1, X5
+	MOVOU iv0<>(SB), X6
+	MOVOU iv1<>(SB), X7
+
+	MOVO  0(DI), X3
+	PADDQ X2, X3
+	PXOR  X3, X7
+	MOVO  X3, 0(DI)
+
+	PRECOMPUTE(DI, 16, SI, CX)
+	ROUND_SSE2(X4, X5, X6, X7, 16(DI), 32(DI), 48(DI), 64(DI), X3)
+	ROUND_SSE2(X4, X5, X6, X7, 16+64(DI), 32+64(DI), 48+64(DI), 64+64(DI), X3)
+	ROUND_SSE2(X4, X5, X6, X7, 16+128(DI), 32+128(DI), 48+128(DI), 64+128(DI), X3)
+	ROUND_SSE2(X4, X5, X6, X7, 16+192(DI), 32+192(DI), 48+192(DI), 64+192(DI), X3)
+	ROUND_SSE2(X4, X5, X6, X7, 16+256(DI), 32+256(DI), 48+256(DI), 64+256(DI), X3)
+	ROUND_SSE2(X4, X5, X6, X7, 16+320(DI), 32+320(DI), 48+320(DI), 64+320(DI), X3)
+	ROUND_SSE2(X4, X5, X6, X7, 16+384(DI), 32+384(DI), 48+384(DI), 64+384(DI), X3)
+	ROUND_SSE2(X4, X5, X6, X7, 16+448(DI), 32+448(DI), 48+448(DI), 64+448(DI), X3)
+	ROUND_SSE2(X4, X5, X6, X7, 16+512(DI), 32+512(DI), 48+512(DI), 64+512(DI), X3)
+	ROUND_SSE2(X4, X5, X6, X7, 16+576(DI), 32+576(DI), 48+576(DI), 64+576(DI), X3)
+
+	PXOR X4, X0
+	PXOR X5, X1
+	PXOR X6, X0
+	PXOR X7, X1
+
+	LEAL 64(SI), SI
+	SUBL $64, DX
+	JNE  loop
+
+	MOVL 0(DI), CX
+	MOVL CX, 0(BX)
+	MOVL 4(DI), CX
+	MOVL CX, 4(BX)
+
+	MOVOU X0, 0(AX)
+	MOVOU X1, 16(AX)
+
+	RET
+
+// func hashBlocksSSSE3(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte)
+TEXT ·hashBlocksSSSE3(SB), 0, $704-24 // frame = 688 + 16 byte alignment
+	MOVL h+0(FP), AX
+	MOVL c+4(FP), BX
+	MOVL flag+8(FP), CX
+	MOVL blocks_base+12(FP), SI
+	MOVL blocks_len+16(FP), DX
+
+	MOVL SP, DI
+	ADDL $15, DI
+	ANDL $~15, DI
+
+	MOVL CX, 8(DI)
+	MOVL 0(BX), CX
+	MOVL CX, 0(DI)
+	MOVL 4(BX), CX
+	MOVL CX, 4(DI)
+	XORL CX, CX
+	MOVL CX, 12(DI)
+
+	MOVOU 0(AX), X0
+	MOVOU 16(AX), X1
+	MOVOU counter<>(SB), X2
+
+loop:
+	MOVO  X0, 656(DI)
+	MOVO  X1, 672(DI)
+	MOVO  X0, X4
+	MOVO  X1, X5
+	MOVOU iv0<>(SB), X6
+	MOVOU iv1<>(SB), X7
+
+	MOVO  0(DI), X3
+	PADDQ X2, X3
+	PXOR  X3, X7
+	MOVO  X3, 0(DI)
+
+	MOVOU rol16<>(SB), X0
+	MOVOU rol8<>(SB), X1
+
+	PRECOMPUTE(DI, 16, SI, CX)
+	ROUND_SSSE3(X4, X5, X6, X7, 16(DI), 32(DI), 48(DI), 64(DI), X3, X0, X1)
+	ROUND_SSSE3(X4, X5, X6, X7, 16+64(DI), 32+64(DI), 48+64(DI), 64+64(DI), X3, X0, X1)
+	ROUND_SSSE3(X4, X5, X6, X7, 16+128(DI), 32+128(DI), 48+128(DI), 64+128(DI), X3, X0, X1)
+	ROUND_SSSE3(X4, X5, X6, X7, 16+192(DI), 32+192(DI), 48+192(DI), 64+192(DI), X3, X0, X1)
+	ROUND_SSSE3(X4, X5, X6, X7, 16+256(DI), 32+256(DI), 48+256(DI), 64+256(DI), X3, X0, X1)
+	ROUND_SSSE3(X4, X5, X6, X7, 16+320(DI), 32+320(DI), 48+320(DI), 64+320(DI), X3, X0, X1)
+	ROUND_SSSE3(X4, X5, X6, X7, 16+384(DI), 32+384(DI), 48+384(DI), 64+384(DI), X3, X0, X1)
+	ROUND_SSSE3(X4, X5, X6, X7, 16+448(DI), 32+448(DI), 48+448(DI), 64+448(DI), X3, X0, X1)
+	ROUND_SSSE3(X4, X5, X6, X7, 16+512(DI), 32+512(DI), 48+512(DI), 64+512(DI), X3, X0, X1)
+	ROUND_SSSE3(X4, X5, X6, X7, 16+576(DI), 32+576(DI), 48+576(DI), 64+576(DI), X3, X0, X1)
+
+	MOVO 656(DI), X0
+	MOVO 672(DI), X1
+	PXOR X4, X0
+	PXOR X5, X1
+	PXOR X6, X0
+	PXOR X7, X1
+
+	LEAL 64(SI), SI
+	SUBL $64, DX
+	JNE  loop
+
+	MOVL 0(DI), CX
+	MOVL CX, 0(BX)
+	MOVL 4(DI), CX
+	MOVL CX, 4(BX)
+
+	MOVOU X0, 0(AX)
+	MOVOU X1, 16(AX)
+
+	RET
diff --git a/vendor/golang.org/x/crypto/blake2s/blake2s_amd64.go b/vendor/golang.org/x/crypto/blake2s/blake2s_amd64.go
new file mode 100644
index 0000000000..becdaa120f
--- /dev/null
+++ b/vendor/golang.org/x/crypto/blake2s/blake2s_amd64.go
@@ -0,0 +1,38 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build amd64 && gc && !purego
+// +build amd64,gc,!purego
+
+package blake2s
+
+import "golang.org/x/sys/cpu"
+
+var (
+	useSSE4  = cpu.X86.HasSSE41
+	useSSSE3 = cpu.X86.HasSSSE3
+	useSSE2  = cpu.X86.HasSSE2
+)
+
+//go:noescape
+func hashBlocksSSE2(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte)
+
+//go:noescape
+func hashBlocksSSSE3(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte)
+
+//go:noescape
+func hashBlocksSSE4(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte)
+
+func hashBlocks(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte) {
+	switch {
+	case useSSE4:
+		hashBlocksSSE4(h, c, flag, blocks)
+	case useSSSE3:
+		hashBlocksSSSE3(h, c, flag, blocks)
+	case useSSE2:
+		hashBlocksSSE2(h, c, flag, blocks)
+	default:
+		hashBlocksGeneric(h, c, flag, blocks)
+	}
+}
diff --git a/vendor/golang.org/x/crypto/blake2s/blake2s_amd64.s b/vendor/golang.org/x/crypto/blake2s/blake2s_amd64.s
new file mode 100644
index 0000000000..e9df7a7c21
--- /dev/null
+++ b/vendor/golang.org/x/crypto/blake2s/blake2s_amd64.s
@@ -0,0 +1,433 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build amd64 && gc && !purego
+// +build amd64,gc,!purego
+
+#include "textflag.h"
+
+DATA iv0<>+0x00(SB)/4, $0x6a09e667
+DATA iv0<>+0x04(SB)/4, $0xbb67ae85
+DATA iv0<>+0x08(SB)/4, $0x3c6ef372
+DATA iv0<>+0x0c(SB)/4, $0xa54ff53a
+GLOBL iv0<>(SB), (NOPTR+RODATA), $16
+
+DATA iv1<>+0x00(SB)/4, $0x510e527f
+DATA iv1<>+0x04(SB)/4, $0x9b05688c
+DATA iv1<>+0x08(SB)/4, $0x1f83d9ab
+DATA iv1<>+0x0c(SB)/4, $0x5be0cd19
+GLOBL iv1<>(SB), (NOPTR+RODATA), $16
+
+DATA rol16<>+0x00(SB)/8, $0x0504070601000302
+DATA rol16<>+0x08(SB)/8, $0x0D0C0F0E09080B0A
+GLOBL rol16<>(SB), (NOPTR+RODATA), $16
+
+DATA rol8<>+0x00(SB)/8, $0x0407060500030201
+DATA rol8<>+0x08(SB)/8, $0x0C0F0E0D080B0A09
+GLOBL rol8<>(SB), (NOPTR+RODATA), $16
+
+DATA counter<>+0x00(SB)/8, $0x40
+DATA counter<>+0x08(SB)/8, $0x0
+GLOBL counter<>(SB), (NOPTR+RODATA), $16
+
+#define ROTL_SSE2(n, t, v) \
+	MOVO  v, t;       \
+	PSLLL $n, t;      \
+	PSRLL $(32-n), v; \
+	PXOR  t, v
+
+#define ROTL_SSSE3(c, v) \
+	PSHUFB c, v
+
+#define ROUND_SSE2(v0, v1, v2, v3, m0, m1, m2, m3, t) \
+	PADDL  m0, v0;        \
+	PADDL  v1, v0;        \
+	PXOR   v0, v3;        \
+	ROTL_SSE2(16, t, v3); \
+	PADDL  v3, v2;        \
+	PXOR   v2, v1;        \
+	ROTL_SSE2(20, t, v1); \
+	PADDL  m1, v0;        \
+	PADDL  v1, v0;        \
+	PXOR   v0, v3;        \
+	ROTL_SSE2(24, t, v3); \
+	PADDL  v3, v2;        \
+	PXOR   v2, v1;        \
+	ROTL_SSE2(25, t, v1); \
+	PSHUFL $0x39, v1, v1; \
+	PSHUFL $0x4E, v2, v2; \
+	PSHUFL $0x93, v3, v3; \
+	PADDL  m2, v0;        \
+	PADDL  v1, v0;        \
+	PXOR   v0, v3;        \
+	ROTL_SSE2(16, t, v3); \
+	PADDL  v3, v2;        \
+	PXOR   v2, v1;        \
+	ROTL_SSE2(20, t, v1); \
+	PADDL  m3, v0;        \
+	PADDL  v1, v0;        \
+	PXOR   v0, v3;        \
+	ROTL_SSE2(24, t, v3); \
+	PADDL  v3, v2;        \
+	PXOR   v2, v1;        \
+	ROTL_SSE2(25, t, v1); \
+	PSHUFL $0x39, v3, v3; \
+	PSHUFL $0x4E, v2, v2; \
+	PSHUFL $0x93, v1, v1
+
+#define ROUND_SSSE3(v0, v1, v2, v3, m0, m1, m2, m3, t, c16, c8) \
+	PADDL  m0, v0;        \
+	PADDL  v1, v0;        \
+	PXOR   v0, v3;        \
+	ROTL_SSSE3(c16, v3);  \
+	PADDL  v3, v2;        \
+	PXOR   v2, v1;        \
+	ROTL_SSE2(20, t, v1); \
+	PADDL  m1, v0;        \
+	PADDL  v1, v0;        \
+	PXOR   v0, v3;        \
+	ROTL_SSSE3(c8, v3);   \
+	PADDL  v3, v2;        \
+	PXOR   v2, v1;        \
+	ROTL_SSE2(25, t, v1); \
+	PSHUFL $0x39, v1, v1; \
+	PSHUFL $0x4E, v2, v2; \
+	PSHUFL $0x93, v3, v3; \
+	PADDL  m2, v0;        \
+	PADDL  v1, v0;        \
+	PXOR   v0, v3;        \
+	ROTL_SSSE3(c16, v3);  \
+	PADDL  v3, v2;        \
+	PXOR   v2, v1;        \
+	ROTL_SSE2(20, t, v1); \
+	PADDL  m3, v0;        \
+	PADDL  v1, v0;        \
+	PXOR   v0, v3;        \
+	ROTL_SSSE3(c8, v3);   \
+	PADDL  v3, v2;        \
+	PXOR   v2, v1;        \
+	ROTL_SSE2(25, t, v1); \
+	PSHUFL $0x39, v3, v3; \
+	PSHUFL $0x4E, v2, v2; \
+	PSHUFL $0x93, v1, v1
+
+
+#define LOAD_MSG_SSE4(m0, m1, m2, m3, src, i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14, i15) \
+	MOVL   i0*4(src), m0;      \
+	PINSRD $1, i1*4(src), m0;  \
+	PINSRD $2, i2*4(src), m0;  \
+	PINSRD $3, i3*4(src), m0;  \
+	MOVL   i4*4(src), m1;      \
+	PINSRD $1, i5*4(src), m1;  \
+	PINSRD $2, i6*4(src), m1;  \
+	PINSRD $3, i7*4(src), m1;  \
+	MOVL   i8*4(src), m2;      \
+	PINSRD $1, i9*4(src), m2;  \
+	PINSRD $2, i10*4(src), m2; \
+	PINSRD $3, i11*4(src), m2; \
+	MOVL   i12*4(src), m3;     \
+	PINSRD $1, i13*4(src), m3; \
+	PINSRD $2, i14*4(src), m3; \
+	PINSRD $3, i15*4(src), m3
+
+#define PRECOMPUTE_MSG(dst, off, src, R8, R9, R10, R11, R12, R13, R14, R15) \
+	MOVQ 0*4(src), R8;           \
+	MOVQ 2*4(src), R9;           \
+	MOVQ 4*4(src), R10;          \
+	MOVQ 6*4(src), R11;          \
+	MOVQ 8*4(src), R12;          \
+	MOVQ 10*4(src), R13;         \
+	MOVQ 12*4(src), R14;         \
+	MOVQ 14*4(src), R15;         \
+	                             \
+	MOVL R8, 0*4+off+0(dst);     \
+	MOVL R8, 9*4+off+64(dst);    \
+	MOVL R8, 5*4+off+128(dst);   \
+	MOVL R8, 14*4+off+192(dst);  \
+	MOVL R8, 4*4+off+256(dst);   \
+	MOVL R8, 2*4+off+320(dst);   \
+	MOVL R8, 8*4+off+384(dst);   \
+	MOVL R8, 12*4+off+448(dst);  \
+	MOVL R8, 3*4+off+512(dst);   \
+	MOVL R8, 15*4+off+576(dst);  \
+	SHRQ $32, R8;                \
+	MOVL R8, 4*4+off+0(dst);     \
+	MOVL R8, 8*4+off+64(dst);    \
+	MOVL R8, 14*4+off+128(dst);  \
+	MOVL R8, 5*4+off+192(dst);   \
+	MOVL R8, 12*4+off+256(dst);  \
+	MOVL R8, 11*4+off+320(dst);  \
+	MOVL R8, 1*4+off+384(dst);   \
+	MOVL R8, 6*4+off+448(dst);   \
+	MOVL R8, 10*4+off+512(dst);  \
+	MOVL R8, 3*4+off+576(dst);   \
+	                             \
+	MOVL R9, 1*4+off+0(dst);     \
+	MOVL R9, 13*4+off+64(dst);   \
+	MOVL R9, 6*4+off+128(dst);   \
+	MOVL R9, 8*4+off+192(dst);   \
+	MOVL R9, 2*4+off+256(dst);   \
+	MOVL R9, 0*4+off+320(dst);   \
+	MOVL R9, 14*4+off+384(dst);  \
+	MOVL R9, 11*4+off+448(dst);  \
+	MOVL R9, 12*4+off+512(dst);  \
+	MOVL R9, 4*4+off+576(dst);   \
+	SHRQ $32, R9;                \
+	MOVL R9, 5*4+off+0(dst);     \
+	MOVL R9, 15*4+off+64(dst);   \
+	MOVL R9, 9*4+off+128(dst);   \
+	MOVL R9, 1*4+off+192(dst);   \
+	MOVL R9, 11*4+off+256(dst);  \
+	MOVL R9, 7*4+off+320(dst);   \
+	MOVL R9, 13*4+off+384(dst);  \
+	MOVL R9, 3*4+off+448(dst);   \
+	MOVL R9, 6*4+off+512(dst);   \
+	MOVL R9, 10*4+off+576(dst);  \
+	                             \
+	MOVL R10, 2*4+off+0(dst);    \
+	MOVL R10, 1*4+off+64(dst);   \
+	MOVL R10, 15*4+off+128(dst); \
+	MOVL R10, 10*4+off+192(dst); \
+	MOVL R10, 6*4+off+256(dst);  \
+	MOVL R10, 8*4+off+320(dst);  \
+	MOVL R10, 3*4+off+384(dst);  \
+	MOVL R10, 13*4+off+448(dst); \
+	MOVL R10, 14*4+off+512(dst); \
+	MOVL R10, 5*4+off+576(dst);  \
+	SHRQ $32, R10;               \
+	MOVL R10, 6*4+off+0(dst);    \
+	MOVL R10, 11*4+off+64(dst);  \
+	MOVL R10, 2*4+off+128(dst);  \
+	MOVL R10, 9*4+off+192(dst);  \
+	MOVL R10, 1*4+off+256(dst);  \
+	MOVL R10, 13*4+off+320(dst); \
+	MOVL R10, 4*4+off+384(dst);  \
+	MOVL R10, 8*4+off+448(dst);  \
+	MOVL R10, 15*4+off+512(dst); \
+	MOVL R10, 7*4+off+576(dst);  \
+	                             \
+	MOVL R11, 3*4+off+0(dst);    \
+	MOVL R11, 7*4+off+64(dst);   \
+	MOVL R11, 13*4+off+128(dst); \
+	MOVL R11, 12*4+off+192(dst); \
+	MOVL R11, 10*4+off+256(dst); \
+	MOVL R11, 1*4+off+320(dst);  \
+	MOVL R11, 9*4+off+384(dst);  \
+	MOVL R11, 14*4+off+448(dst); \
+	MOVL R11, 0*4+off+512(dst);  \
+	MOVL R11, 6*4+off+576(dst);  \
+	SHRQ $32, R11;               \
+	MOVL R11, 7*4+off+0(dst);    \
+	MOVL R11, 14*4+off+64(dst);  \
+	MOVL R11, 10*4+off+128(dst); \
+	MOVL R11, 0*4+off+192(dst);  \
+	MOVL R11, 5*4+off+256(dst);  \
+	MOVL R11, 9*4+off+320(dst);  \
+	MOVL R11, 12*4+off+384(dst); \
+	MOVL R11, 1*4+off+448(dst);  \
+	MOVL R11, 13*4+off+512(dst); \
+	MOVL R11, 2*4+off+576(dst);  \
+	                             \
+	MOVL R12, 8*4+off+0(dst);    \
+	MOVL R12, 5*4+off+64(dst);   \
+	MOVL R12, 4*4+off+128(dst);  \
+	MOVL R12, 15*4+off+192(dst); \
+	MOVL R12, 14*4+off+256(dst); \
+	MOVL R12, 3*4+off+320(dst);  \
+	MOVL R12, 11*4+off+384(dst); \
+	MOVL R12, 10*4+off+448(dst); \
+	MOVL R12, 7*4+off+512(dst);  \
+	MOVL R12, 1*4+off+576(dst);  \
+	SHRQ $32, R12;               \
+	MOVL R12, 12*4+off+0(dst);   \
+	MOVL R12, 2*4+off+64(dst);   \
+	MOVL R12, 11*4+off+128(dst); \
+	MOVL R12, 4*4+off+192(dst);  \
+	MOVL R12, 0*4+off+256(dst);  \
+	MOVL R12, 15*4+off+320(dst); \
+	MOVL R12, 10*4+off+384(dst); \
+	MOVL R12, 7*4+off+448(dst);  \
+	MOVL R12, 5*4+off+512(dst);  \
+	MOVL R12, 9*4+off+576(dst);  \
+	                             \
+	MOVL R13, 9*4+off+0(dst);    \
+	MOVL R13, 4*4+off+64(dst);   \
+	MOVL R13, 8*4+off+128(dst);  \
+	MOVL R13, 13*4+off+192(dst); \
+	MOVL R13, 3*4+off+256(dst);  \
+	MOVL R13, 5*4+off+320(dst);  \
+	MOVL R13, 7*4+off+384(dst);  \
+	MOVL R13, 15*4+off+448(dst); \
+	MOVL R13, 11*4+off+512(dst); \
+	MOVL R13, 0*4+off+576(dst);  \
+	SHRQ $32, R13;               \
+	MOVL R13, 13*4+off+0(dst);   \
+	MOVL R13, 10*4+off+64(dst);  \
+	MOVL R13, 0*4+off+128(dst);  \
+	MOVL R13, 3*4+off+192(dst);  \
+	MOVL R13, 9*4+off+256(dst);  \
+	MOVL R13, 6*4+off+320(dst);  \
+	MOVL R13, 15*4+off+384(dst); \
+	MOVL R13, 4*4+off+448(dst);  \
+	MOVL R13, 2*4+off+512(dst);  \
+	MOVL R13, 12*4+off+576(dst); \
+	                             \
+	MOVL R14, 10*4+off+0(dst);   \
+	MOVL R14, 12*4+off+64(dst);  \
+	MOVL R14, 1*4+off+128(dst);  \
+	MOVL R14, 6*4+off+192(dst);  \
+	MOVL R14, 13*4+off+256(dst); \
+	MOVL R14, 4*4+off+320(dst);  \
+	MOVL R14, 0*4+off+384(dst);  \
+	MOVL R14, 2*4+off+448(dst);  \
+	MOVL R14, 8*4+off+512(dst);  \
+	MOVL R14, 14*4+off+576(dst); \
+	SHRQ $32, R14;               \
+	MOVL R14, 14*4+off+0(dst);   \
+	MOVL R14, 3*4+off+64(dst);   \
+	MOVL R14, 7*4+off+128(dst);  \
+	MOVL R14, 2*4+off+192(dst);  \
+	MOVL R14, 15*4+off+256(dst); \
+	MOVL R14, 12*4+off+320(dst); \
+	MOVL R14, 6*4+off+384(dst);  \
+	MOVL R14, 0*4+off+448(dst);  \
+	MOVL R14, 9*4+off+512(dst);  \
+	MOVL R14, 11*4+off+576(dst); \
+	                             \
+	MOVL R15, 11*4+off+0(dst);   \
+	MOVL R15, 0*4+off+64(dst);   \
+	MOVL R15, 12*4+off+128(dst); \
+	MOVL R15, 7*4+off+192(dst);  \
+	MOVL R15, 8*4+off+256(dst);  \
+	MOVL R15, 14*4+off+320(dst); \
+	MOVL R15, 2*4+off+384(dst);  \
+	MOVL R15, 5*4+off+448(dst);  \
+	MOVL R15, 1*4+off+512(dst);  \
+	MOVL R15, 13*4+off+576(dst); \
+	SHRQ $32, R15;               \
+	MOVL R15, 15*4+off+0(dst);   \
+	MOVL R15, 6*4+off+64(dst);   \
+	MOVL R15, 3*4+off+128(dst);  \
+	MOVL R15, 11*4+off+192(dst); \
+	MOVL R15, 7*4+off+256(dst);  \
+	MOVL R15, 10*4+off+320(dst); \
+	MOVL R15, 5*4+off+384(dst);  \
+	MOVL R15, 9*4+off+448(dst);  \
+	MOVL R15, 4*4+off+512(dst);  \
+	MOVL R15, 8*4+off+576(dst)
+
+#define BLAKE2s_SSE2() \
+	PRECOMPUTE_MSG(BP, 16, SI, R8, R9, R10, R11, R12, R13, R14, R15);               \
+	ROUND_SSE2(X4, X5, X6, X7, 16(BP), 32(BP), 48(BP), 64(BP), X8);                 \
+	ROUND_SSE2(X4, X5, X6, X7, 16+64(BP), 32+64(BP), 48+64(BP), 64+64(BP), X8);     \
+	ROUND_SSE2(X4, X5, X6, X7, 16+128(BP), 32+128(BP), 48+128(BP), 64+128(BP), X8); \
+	ROUND_SSE2(X4, X5, X6, X7, 16+192(BP), 32+192(BP), 48+192(BP), 64+192(BP), X8); \
+	ROUND_SSE2(X4, X5, X6, X7, 16+256(BP), 32+256(BP), 48+256(BP), 64+256(BP), X8); \
+	ROUND_SSE2(X4, X5, X6, X7, 16+320(BP), 32+320(BP), 48+320(BP), 64+320(BP), X8); \
+	ROUND_SSE2(X4, X5, X6, X7, 16+384(BP), 32+384(BP), 48+384(BP), 64+384(BP), X8); \
+	ROUND_SSE2(X4, X5, X6, X7, 16+448(BP), 32+448(BP), 48+448(BP), 64+448(BP), X8); \
+	ROUND_SSE2(X4, X5, X6, X7, 16+512(BP), 32+512(BP), 48+512(BP), 64+512(BP), X8); \
+	ROUND_SSE2(X4, X5, X6, X7, 16+576(BP), 32+576(BP), 48+576(BP), 64+576(BP), X8)
+
+#define BLAKE2s_SSSE3() \
+	PRECOMPUTE_MSG(BP, 16, SI, R8, R9, R10, R11, R12, R13, R14, R15);                          \
+	ROUND_SSSE3(X4, X5, X6, X7, 16(BP), 32(BP), 48(BP), 64(BP), X8, X13, X14);                 \
+	ROUND_SSSE3(X4, X5, X6, X7, 16+64(BP), 32+64(BP), 48+64(BP), 64+64(BP), X8, X13, X14);     \
+	ROUND_SSSE3(X4, X5, X6, X7, 16+128(BP), 32+128(BP), 48+128(BP), 64+128(BP), X8, X13, X14); \
+	ROUND_SSSE3(X4, X5, X6, X7, 16+192(BP), 32+192(BP), 48+192(BP), 64+192(BP), X8, X13, X14); \
+	ROUND_SSSE3(X4, X5, X6, X7, 16+256(BP), 32+256(BP), 48+256(BP), 64+256(BP), X8, X13, X14); \
+	ROUND_SSSE3(X4, X5, X6, X7, 16+320(BP), 32+320(BP), 48+320(BP), 64+320(BP), X8, X13, X14); \
+	ROUND_SSSE3(X4, X5, X6, X7, 16+384(BP), 32+384(BP), 48+384(BP), 64+384(BP), X8, X13, X14); \
+	ROUND_SSSE3(X4, X5, X6, X7, 16+448(BP), 32+448(BP), 48+448(BP), 64+448(BP), X8, X13, X14); \
+	ROUND_SSSE3(X4, X5, X6, X7, 16+512(BP), 32+512(BP), 48+512(BP), 64+512(BP), X8, X13, X14); \
+	ROUND_SSSE3(X4, X5, X6, X7, 16+576(BP), 32+576(BP), 48+576(BP), 64+576(BP), X8, X13, X14)
+
+#define BLAKE2s_SSE4() \
+	LOAD_MSG_SSE4(X8, X9, X10, X11, SI, 0, 2, 4, 6, 1, 3, 5, 7, 8, 10, 12, 14, 9, 11, 13, 15); \
+	ROUND_SSSE3(X4, X5, X6, X7, X8, X9, X10, X11, X8, X13, X14);                               \
+	LOAD_MSG_SSE4(X8, X9, X10, X11, SI, 14, 4, 9, 13, 10, 8, 15, 6, 1, 0, 11, 5, 12, 2, 7, 3); \
+	ROUND_SSSE3(X4, X5, X6, X7, X8, X9, X10, X11, X8, X13, X14);                               \
+	LOAD_MSG_SSE4(X8, X9, X10, X11, SI, 11, 12, 5, 15, 8, 0, 2, 13, 10, 3, 7, 9, 14, 6, 1, 4); \
+	ROUND_SSSE3(X4, X5, X6, X7, X8, X9, X10, X11, X8, X13, X14);                               \
+	LOAD_MSG_SSE4(X8, X9, X10, X11, SI, 7, 3, 13, 11, 9, 1, 12, 14, 2, 5, 4, 15, 6, 10, 0, 8); \
+	ROUND_SSSE3(X4, X5, X6, X7, X8, X9, X10, X11, X8, X13, X14);                               \
+	LOAD_MSG_SSE4(X8, X9, X10, X11, SI, 9, 5, 2, 10, 0, 7, 4, 15, 14, 11, 6, 3, 1, 12, 8, 13); \
+	ROUND_SSSE3(X4, X5, X6, X7, X8, X9, X10, X11, X8, X13, X14);                               \
+	LOAD_MSG_SSE4(X8, X9, X10, X11, SI, 2, 6, 0, 8, 12, 10, 11, 3, 4, 7, 15, 1, 13, 5, 14, 9); \
+	ROUND_SSSE3(X4, X5, X6, X7, X8, X9, X10, X11, X8, X13, X14);                               \
+	LOAD_MSG_SSE4(X8, X9, X10, X11, SI, 12, 1, 14, 4, 5, 15, 13, 10, 0, 6, 9, 8, 7, 3, 2, 11); \
+	ROUND_SSSE3(X4, X5, X6, X7, X8, X9, X10, X11, X8, X13, X14);                               \
+	LOAD_MSG_SSE4(X8, X9, X10, X11, SI, 13, 7, 12, 3, 11, 14, 1, 9, 5, 15, 8, 2, 0, 4, 6, 10); \
+	ROUND_SSSE3(X4, X5, X6, X7, X8, X9, X10, X11, X8, X13, X14);                               \
+	LOAD_MSG_SSE4(X8, X9, X10, X11, SI, 6, 14, 11, 0, 15, 9, 3, 8, 12, 13, 1, 10, 2, 7, 4, 5); \
+	ROUND_SSSE3(X4, X5, X6, X7, X8, X9, X10, X11, X8, X13, X14);                               \
+	LOAD_MSG_SSE4(X8, X9, X10, X11, SI, 10, 8, 7, 1, 2, 4, 6, 5, 15, 9, 3, 13, 11, 14, 12, 0); \
+	ROUND_SSSE3(X4, X5, X6, X7, X8, X9, X10, X11, X8, X13, X14)
+
+#define HASH_BLOCKS(h, c, flag, blocks_base, blocks_len, BLAKE2s_FUNC) \
+	MOVQ  h, AX;                   \
+	MOVQ  c, BX;                   \
+	MOVL  flag, CX;                \
+	MOVQ  blocks_base, SI;         \
+	MOVQ  blocks_len, DX;          \
+	                               \
+	MOVQ  SP, BP;                  \
+	ADDQ  $15, BP;                 \
+	ANDQ  $~15, BP;                \
+	                               \
+	MOVQ  0(BX), R9;               \
+	MOVQ  R9, 0(BP);               \
+	MOVQ  CX, 8(BP);               \
+	                               \
+	MOVOU 0(AX), X0;               \
+	MOVOU 16(AX), X1;              \
+	MOVOU iv0<>(SB), X2;           \
+	MOVOU iv1<>(SB), X3            \
+	                               \
+	MOVOU counter<>(SB), X12;      \
+	MOVOU rol16<>(SB), X13;        \
+	MOVOU rol8<>(SB), X14;         \
+	MOVO  0(BP), X15;              \
+	                               \
+	loop:                          \
+	MOVO  X0, X4;                  \
+	MOVO  X1, X5;                  \
+	MOVO  X2, X6;                  \
+	MOVO  X3, X7;                  \
+	                               \
+	PADDQ X12, X15;                \
+	PXOR  X15, X7;                 \
+	                               \
+	BLAKE2s_FUNC();                \
+	                               \
+	PXOR  X4, X0;                  \
+	PXOR  X5, X1;                  \
+	PXOR  X6, X0;                  \
+	PXOR  X7, X1;                  \
+	                               \
+	LEAQ  64(SI), SI;              \
+	SUBQ  $64, DX;                 \
+	JNE   loop;                    \
+	                               \
+	MOVO  X15, 0(BP);              \
+	MOVQ  0(BP), R9;               \
+	MOVQ  R9, 0(BX);               \
+	                               \
+	MOVOU X0, 0(AX);               \
+	MOVOU X1, 16(AX)
+
+// func hashBlocksSSE2(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte)
+TEXT ·hashBlocksSSE2(SB), 0, $672-48 // frame = 656 + 16 byte alignment
+	HASH_BLOCKS(h+0(FP), c+8(FP), flag+16(FP), blocks_base+24(FP), blocks_len+32(FP), BLAKE2s_SSE2)
+	RET
+
+// func hashBlocksSSSE3(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte)
+TEXT ·hashBlocksSSSE3(SB), 0, $672-48 // frame = 656 + 16 byte alignment
+	HASH_BLOCKS(h+0(FP), c+8(FP), flag+16(FP), blocks_base+24(FP), blocks_len+32(FP), BLAKE2s_SSSE3)
+	RET
+
+// func hashBlocksSSE4(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte)
+TEXT ·hashBlocksSSE4(SB), 0, $32-48 // frame = 16 + 16 byte alignment
+	HASH_BLOCKS(h+0(FP), c+8(FP), flag+16(FP), blocks_base+24(FP), blocks_len+32(FP), BLAKE2s_SSE4)
+	RET
diff --git a/vendor/golang.org/x/crypto/blake2s/blake2s_generic.go b/vendor/golang.org/x/crypto/blake2s/blake2s_generic.go
new file mode 100644
index 0000000000..24a1ff22ad
--- /dev/null
+++ b/vendor/golang.org/x/crypto/blake2s/blake2s_generic.go
@@ -0,0 +1,178 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package blake2s
+
+import (
+	"math/bits"
+)
+
+// the precomputed values for BLAKE2s
+// there are 10 16-byte arrays - one for each round
+// the entries are calculated from the sigma constants.
+var precomputed = [10][16]byte{
+	{0, 2, 4, 6, 1, 3, 5, 7, 8, 10, 12, 14, 9, 11, 13, 15},
+	{14, 4, 9, 13, 10, 8, 15, 6, 1, 0, 11, 5, 12, 2, 7, 3},
+	{11, 12, 5, 15, 8, 0, 2, 13, 10, 3, 7, 9, 14, 6, 1, 4},
+	{7, 3, 13, 11, 9, 1, 12, 14, 2, 5, 4, 15, 6, 10, 0, 8},
+	{9, 5, 2, 10, 0, 7, 4, 15, 14, 11, 6, 3, 1, 12, 8, 13},
+	{2, 6, 0, 8, 12, 10, 11, 3, 4, 7, 15, 1, 13, 5, 14, 9},
+	{12, 1, 14, 4, 5, 15, 13, 10, 0, 6, 9, 8, 7, 3, 2, 11},
+	{13, 7, 12, 3, 11, 14, 1, 9, 5, 15, 8, 2, 0, 4, 6, 10},
+	{6, 14, 11, 0, 15, 9, 3, 8, 12, 13, 1, 10, 2, 7, 4, 5},
+	{10, 8, 7, 1, 2, 4, 6, 5, 15, 9, 3, 13, 11, 14, 12, 0},
+}
+
+func hashBlocksGeneric(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte) {
+	var m [16]uint32
+	c0, c1 := c[0], c[1]
+
+	for i := 0; i < len(blocks); {
+		c0 += BlockSize
+		if c0 < BlockSize {
+			c1++
+		}
+
+		v0, v1, v2, v3, v4, v5, v6, v7 := h[0], h[1], h[2], h[3], h[4], h[5], h[6], h[7]
+		v8, v9, v10, v11, v12, v13, v14, v15 := iv[0], iv[1], iv[2], iv[3], iv[4], iv[5], iv[6], iv[7]
+		v12 ^= c0
+		v13 ^= c1
+		v14 ^= flag
+
+		for j := range m {
+			m[j] = uint32(blocks[i]) | uint32(blocks[i+1])<<8 | uint32(blocks[i+2])<<16 | uint32(blocks[i+3])<<24
+			i += 4
+		}
+
+		for k := range precomputed {
+			s := &(precomputed[k])
+
+			v0 += m[s[0]]
+			v0 += v4
+			v12 ^= v0
+			v12 = bits.RotateLeft32(v12, -16)
+			v8 += v12
+			v4 ^= v8
+			v4 = bits.RotateLeft32(v4, -12)
+			v1 += m[s[1]]
+			v1 += v5
+			v13 ^= v1
+			v13 = bits.RotateLeft32(v13, -16)
+			v9 += v13
+			v5 ^= v9
+			v5 = bits.RotateLeft32(v5, -12)
+			v2 += m[s[2]]
+			v2 += v6
+			v14 ^= v2
+			v14 = bits.RotateLeft32(v14, -16)
+			v10 += v14
+			v6 ^= v10
+			v6 = bits.RotateLeft32(v6, -12)
+			v3 += m[s[3]]
+			v3 += v7
+			v15 ^= v3
+			v15 = bits.RotateLeft32(v15, -16)
+			v11 += v15
+			v7 ^= v11
+			v7 = bits.RotateLeft32(v7, -12)
+
+			v0 += m[s[4]]
+			v0 += v4
+			v12 ^= v0
+			v12 = bits.RotateLeft32(v12, -8)
+			v8 += v12
+			v4 ^= v8
+			v4 = bits.RotateLeft32(v4, -7)
+			v1 += m[s[5]]
+			v1 += v5
+			v13 ^= v1
+			v13 = bits.RotateLeft32(v13, -8)
+			v9 += v13
+			v5 ^= v9
+			v5 = bits.RotateLeft32(v5, -7)
+			v2 += m[s[6]]
+			v2 += v6
+			v14 ^= v2
+			v14 = bits.RotateLeft32(v14, -8)
+			v10 += v14
+			v6 ^= v10
+			v6 = bits.RotateLeft32(v6, -7)
+			v3 += m[s[7]]
+			v3 += v7
+			v15 ^= v3
+			v15 = bits.RotateLeft32(v15, -8)
+			v11 += v15
+			v7 ^= v11
+			v7 = bits.RotateLeft32(v7, -7)
+
+			v0 += m[s[8]]
+			v0 += v5
+			v15 ^= v0
+			v15 = bits.RotateLeft32(v15, -16)
+			v10 += v15
+			v5 ^= v10
+			v5 = bits.RotateLeft32(v5, -12)
+			v1 += m[s[9]]
+			v1 += v6
+			v12 ^= v1
+			v12 = bits.RotateLeft32(v12, -16)
+			v11 += v12
+			v6 ^= v11
+			v6 = bits.RotateLeft32(v6, -12)
+			v2 += m[s[10]]
+			v2 += v7
+			v13 ^= v2
+			v13 = bits.RotateLeft32(v13, -16)
+			v8 += v13
+			v7 ^= v8
+			v7 = bits.RotateLeft32(v7, -12)
+			v3 += m[s[11]]
+			v3 += v4
+			v14 ^= v3
+			v14 = bits.RotateLeft32(v14, -16)
+			v9 += v14
+			v4 ^= v9
+			v4 = bits.RotateLeft32(v4, -12)
+
+			v0 += m[s[12]]
+			v0 += v5
+			v15 ^= v0
+			v15 = bits.RotateLeft32(v15, -8)
+			v10 += v15
+			v5 ^= v10
+			v5 = bits.RotateLeft32(v5, -7)
+			v1 += m[s[13]]
+			v1 += v6
+			v12 ^= v1
+			v12 = bits.RotateLeft32(v12, -8)
+			v11 += v12
+			v6 ^= v11
+			v6 = bits.RotateLeft32(v6, -7)
+			v2 += m[s[14]]
+			v2 += v7
+			v13 ^= v2
+			v13 = bits.RotateLeft32(v13, -8)
+			v8 += v13
+			v7 ^= v8
+			v7 = bits.RotateLeft32(v7, -7)
+			v3 += m[s[15]]
+			v3 += v4
+			v14 ^= v3
+			v14 = bits.RotateLeft32(v14, -8)
+			v9 += v14
+			v4 ^= v9
+			v4 = bits.RotateLeft32(v4, -7)
+		}
+
+		h[0] ^= v0 ^ v8
+		h[1] ^= v1 ^ v9
+		h[2] ^= v2 ^ v10
+		h[3] ^= v3 ^ v11
+		h[4] ^= v4 ^ v12
+		h[5] ^= v5 ^ v13
+		h[6] ^= v6 ^ v14
+		h[7] ^= v7 ^ v15
+	}
+	c[0], c[1] = c0, c1
+}
diff --git a/vendor/golang.org/x/crypto/blake2s/blake2s_ref.go b/vendor/golang.org/x/crypto/blake2s/blake2s_ref.go
new file mode 100644
index 0000000000..799dba0c41
--- /dev/null
+++ b/vendor/golang.org/x/crypto/blake2s/blake2s_ref.go
@@ -0,0 +1,18 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build (!amd64 && !386) || !gc || purego
+// +build !amd64,!386 !gc purego
+
+package blake2s
+
+var (
+	useSSE4  = false
+	useSSSE3 = false
+	useSSE2  = false
+)
+
+func hashBlocks(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte) {
+	hashBlocksGeneric(h, c, flag, blocks)
+}
diff --git a/vendor/golang.org/x/crypto/blake2s/blake2x.go b/vendor/golang.org/x/crypto/blake2s/blake2x.go
new file mode 100644
index 0000000000..828749ff01
--- /dev/null
+++ b/vendor/golang.org/x/crypto/blake2s/blake2x.go
@@ -0,0 +1,178 @@
+// Copyright 2017 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 blake2s
+
+import (
+	"encoding/binary"
+	"errors"
+	"io"
+)
+
+// XOF defines the interface to hash functions that
+// support arbitrary-length output.
+type XOF interface {
+	// Write absorbs more data into the hash's state. It panics if called
+	// after Read.
+	io.Writer
+
+	// Read reads more output from the hash. It returns io.EOF if the limit
+	// has been reached.
+	io.Reader
+
+	// Clone returns a copy of the XOF in its current state.
+	Clone() XOF
+
+	// Reset resets the XOF to its initial state.
+	Reset()
+}
+
+// OutputLengthUnknown can be used as the size argument to NewXOF to indicate
+// the length of the output is not known in advance.
+const OutputLengthUnknown = 0
+
+// magicUnknownOutputLength is a magic value for the output size that indicates
+// an unknown number of output bytes.
+const magicUnknownOutputLength = 65535
+
+// maxOutputLength is the absolute maximum number of bytes to produce when the
+// number of output bytes is unknown.
+const maxOutputLength = (1 << 32) * 32
+
+// NewXOF creates a new variable-output-length hash. The hash either produce a
+// known number of bytes (1 <= size < 65535), or an unknown number of bytes
+// (size == OutputLengthUnknown). In the latter case, an absolute limit of
+// 128GiB applies.
+//
+// A non-nil key turns the hash into a MAC. The key must between
+// zero and 32 bytes long.
+func NewXOF(size uint16, key []byte) (XOF, error) {
+	if len(key) > Size {
+		return nil, errKeySize
+	}
+	if size == magicUnknownOutputLength {
+		// 2^16-1 indicates an unknown number of bytes and thus isn't a
+		// valid length.
+		return nil, errors.New("blake2s: XOF length too large")
+	}
+	if size == OutputLengthUnknown {
+		size = magicUnknownOutputLength
+	}
+	x := &xof{
+		d: digest{
+			size:   Size,
+			keyLen: len(key),
+		},
+		length: size,
+	}
+	copy(x.d.key[:], key)
+	x.Reset()
+	return x, nil
+}
+
+type xof struct {
+	d                digest
+	length           uint16
+	remaining        uint64
+	cfg, root, block [Size]byte
+	offset           int
+	nodeOffset       uint32
+	readMode         bool
+}
+
+func (x *xof) Write(p []byte) (n int, err error) {
+	if x.readMode {
+		panic("blake2s: write to XOF after read")
+	}
+	return x.d.Write(p)
+}
+
+func (x *xof) Clone() XOF {
+	clone := *x
+	return &clone
+}
+
+func (x *xof) Reset() {
+	x.cfg[0] = byte(Size)
+	binary.LittleEndian.PutUint32(x.cfg[4:], uint32(Size)) // leaf length
+	binary.LittleEndian.PutUint16(x.cfg[12:], x.length)    // XOF length
+	x.cfg[15] = byte(Size)                                 // inner hash size
+
+	x.d.Reset()
+	x.d.h[3] ^= uint32(x.length)
+
+	x.remaining = uint64(x.length)
+	if x.remaining == magicUnknownOutputLength {
+		x.remaining = maxOutputLength
+	}
+	x.offset, x.nodeOffset = 0, 0
+	x.readMode = false
+}
+
+func (x *xof) Read(p []byte) (n int, err error) {
+	if !x.readMode {
+		x.d.finalize(&x.root)
+		x.readMode = true
+	}
+
+	if x.remaining == 0 {
+		return 0, io.EOF
+	}
+
+	n = len(p)
+	if uint64(n) > x.remaining {
+		n = int(x.remaining)
+		p = p[:n]
+	}
+
+	if x.offset > 0 {
+		blockRemaining := Size - x.offset
+		if n < blockRemaining {
+			x.offset += copy(p, x.block[x.offset:])
+			x.remaining -= uint64(n)
+			return
+		}
+		copy(p, x.block[x.offset:])
+		p = p[blockRemaining:]
+		x.offset = 0
+		x.remaining -= uint64(blockRemaining)
+	}
+
+	for len(p) >= Size {
+		binary.LittleEndian.PutUint32(x.cfg[8:], x.nodeOffset)
+		x.nodeOffset++
+
+		x.d.initConfig(&x.cfg)
+		x.d.Write(x.root[:])
+		x.d.finalize(&x.block)
+
+		copy(p, x.block[:])
+		p = p[Size:]
+		x.remaining -= uint64(Size)
+	}
+
+	if todo := len(p); todo > 0 {
+		if x.remaining < uint64(Size) {
+			x.cfg[0] = byte(x.remaining)
+		}
+		binary.LittleEndian.PutUint32(x.cfg[8:], x.nodeOffset)
+		x.nodeOffset++
+
+		x.d.initConfig(&x.cfg)
+		x.d.Write(x.root[:])
+		x.d.finalize(&x.block)
+
+		x.offset = copy(p, x.block[:todo])
+		x.remaining -= uint64(todo)
+	}
+
+	return
+}
+
+func (d *digest) initConfig(cfg *[Size]byte) {
+	d.offset, d.c[0], d.c[1] = 0, 0, 0
+	for i := range d.h {
+		d.h[i] = iv[i] ^ binary.LittleEndian.Uint32(cfg[i*4:])
+	}
+}
diff --git a/vendor/golang.org/x/crypto/blake2s/register.go b/vendor/golang.org/x/crypto/blake2s/register.go
new file mode 100644
index 0000000000..ef79ff3c67
--- /dev/null
+++ b/vendor/golang.org/x/crypto/blake2s/register.go
@@ -0,0 +1,22 @@
+// Copyright 2017 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.
+
+//go:build go1.9
+// +build go1.9
+
+package blake2s
+
+import (
+	"crypto"
+	"hash"
+)
+
+func init() {
+	newHash256 := func() hash.Hash {
+		h, _ := New256(nil)
+		return h
+	}
+
+	crypto.RegisterHash(crypto.BLAKE2s_256, newHash256)
+}
diff --git a/vendor/golang.org/x/crypto/bn256/bn256.go b/vendor/golang.org/x/crypto/bn256/bn256.go
new file mode 100644
index 0000000000..9c99fcdb5d
--- /dev/null
+++ b/vendor/golang.org/x/crypto/bn256/bn256.go
@@ -0,0 +1,429 @@
+// 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 bn256 implements a particular bilinear group.
+//
+// Bilinear groups are the basis of many of the new cryptographic protocols
+// that have been proposed over the past decade. They consist of a triplet of
+// groups (G₁, G₂ and GT) such that there exists a function e(g₁ˣ,g₂ʸ)=gTˣʸ
+// (where gₓ is a generator of the respective group). That function is called
+// a pairing function.
+//
+// This package specifically implements the Optimal Ate pairing over a 256-bit
+// Barreto-Naehrig curve as described in
+// http://cryptojedi.org/papers/dclxvi-20100714.pdf. Its output is compatible
+// with the implementation described in that paper.
+//
+// This package previously claimed to operate at a 128-bit security level.
+// However, recent improvements in attacks mean that is no longer true. See
+// https://moderncrypto.org/mail-archive/curves/2016/000740.html.
+//
+// Deprecated: due to its weakened security, new systems should not rely on this
+// elliptic curve. This package is frozen, and not implemented in constant time.
+// There is a more complete implementation at github.com/cloudflare/bn256, but
+// note that it suffers from the same security issues of the underlying curve.
+package bn256 // import "golang.org/x/crypto/bn256"
+
+import (
+	"crypto/rand"
+	"io"
+	"math/big"
+)
+
+// G1 is an abstract cyclic group. The zero value is suitable for use as the
+// output of an operation, but cannot be used as an input.
+type G1 struct {
+	p *curvePoint
+}
+
+// RandomG1 returns x and g₁ˣ where x is a random, non-zero number read from r.
+func RandomG1(r io.Reader) (*big.Int, *G1, error) {
+	var k *big.Int
+	var err error
+
+	for {
+		k, err = rand.Int(r, Order)
+		if err != nil {
+			return nil, nil, err
+		}
+		if k.Sign() > 0 {
+			break
+		}
+	}
+
+	return k, new(G1).ScalarBaseMult(k), nil
+}
+
+func (e *G1) String() string {
+	if e.p == nil {
+		return "bn256.G1" + newCurvePoint(nil).String()
+	}
+	return "bn256.G1" + e.p.String()
+}
+
+// ScalarBaseMult sets e to g*k where g is the generator of the group and
+// then returns e.
+func (e *G1) ScalarBaseMult(k *big.Int) *G1 {
+	if e.p == nil {
+		e.p = newCurvePoint(nil)
+	}
+	e.p.Mul(curveGen, k, new(bnPool))
+	return e
+}
+
+// ScalarMult sets e to a*k and then returns e.
+func (e *G1) ScalarMult(a *G1, k *big.Int) *G1 {
+	if e.p == nil {
+		e.p = newCurvePoint(nil)
+	}
+	e.p.Mul(a.p, k, new(bnPool))
+	return e
+}
+
+// Add sets e to a+b and then returns e.
+//
+// Warning: this function is not complete, it fails for a equal to b.
+func (e *G1) Add(a, b *G1) *G1 {
+	if e.p == nil {
+		e.p = newCurvePoint(nil)
+	}
+	e.p.Add(a.p, b.p, new(bnPool))
+	return e
+}
+
+// Neg sets e to -a and then returns e.
+func (e *G1) Neg(a *G1) *G1 {
+	if e.p == nil {
+		e.p = newCurvePoint(nil)
+	}
+	e.p.Negative(a.p)
+	return e
+}
+
+// Marshal converts n to a byte slice.
+func (e *G1) Marshal() []byte {
+	// Each value is a 256-bit number.
+	const numBytes = 256 / 8
+
+	if e.p.IsInfinity() {
+		return make([]byte, numBytes*2)
+	}
+
+	e.p.MakeAffine(nil)
+
+	xBytes := new(big.Int).Mod(e.p.x, p).Bytes()
+	yBytes := new(big.Int).Mod(e.p.y, p).Bytes()
+
+	ret := make([]byte, numBytes*2)
+	copy(ret[1*numBytes-len(xBytes):], xBytes)
+	copy(ret[2*numBytes-len(yBytes):], yBytes)
+
+	return ret
+}
+
+// Unmarshal sets e to the result of converting the output of Marshal back into
+// a group element and then returns e.
+func (e *G1) Unmarshal(m []byte) (*G1, bool) {
+	// Each value is a 256-bit number.
+	const numBytes = 256 / 8
+
+	if len(m) != 2*numBytes {
+		return nil, false
+	}
+
+	if e.p == nil {
+		e.p = newCurvePoint(nil)
+	}
+
+	e.p.x.SetBytes(m[0*numBytes : 1*numBytes])
+	e.p.y.SetBytes(m[1*numBytes : 2*numBytes])
+
+	if e.p.x.Sign() == 0 && e.p.y.Sign() == 0 {
+		// This is the point at infinity.
+		e.p.y.SetInt64(1)
+		e.p.z.SetInt64(0)
+		e.p.t.SetInt64(0)
+	} else {
+		e.p.z.SetInt64(1)
+		e.p.t.SetInt64(1)
+
+		if !e.p.IsOnCurve() {
+			return nil, false
+		}
+	}
+
+	return e, true
+}
+
+// G2 is an abstract cyclic group. The zero value is suitable for use as the
+// output of an operation, but cannot be used as an input.
+type G2 struct {
+	p *twistPoint
+}
+
+// RandomG1 returns x and g₂ˣ where x is a random, non-zero number read from r.
+func RandomG2(r io.Reader) (*big.Int, *G2, error) {
+	var k *big.Int
+	var err error
+
+	for {
+		k, err = rand.Int(r, Order)
+		if err != nil {
+			return nil, nil, err
+		}
+		if k.Sign() > 0 {
+			break
+		}
+	}
+
+	return k, new(G2).ScalarBaseMult(k), nil
+}
+
+func (e *G2) String() string {
+	if e.p == nil {
+		return "bn256.G2" + newTwistPoint(nil).String()
+	}
+	return "bn256.G2" + e.p.String()
+}
+
+// ScalarBaseMult sets e to g*k where g is the generator of the group and
+// then returns out.
+func (e *G2) ScalarBaseMult(k *big.Int) *G2 {
+	if e.p == nil {
+		e.p = newTwistPoint(nil)
+	}
+	e.p.Mul(twistGen, k, new(bnPool))
+	return e
+}
+
+// ScalarMult sets e to a*k and then returns e.
+func (e *G2) ScalarMult(a *G2, k *big.Int) *G2 {
+	if e.p == nil {
+		e.p = newTwistPoint(nil)
+	}
+	e.p.Mul(a.p, k, new(bnPool))
+	return e
+}
+
+// Add sets e to a+b and then returns e.
+//
+// Warning: this function is not complete, it fails for a equal to b.
+func (e *G2) Add(a, b *G2) *G2 {
+	if e.p == nil {
+		e.p = newTwistPoint(nil)
+	}
+	e.p.Add(a.p, b.p, new(bnPool))
+	return e
+}
+
+// Marshal converts n into a byte slice.
+func (n *G2) Marshal() []byte {
+	// Each value is a 256-bit number.
+	const numBytes = 256 / 8
+
+	if n.p.IsInfinity() {
+		return make([]byte, numBytes*4)
+	}
+
+	n.p.MakeAffine(nil)
+
+	xxBytes := new(big.Int).Mod(n.p.x.x, p).Bytes()
+	xyBytes := new(big.Int).Mod(n.p.x.y, p).Bytes()
+	yxBytes := new(big.Int).Mod(n.p.y.x, p).Bytes()
+	yyBytes := new(big.Int).Mod(n.p.y.y, p).Bytes()
+
+	ret := make([]byte, numBytes*4)
+	copy(ret[1*numBytes-len(xxBytes):], xxBytes)
+	copy(ret[2*numBytes-len(xyBytes):], xyBytes)
+	copy(ret[3*numBytes-len(yxBytes):], yxBytes)
+	copy(ret[4*numBytes-len(yyBytes):], yyBytes)
+
+	return ret
+}
+
+// Unmarshal sets e to the result of converting the output of Marshal back into
+// a group element and then returns e.
+func (e *G2) Unmarshal(m []byte) (*G2, bool) {
+	// Each value is a 256-bit number.
+	const numBytes = 256 / 8
+
+	if len(m) != 4*numBytes {
+		return nil, false
+	}
+
+	if e.p == nil {
+		e.p = newTwistPoint(nil)
+	}
+
+	e.p.x.x.SetBytes(m[0*numBytes : 1*numBytes])
+	e.p.x.y.SetBytes(m[1*numBytes : 2*numBytes])
+	e.p.y.x.SetBytes(m[2*numBytes : 3*numBytes])
+	e.p.y.y.SetBytes(m[3*numBytes : 4*numBytes])
+
+	if e.p.x.x.Sign() == 0 &&
+		e.p.x.y.Sign() == 0 &&
+		e.p.y.x.Sign() == 0 &&
+		e.p.y.y.Sign() == 0 {
+		// This is the point at infinity.
+		e.p.y.SetOne()
+		e.p.z.SetZero()
+		e.p.t.SetZero()
+	} else {
+		e.p.z.SetOne()
+		e.p.t.SetOne()
+
+		if !e.p.IsOnCurve() {
+			return nil, false
+		}
+	}
+
+	return e, true
+}
+
+// GT is an abstract cyclic group. The zero value is suitable for use as the
+// output of an operation, but cannot be used as an input.
+type GT struct {
+	p *gfP12
+}
+
+func (e *GT) String() string {
+	if e.p == nil {
+		return "bn256.GT" + newGFp12(nil).String()
+	}
+	return "bn256.GT" + e.p.String()
+}
+
+// ScalarMult sets e to a*k and then returns e.
+func (e *GT) ScalarMult(a *GT, k *big.Int) *GT {
+	if e.p == nil {
+		e.p = newGFp12(nil)
+	}
+	e.p.Exp(a.p, k, new(bnPool))
+	return e
+}
+
+// Add sets e to a+b and then returns e.
+func (e *GT) Add(a, b *GT) *GT {
+	if e.p == nil {
+		e.p = newGFp12(nil)
+	}
+	e.p.Mul(a.p, b.p, new(bnPool))
+	return e
+}
+
+// Neg sets e to -a and then returns e.
+func (e *GT) Neg(a *GT) *GT {
+	if e.p == nil {
+		e.p = newGFp12(nil)
+	}
+	e.p.Invert(a.p, new(bnPool))
+	return e
+}
+
+// Marshal converts n into a byte slice.
+func (n *GT) Marshal() []byte {
+	n.p.Minimal()
+
+	xxxBytes := n.p.x.x.x.Bytes()
+	xxyBytes := n.p.x.x.y.Bytes()
+	xyxBytes := n.p.x.y.x.Bytes()
+	xyyBytes := n.p.x.y.y.Bytes()
+	xzxBytes := n.p.x.z.x.Bytes()
+	xzyBytes := n.p.x.z.y.Bytes()
+	yxxBytes := n.p.y.x.x.Bytes()
+	yxyBytes := n.p.y.x.y.Bytes()
+	yyxBytes := n.p.y.y.x.Bytes()
+	yyyBytes := n.p.y.y.y.Bytes()
+	yzxBytes := n.p.y.z.x.Bytes()
+	yzyBytes := n.p.y.z.y.Bytes()
+
+	// Each value is a 256-bit number.
+	const numBytes = 256 / 8
+
+	ret := make([]byte, numBytes*12)
+	copy(ret[1*numBytes-len(xxxBytes):], xxxBytes)
+	copy(ret[2*numBytes-len(xxyBytes):], xxyBytes)
+	copy(ret[3*numBytes-len(xyxBytes):], xyxBytes)
+	copy(ret[4*numBytes-len(xyyBytes):], xyyBytes)
+	copy(ret[5*numBytes-len(xzxBytes):], xzxBytes)
+	copy(ret[6*numBytes-len(xzyBytes):], xzyBytes)
+	copy(ret[7*numBytes-len(yxxBytes):], yxxBytes)
+	copy(ret[8*numBytes-len(yxyBytes):], yxyBytes)
+	copy(ret[9*numBytes-len(yyxBytes):], yyxBytes)
+	copy(ret[10*numBytes-len(yyyBytes):], yyyBytes)
+	copy(ret[11*numBytes-len(yzxBytes):], yzxBytes)
+	copy(ret[12*numBytes-len(yzyBytes):], yzyBytes)
+
+	return ret
+}
+
+// Unmarshal sets e to the result of converting the output of Marshal back into
+// a group element and then returns e.
+func (e *GT) Unmarshal(m []byte) (*GT, bool) {
+	// Each value is a 256-bit number.
+	const numBytes = 256 / 8
+
+	if len(m) != 12*numBytes {
+		return nil, false
+	}
+
+	if e.p == nil {
+		e.p = newGFp12(nil)
+	}
+
+	e.p.x.x.x.SetBytes(m[0*numBytes : 1*numBytes])
+	e.p.x.x.y.SetBytes(m[1*numBytes : 2*numBytes])
+	e.p.x.y.x.SetBytes(m[2*numBytes : 3*numBytes])
+	e.p.x.y.y.SetBytes(m[3*numBytes : 4*numBytes])
+	e.p.x.z.x.SetBytes(m[4*numBytes : 5*numBytes])
+	e.p.x.z.y.SetBytes(m[5*numBytes : 6*numBytes])
+	e.p.y.x.x.SetBytes(m[6*numBytes : 7*numBytes])
+	e.p.y.x.y.SetBytes(m[7*numBytes : 8*numBytes])
+	e.p.y.y.x.SetBytes(m[8*numBytes : 9*numBytes])
+	e.p.y.y.y.SetBytes(m[9*numBytes : 10*numBytes])
+	e.p.y.z.x.SetBytes(m[10*numBytes : 11*numBytes])
+	e.p.y.z.y.SetBytes(m[11*numBytes : 12*numBytes])
+
+	return e, true
+}
+
+// Pair calculates an Optimal Ate pairing.
+func Pair(g1 *G1, g2 *G2) *GT {
+	return &GT{optimalAte(g2.p, g1.p, new(bnPool))}
+}
+
+// bnPool implements a tiny cache of *big.Int objects that's used to reduce the
+// number of allocations made during processing.
+type bnPool struct {
+	bns   []*big.Int
+	count int
+}
+
+func (pool *bnPool) Get() *big.Int {
+	if pool == nil {
+		return new(big.Int)
+	}
+
+	pool.count++
+	l := len(pool.bns)
+	if l == 0 {
+		return new(big.Int)
+	}
+
+	bn := pool.bns[l-1]
+	pool.bns = pool.bns[:l-1]
+	return bn
+}
+
+func (pool *bnPool) Put(bn *big.Int) {
+	if pool == nil {
+		return
+	}
+	pool.bns = append(pool.bns, bn)
+	pool.count--
+}
+
+func (pool *bnPool) Count() int {
+	return pool.count
+}
diff --git a/vendor/golang.org/x/crypto/bn256/constants.go b/vendor/golang.org/x/crypto/bn256/constants.go
new file mode 100644
index 0000000000..1ccefc4982
--- /dev/null
+++ b/vendor/golang.org/x/crypto/bn256/constants.go
@@ -0,0 +1,44 @@
+// 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 bn256
+
+import (
+	"math/big"
+)
+
+func bigFromBase10(s string) *big.Int {
+	n, _ := new(big.Int).SetString(s, 10)
+	return n
+}
+
+// u is the BN parameter that determines the prime: 1868033³.
+var u = bigFromBase10("6518589491078791937")
+
+// p is a prime over which we form a basic field: 36u⁴+36u³+24u²+6u+1.
+var p = bigFromBase10("65000549695646603732796438742359905742825358107623003571877145026864184071783")
+
+// Order is the number of elements in both G₁ and G₂: 36u⁴+36u³+18u²+6u+1.
+var Order = bigFromBase10("65000549695646603732796438742359905742570406053903786389881062969044166799969")
+
+// xiToPMinus1Over6 is ξ^((p-1)/6) where ξ = i+3.
+var xiToPMinus1Over6 = &gfP2{bigFromBase10("8669379979083712429711189836753509758585994370025260553045152614783263110636"), bigFromBase10("19998038925833620163537568958541907098007303196759855091367510456613536016040")}
+
+// xiToPMinus1Over3 is ξ^((p-1)/3) where ξ = i+3.
+var xiToPMinus1Over3 = &gfP2{bigFromBase10("26098034838977895781559542626833399156321265654106457577426020397262786167059"), bigFromBase10("15931493369629630809226283458085260090334794394361662678240713231519278691715")}
+
+// xiToPMinus1Over2 is ξ^((p-1)/2) where ξ = i+3.
+var xiToPMinus1Over2 = &gfP2{bigFromBase10("50997318142241922852281555961173165965672272825141804376761836765206060036244"), bigFromBase10("38665955945962842195025998234511023902832543644254935982879660597356748036009")}
+
+// xiToPSquaredMinus1Over3 is ξ^((p²-1)/3) where ξ = i+3.
+var xiToPSquaredMinus1Over3 = bigFromBase10("65000549695646603727810655408050771481677621702948236658134783353303381437752")
+
+// xiTo2PSquaredMinus2Over3 is ξ^((2p²-2)/3) where ξ = i+3 (a cubic root of unity, mod p).
+var xiTo2PSquaredMinus2Over3 = bigFromBase10("4985783334309134261147736404674766913742361673560802634030")
+
+// xiToPSquaredMinus1Over6 is ξ^((1p²-1)/6) where ξ = i+3 (a cubic root of -1, mod p).
+var xiToPSquaredMinus1Over6 = bigFromBase10("65000549695646603727810655408050771481677621702948236658134783353303381437753")
+
+// xiTo2PMinus2Over3 is ξ^((2p-2)/3) where ξ = i+3.
+var xiTo2PMinus2Over3 = &gfP2{bigFromBase10("19885131339612776214803633203834694332692106372356013117629940868870585019582"), bigFromBase10("21645619881471562101905880913352894726728173167203616652430647841922248593627")}
diff --git a/vendor/golang.org/x/crypto/bn256/curve.go b/vendor/golang.org/x/crypto/bn256/curve.go
new file mode 100644
index 0000000000..63c052bc22
--- /dev/null
+++ b/vendor/golang.org/x/crypto/bn256/curve.go
@@ -0,0 +1,287 @@
+// 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 bn256
+
+import (
+	"math/big"
+)
+
+// curvePoint implements the elliptic curve y²=x³+3. Points are kept in
+// Jacobian form and t=z² when valid. G₁ is the set of points of this curve on
+// GF(p).
+type curvePoint struct {
+	x, y, z, t *big.Int
+}
+
+var curveB = new(big.Int).SetInt64(3)
+
+// curveGen is the generator of G₁.
+var curveGen = &curvePoint{
+	new(big.Int).SetInt64(1),
+	new(big.Int).SetInt64(-2),
+	new(big.Int).SetInt64(1),
+	new(big.Int).SetInt64(1),
+}
+
+func newCurvePoint(pool *bnPool) *curvePoint {
+	return &curvePoint{
+		pool.Get(),
+		pool.Get(),
+		pool.Get(),
+		pool.Get(),
+	}
+}
+
+func (c *curvePoint) String() string {
+	c.MakeAffine(new(bnPool))
+	return "(" + c.x.String() + ", " + c.y.String() + ")"
+}
+
+func (c *curvePoint) Put(pool *bnPool) {
+	pool.Put(c.x)
+	pool.Put(c.y)
+	pool.Put(c.z)
+	pool.Put(c.t)
+}
+
+func (c *curvePoint) Set(a *curvePoint) {
+	c.x.Set(a.x)
+	c.y.Set(a.y)
+	c.z.Set(a.z)
+	c.t.Set(a.t)
+}
+
+// IsOnCurve returns true iff c is on the curve where c must be in affine form.
+func (c *curvePoint) IsOnCurve() bool {
+	yy := new(big.Int).Mul(c.y, c.y)
+	xxx := new(big.Int).Mul(c.x, c.x)
+	xxx.Mul(xxx, c.x)
+	yy.Sub(yy, xxx)
+	yy.Sub(yy, curveB)
+	if yy.Sign() < 0 || yy.Cmp(p) >= 0 {
+		yy.Mod(yy, p)
+	}
+	return yy.Sign() == 0
+}
+
+func (c *curvePoint) SetInfinity() {
+	c.z.SetInt64(0)
+}
+
+func (c *curvePoint) IsInfinity() bool {
+	return c.z.Sign() == 0
+}
+
+func (c *curvePoint) Add(a, b *curvePoint, pool *bnPool) {
+	if a.IsInfinity() {
+		c.Set(b)
+		return
+	}
+	if b.IsInfinity() {
+		c.Set(a)
+		return
+	}
+
+	// See http://hyperelliptic.org/EFD/g1p/auto-code/shortw/jacobian-0/addition/add-2007-bl.op3
+
+	// Normalize the points by replacing a = [x1:y1:z1] and b = [x2:y2:z2]
+	// by [u1:s1:z1·z2] and [u2:s2:z1·z2]
+	// where u1 = x1·z2², s1 = y1·z2³ and u1 = x2·z1², s2 = y2·z1³
+	z1z1 := pool.Get().Mul(a.z, a.z)
+	z1z1.Mod(z1z1, p)
+	z2z2 := pool.Get().Mul(b.z, b.z)
+	z2z2.Mod(z2z2, p)
+	u1 := pool.Get().Mul(a.x, z2z2)
+	u1.Mod(u1, p)
+	u2 := pool.Get().Mul(b.x, z1z1)
+	u2.Mod(u2, p)
+
+	t := pool.Get().Mul(b.z, z2z2)
+	t.Mod(t, p)
+	s1 := pool.Get().Mul(a.y, t)
+	s1.Mod(s1, p)
+
+	t.Mul(a.z, z1z1)
+	t.Mod(t, p)
+	s2 := pool.Get().Mul(b.y, t)
+	s2.Mod(s2, p)
+
+	// Compute x = (2h)²(s²-u1-u2)
+	// where s = (s2-s1)/(u2-u1) is the slope of the line through
+	// (u1,s1) and (u2,s2). The extra factor 2h = 2(u2-u1) comes from the value of z below.
+	// This is also:
+	// 4(s2-s1)² - 4h²(u1+u2) = 4(s2-s1)² - 4h³ - 4h²(2u1)
+	//                        = r² - j - 2v
+	// with the notations below.
+	h := pool.Get().Sub(u2, u1)
+	xEqual := h.Sign() == 0
+
+	t.Add(h, h)
+	// i = 4h²
+	i := pool.Get().Mul(t, t)
+	i.Mod(i, p)
+	// j = 4h³
+	j := pool.Get().Mul(h, i)
+	j.Mod(j, p)
+
+	t.Sub(s2, s1)
+	yEqual := t.Sign() == 0
+	if xEqual && yEqual {
+		c.Double(a, pool)
+		return
+	}
+	r := pool.Get().Add(t, t)
+
+	v := pool.Get().Mul(u1, i)
+	v.Mod(v, p)
+
+	// t4 = 4(s2-s1)²
+	t4 := pool.Get().Mul(r, r)
+	t4.Mod(t4, p)
+	t.Add(v, v)
+	t6 := pool.Get().Sub(t4, j)
+	c.x.Sub(t6, t)
+
+	// Set y = -(2h)³(s1 + s*(x/4h²-u1))
+	// This is also
+	// y = - 2·s1·j - (s2-s1)(2x - 2i·u1) = r(v-x) - 2·s1·j
+	t.Sub(v, c.x) // t7
+	t4.Mul(s1, j) // t8
+	t4.Mod(t4, p)
+	t6.Add(t4, t4) // t9
+	t4.Mul(r, t)   // t10
+	t4.Mod(t4, p)
+	c.y.Sub(t4, t6)
+
+	// Set z = 2(u2-u1)·z1·z2 = 2h·z1·z2
+	t.Add(a.z, b.z) // t11
+	t4.Mul(t, t)    // t12
+	t4.Mod(t4, p)
+	t.Sub(t4, z1z1) // t13
+	t4.Sub(t, z2z2) // t14
+	c.z.Mul(t4, h)
+	c.z.Mod(c.z, p)
+
+	pool.Put(z1z1)
+	pool.Put(z2z2)
+	pool.Put(u1)
+	pool.Put(u2)
+	pool.Put(t)
+	pool.Put(s1)
+	pool.Put(s2)
+	pool.Put(h)
+	pool.Put(i)
+	pool.Put(j)
+	pool.Put(r)
+	pool.Put(v)
+	pool.Put(t4)
+	pool.Put(t6)
+}
+
+func (c *curvePoint) Double(a *curvePoint, pool *bnPool) {
+	// See http://hyperelliptic.org/EFD/g1p/auto-code/shortw/jacobian-0/doubling/dbl-2009-l.op3
+	A := pool.Get().Mul(a.x, a.x)
+	A.Mod(A, p)
+	B := pool.Get().Mul(a.y, a.y)
+	B.Mod(B, p)
+	C := pool.Get().Mul(B, B)
+	C.Mod(C, p)
+
+	t := pool.Get().Add(a.x, B)
+	t2 := pool.Get().Mul(t, t)
+	t2.Mod(t2, p)
+	t.Sub(t2, A)
+	t2.Sub(t, C)
+	d := pool.Get().Add(t2, t2)
+	t.Add(A, A)
+	e := pool.Get().Add(t, A)
+	f := pool.Get().Mul(e, e)
+	f.Mod(f, p)
+
+	t.Add(d, d)
+	c.x.Sub(f, t)
+
+	t.Add(C, C)
+	t2.Add(t, t)
+	t.Add(t2, t2)
+	c.y.Sub(d, c.x)
+	t2.Mul(e, c.y)
+	t2.Mod(t2, p)
+	c.y.Sub(t2, t)
+
+	t.Mul(a.y, a.z)
+	t.Mod(t, p)
+	c.z.Add(t, t)
+
+	pool.Put(A)
+	pool.Put(B)
+	pool.Put(C)
+	pool.Put(t)
+	pool.Put(t2)
+	pool.Put(d)
+	pool.Put(e)
+	pool.Put(f)
+}
+
+func (c *curvePoint) Mul(a *curvePoint, scalar *big.Int, pool *bnPool) *curvePoint {
+	sum := newCurvePoint(pool)
+	sum.SetInfinity()
+	t := newCurvePoint(pool)
+
+	for i := scalar.BitLen(); i >= 0; i-- {
+		t.Double(sum, pool)
+		if scalar.Bit(i) != 0 {
+			sum.Add(t, a, pool)
+		} else {
+			sum.Set(t)
+		}
+	}
+
+	c.Set(sum)
+	sum.Put(pool)
+	t.Put(pool)
+	return c
+}
+
+// MakeAffine converts c to affine form and returns c. If c is ∞, then it sets
+// c to 0 : 1 : 0.
+func (c *curvePoint) MakeAffine(pool *bnPool) *curvePoint {
+	if words := c.z.Bits(); len(words) == 1 && words[0] == 1 {
+		return c
+	}
+	if c.IsInfinity() {
+		c.x.SetInt64(0)
+		c.y.SetInt64(1)
+		c.z.SetInt64(0)
+		c.t.SetInt64(0)
+		return c
+	}
+
+	zInv := pool.Get().ModInverse(c.z, p)
+	t := pool.Get().Mul(c.y, zInv)
+	t.Mod(t, p)
+	zInv2 := pool.Get().Mul(zInv, zInv)
+	zInv2.Mod(zInv2, p)
+	c.y.Mul(t, zInv2)
+	c.y.Mod(c.y, p)
+	t.Mul(c.x, zInv2)
+	t.Mod(t, p)
+	c.x.Set(t)
+	c.z.SetInt64(1)
+	c.t.SetInt64(1)
+
+	pool.Put(zInv)
+	pool.Put(t)
+	pool.Put(zInv2)
+
+	return c
+}
+
+func (c *curvePoint) Negative(a *curvePoint) {
+	c.x.Set(a.x)
+	c.y.Neg(a.y)
+	c.z.Set(a.z)
+	c.t.SetInt64(0)
+}
diff --git a/vendor/golang.org/x/crypto/bn256/gfp12.go b/vendor/golang.org/x/crypto/bn256/gfp12.go
new file mode 100644
index 0000000000..2b0151ebcc
--- /dev/null
+++ b/vendor/golang.org/x/crypto/bn256/gfp12.go
@@ -0,0 +1,200 @@
+// 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 bn256
+
+// For details of the algorithms used, see "Multiplication and Squaring on
+// Pairing-Friendly Fields, Devegili et al.
+// http://eprint.iacr.org/2006/471.pdf.
+
+import (
+	"math/big"
+)
+
+// gfP12 implements the field of size p¹² as a quadratic extension of gfP6
+// where ω²=τ.
+type gfP12 struct {
+	x, y *gfP6 // value is xω + y
+}
+
+func newGFp12(pool *bnPool) *gfP12 {
+	return &gfP12{newGFp6(pool), newGFp6(pool)}
+}
+
+func (e *gfP12) String() string {
+	return "(" + e.x.String() + "," + e.y.String() + ")"
+}
+
+func (e *gfP12) Put(pool *bnPool) {
+	e.x.Put(pool)
+	e.y.Put(pool)
+}
+
+func (e *gfP12) Set(a *gfP12) *gfP12 {
+	e.x.Set(a.x)
+	e.y.Set(a.y)
+	return e
+}
+
+func (e *gfP12) SetZero() *gfP12 {
+	e.x.SetZero()
+	e.y.SetZero()
+	return e
+}
+
+func (e *gfP12) SetOne() *gfP12 {
+	e.x.SetZero()
+	e.y.SetOne()
+	return e
+}
+
+func (e *gfP12) Minimal() {
+	e.x.Minimal()
+	e.y.Minimal()
+}
+
+func (e *gfP12) IsZero() bool {
+	e.Minimal()
+	return e.x.IsZero() && e.y.IsZero()
+}
+
+func (e *gfP12) IsOne() bool {
+	e.Minimal()
+	return e.x.IsZero() && e.y.IsOne()
+}
+
+func (e *gfP12) Conjugate(a *gfP12) *gfP12 {
+	e.x.Negative(a.x)
+	e.y.Set(a.y)
+	return a
+}
+
+func (e *gfP12) Negative(a *gfP12) *gfP12 {
+	e.x.Negative(a.x)
+	e.y.Negative(a.y)
+	return e
+}
+
+// Frobenius computes (xω+y)^p = x^p ω·ξ^((p-1)/6) + y^p
+func (e *gfP12) Frobenius(a *gfP12, pool *bnPool) *gfP12 {
+	e.x.Frobenius(a.x, pool)
+	e.y.Frobenius(a.y, pool)
+	e.x.MulScalar(e.x, xiToPMinus1Over6, pool)
+	return e
+}
+
+// FrobeniusP2 computes (xω+y)^p² = x^p² ω·ξ^((p²-1)/6) + y^p²
+func (e *gfP12) FrobeniusP2(a *gfP12, pool *bnPool) *gfP12 {
+	e.x.FrobeniusP2(a.x)
+	e.x.MulGFP(e.x, xiToPSquaredMinus1Over6)
+	e.y.FrobeniusP2(a.y)
+	return e
+}
+
+func (e *gfP12) Add(a, b *gfP12) *gfP12 {
+	e.x.Add(a.x, b.x)
+	e.y.Add(a.y, b.y)
+	return e
+}
+
+func (e *gfP12) Sub(a, b *gfP12) *gfP12 {
+	e.x.Sub(a.x, b.x)
+	e.y.Sub(a.y, b.y)
+	return e
+}
+
+func (e *gfP12) Mul(a, b *gfP12, pool *bnPool) *gfP12 {
+	tx := newGFp6(pool)
+	tx.Mul(a.x, b.y, pool)
+	t := newGFp6(pool)
+	t.Mul(b.x, a.y, pool)
+	tx.Add(tx, t)
+
+	ty := newGFp6(pool)
+	ty.Mul(a.y, b.y, pool)
+	t.Mul(a.x, b.x, pool)
+	t.MulTau(t, pool)
+	e.y.Add(ty, t)
+	e.x.Set(tx)
+
+	tx.Put(pool)
+	ty.Put(pool)
+	t.Put(pool)
+	return e
+}
+
+func (e *gfP12) MulScalar(a *gfP12, b *gfP6, pool *bnPool) *gfP12 {
+	e.x.Mul(a.x, b, pool)
+	e.y.Mul(a.y, b, pool)
+	return e
+}
+
+func (c *gfP12) Exp(a *gfP12, power *big.Int, pool *bnPool) *gfP12 {
+	sum := newGFp12(pool)
+	sum.SetOne()
+	t := newGFp12(pool)
+
+	for i := power.BitLen() - 1; i >= 0; i-- {
+		t.Square(sum, pool)
+		if power.Bit(i) != 0 {
+			sum.Mul(t, a, pool)
+		} else {
+			sum.Set(t)
+		}
+	}
+
+	c.Set(sum)
+
+	sum.Put(pool)
+	t.Put(pool)
+
+	return c
+}
+
+func (e *gfP12) Square(a *gfP12, pool *bnPool) *gfP12 {
+	// Complex squaring algorithm
+	v0 := newGFp6(pool)
+	v0.Mul(a.x, a.y, pool)
+
+	t := newGFp6(pool)
+	t.MulTau(a.x, pool)
+	t.Add(a.y, t)
+	ty := newGFp6(pool)
+	ty.Add(a.x, a.y)
+	ty.Mul(ty, t, pool)
+	ty.Sub(ty, v0)
+	t.MulTau(v0, pool)
+	ty.Sub(ty, t)
+
+	e.y.Set(ty)
+	e.x.Double(v0)
+
+	v0.Put(pool)
+	t.Put(pool)
+	ty.Put(pool)
+
+	return e
+}
+
+func (e *gfP12) Invert(a *gfP12, pool *bnPool) *gfP12 {
+	// See "Implementing cryptographic pairings", M. Scott, section 3.2.
+	// ftp://136.206.11.249/pub/crypto/pairings.pdf
+	t1 := newGFp6(pool)
+	t2 := newGFp6(pool)
+
+	t1.Square(a.x, pool)
+	t2.Square(a.y, pool)
+	t1.MulTau(t1, pool)
+	t1.Sub(t2, t1)
+	t2.Invert(t1, pool)
+
+	e.x.Negative(a.x)
+	e.y.Set(a.y)
+	e.MulScalar(e, t2, pool)
+
+	t1.Put(pool)
+	t2.Put(pool)
+
+	return e
+}
diff --git a/vendor/golang.org/x/crypto/bn256/gfp2.go b/vendor/golang.org/x/crypto/bn256/gfp2.go
new file mode 100644
index 0000000000..97f3f1f3fa
--- /dev/null
+++ b/vendor/golang.org/x/crypto/bn256/gfp2.go
@@ -0,0 +1,219 @@
+// 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 bn256
+
+// For details of the algorithms used, see "Multiplication and Squaring on
+// Pairing-Friendly Fields, Devegili et al.
+// http://eprint.iacr.org/2006/471.pdf.
+
+import (
+	"math/big"
+)
+
+// gfP2 implements a field of size p² as a quadratic extension of the base
+// field where i²=-1.
+type gfP2 struct {
+	x, y *big.Int // value is xi+y.
+}
+
+func newGFp2(pool *bnPool) *gfP2 {
+	return &gfP2{pool.Get(), pool.Get()}
+}
+
+func (e *gfP2) String() string {
+	x := new(big.Int).Mod(e.x, p)
+	y := new(big.Int).Mod(e.y, p)
+	return "(" + x.String() + "," + y.String() + ")"
+}
+
+func (e *gfP2) Put(pool *bnPool) {
+	pool.Put(e.x)
+	pool.Put(e.y)
+}
+
+func (e *gfP2) Set(a *gfP2) *gfP2 {
+	e.x.Set(a.x)
+	e.y.Set(a.y)
+	return e
+}
+
+func (e *gfP2) SetZero() *gfP2 {
+	e.x.SetInt64(0)
+	e.y.SetInt64(0)
+	return e
+}
+
+func (e *gfP2) SetOne() *gfP2 {
+	e.x.SetInt64(0)
+	e.y.SetInt64(1)
+	return e
+}
+
+func (e *gfP2) Minimal() {
+	if e.x.Sign() < 0 || e.x.Cmp(p) >= 0 {
+		e.x.Mod(e.x, p)
+	}
+	if e.y.Sign() < 0 || e.y.Cmp(p) >= 0 {
+		e.y.Mod(e.y, p)
+	}
+}
+
+func (e *gfP2) IsZero() bool {
+	return e.x.Sign() == 0 && e.y.Sign() == 0
+}
+
+func (e *gfP2) IsOne() bool {
+	if e.x.Sign() != 0 {
+		return false
+	}
+	words := e.y.Bits()
+	return len(words) == 1 && words[0] == 1
+}
+
+func (e *gfP2) Conjugate(a *gfP2) *gfP2 {
+	e.y.Set(a.y)
+	e.x.Neg(a.x)
+	return e
+}
+
+func (e *gfP2) Negative(a *gfP2) *gfP2 {
+	e.x.Neg(a.x)
+	e.y.Neg(a.y)
+	return e
+}
+
+func (e *gfP2) Add(a, b *gfP2) *gfP2 {
+	e.x.Add(a.x, b.x)
+	e.y.Add(a.y, b.y)
+	return e
+}
+
+func (e *gfP2) Sub(a, b *gfP2) *gfP2 {
+	e.x.Sub(a.x, b.x)
+	e.y.Sub(a.y, b.y)
+	return e
+}
+
+func (e *gfP2) Double(a *gfP2) *gfP2 {
+	e.x.Lsh(a.x, 1)
+	e.y.Lsh(a.y, 1)
+	return e
+}
+
+func (c *gfP2) Exp(a *gfP2, power *big.Int, pool *bnPool) *gfP2 {
+	sum := newGFp2(pool)
+	sum.SetOne()
+	t := newGFp2(pool)
+
+	for i := power.BitLen() - 1; i >= 0; i-- {
+		t.Square(sum, pool)
+		if power.Bit(i) != 0 {
+			sum.Mul(t, a, pool)
+		} else {
+			sum.Set(t)
+		}
+	}
+
+	c.Set(sum)
+
+	sum.Put(pool)
+	t.Put(pool)
+
+	return c
+}
+
+// See "Multiplication and Squaring in Pairing-Friendly Fields",
+// http://eprint.iacr.org/2006/471.pdf
+func (e *gfP2) Mul(a, b *gfP2, pool *bnPool) *gfP2 {
+	tx := pool.Get().Mul(a.x, b.y)
+	t := pool.Get().Mul(b.x, a.y)
+	tx.Add(tx, t)
+	tx.Mod(tx, p)
+
+	ty := pool.Get().Mul(a.y, b.y)
+	t.Mul(a.x, b.x)
+	ty.Sub(ty, t)
+	e.y.Mod(ty, p)
+	e.x.Set(tx)
+
+	pool.Put(tx)
+	pool.Put(ty)
+	pool.Put(t)
+
+	return e
+}
+
+func (e *gfP2) MulScalar(a *gfP2, b *big.Int) *gfP2 {
+	e.x.Mul(a.x, b)
+	e.y.Mul(a.y, b)
+	return e
+}
+
+// MulXi sets e=ξa where ξ=i+3 and then returns e.
+func (e *gfP2) MulXi(a *gfP2, pool *bnPool) *gfP2 {
+	// (xi+y)(i+3) = (3x+y)i+(3y-x)
+	tx := pool.Get().Lsh(a.x, 1)
+	tx.Add(tx, a.x)
+	tx.Add(tx, a.y)
+
+	ty := pool.Get().Lsh(a.y, 1)
+	ty.Add(ty, a.y)
+	ty.Sub(ty, a.x)
+
+	e.x.Set(tx)
+	e.y.Set(ty)
+
+	pool.Put(tx)
+	pool.Put(ty)
+
+	return e
+}
+
+func (e *gfP2) Square(a *gfP2, pool *bnPool) *gfP2 {
+	// Complex squaring algorithm:
+	// (xi+b)² = (x+y)(y-x) + 2*i*x*y
+	t1 := pool.Get().Sub(a.y, a.x)
+	t2 := pool.Get().Add(a.x, a.y)
+	ty := pool.Get().Mul(t1, t2)
+	ty.Mod(ty, p)
+
+	t1.Mul(a.x, a.y)
+	t1.Lsh(t1, 1)
+
+	e.x.Mod(t1, p)
+	e.y.Set(ty)
+
+	pool.Put(t1)
+	pool.Put(t2)
+	pool.Put(ty)
+
+	return e
+}
+
+func (e *gfP2) Invert(a *gfP2, pool *bnPool) *gfP2 {
+	// See "Implementing cryptographic pairings", M. Scott, section 3.2.
+	// ftp://136.206.11.249/pub/crypto/pairings.pdf
+	t := pool.Get()
+	t.Mul(a.y, a.y)
+	t2 := pool.Get()
+	t2.Mul(a.x, a.x)
+	t.Add(t, t2)
+
+	inv := pool.Get()
+	inv.ModInverse(t, p)
+
+	e.x.Neg(a.x)
+	e.x.Mul(e.x, inv)
+	e.x.Mod(e.x, p)
+
+	e.y.Mul(a.y, inv)
+	e.y.Mod(e.y, p)
+
+	pool.Put(t)
+	pool.Put(t2)
+	pool.Put(inv)
+
+	return e
+}
diff --git a/vendor/golang.org/x/crypto/bn256/gfp6.go b/vendor/golang.org/x/crypto/bn256/gfp6.go
new file mode 100644
index 0000000000..f98ae782cc
--- /dev/null
+++ b/vendor/golang.org/x/crypto/bn256/gfp6.go
@@ -0,0 +1,296 @@
+// 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 bn256
+
+// For details of the algorithms used, see "Multiplication and Squaring on
+// Pairing-Friendly Fields, Devegili et al.
+// http://eprint.iacr.org/2006/471.pdf.
+
+import (
+	"math/big"
+)
+
+// gfP6 implements the field of size p⁶ as a cubic extension of gfP2 where τ³=ξ
+// and ξ=i+3.
+type gfP6 struct {
+	x, y, z *gfP2 // value is xτ² + yτ + z
+}
+
+func newGFp6(pool *bnPool) *gfP6 {
+	return &gfP6{newGFp2(pool), newGFp2(pool), newGFp2(pool)}
+}
+
+func (e *gfP6) String() string {
+	return "(" + e.x.String() + "," + e.y.String() + "," + e.z.String() + ")"
+}
+
+func (e *gfP6) Put(pool *bnPool) {
+	e.x.Put(pool)
+	e.y.Put(pool)
+	e.z.Put(pool)
+}
+
+func (e *gfP6) Set(a *gfP6) *gfP6 {
+	e.x.Set(a.x)
+	e.y.Set(a.y)
+	e.z.Set(a.z)
+	return e
+}
+
+func (e *gfP6) SetZero() *gfP6 {
+	e.x.SetZero()
+	e.y.SetZero()
+	e.z.SetZero()
+	return e
+}
+
+func (e *gfP6) SetOne() *gfP6 {
+	e.x.SetZero()
+	e.y.SetZero()
+	e.z.SetOne()
+	return e
+}
+
+func (e *gfP6) Minimal() {
+	e.x.Minimal()
+	e.y.Minimal()
+	e.z.Minimal()
+}
+
+func (e *gfP6) IsZero() bool {
+	return e.x.IsZero() && e.y.IsZero() && e.z.IsZero()
+}
+
+func (e *gfP6) IsOne() bool {
+	return e.x.IsZero() && e.y.IsZero() && e.z.IsOne()
+}
+
+func (e *gfP6) Negative(a *gfP6) *gfP6 {
+	e.x.Negative(a.x)
+	e.y.Negative(a.y)
+	e.z.Negative(a.z)
+	return e
+}
+
+func (e *gfP6) Frobenius(a *gfP6, pool *bnPool) *gfP6 {
+	e.x.Conjugate(a.x)
+	e.y.Conjugate(a.y)
+	e.z.Conjugate(a.z)
+
+	e.x.Mul(e.x, xiTo2PMinus2Over3, pool)
+	e.y.Mul(e.y, xiToPMinus1Over3, pool)
+	return e
+}
+
+// FrobeniusP2 computes (xτ²+yτ+z)^(p²) = xτ^(2p²) + yτ^(p²) + z
+func (e *gfP6) FrobeniusP2(a *gfP6) *gfP6 {
+	// τ^(2p²) = τ²τ^(2p²-2) = τ²ξ^((2p²-2)/3)
+	e.x.MulScalar(a.x, xiTo2PSquaredMinus2Over3)
+	// τ^(p²) = ττ^(p²-1) = τξ^((p²-1)/3)
+	e.y.MulScalar(a.y, xiToPSquaredMinus1Over3)
+	e.z.Set(a.z)
+	return e
+}
+
+func (e *gfP6) Add(a, b *gfP6) *gfP6 {
+	e.x.Add(a.x, b.x)
+	e.y.Add(a.y, b.y)
+	e.z.Add(a.z, b.z)
+	return e
+}
+
+func (e *gfP6) Sub(a, b *gfP6) *gfP6 {
+	e.x.Sub(a.x, b.x)
+	e.y.Sub(a.y, b.y)
+	e.z.Sub(a.z, b.z)
+	return e
+}
+
+func (e *gfP6) Double(a *gfP6) *gfP6 {
+	e.x.Double(a.x)
+	e.y.Double(a.y)
+	e.z.Double(a.z)
+	return e
+}
+
+func (e *gfP6) Mul(a, b *gfP6, pool *bnPool) *gfP6 {
+	// "Multiplication and Squaring on Pairing-Friendly Fields"
+	// Section 4, Karatsuba method.
+	// http://eprint.iacr.org/2006/471.pdf
+
+	v0 := newGFp2(pool)
+	v0.Mul(a.z, b.z, pool)
+	v1 := newGFp2(pool)
+	v1.Mul(a.y, b.y, pool)
+	v2 := newGFp2(pool)
+	v2.Mul(a.x, b.x, pool)
+
+	t0 := newGFp2(pool)
+	t0.Add(a.x, a.y)
+	t1 := newGFp2(pool)
+	t1.Add(b.x, b.y)
+	tz := newGFp2(pool)
+	tz.Mul(t0, t1, pool)
+
+	tz.Sub(tz, v1)
+	tz.Sub(tz, v2)
+	tz.MulXi(tz, pool)
+	tz.Add(tz, v0)
+
+	t0.Add(a.y, a.z)
+	t1.Add(b.y, b.z)
+	ty := newGFp2(pool)
+	ty.Mul(t0, t1, pool)
+	ty.Sub(ty, v0)
+	ty.Sub(ty, v1)
+	t0.MulXi(v2, pool)
+	ty.Add(ty, t0)
+
+	t0.Add(a.x, a.z)
+	t1.Add(b.x, b.z)
+	tx := newGFp2(pool)
+	tx.Mul(t0, t1, pool)
+	tx.Sub(tx, v0)
+	tx.Add(tx, v1)
+	tx.Sub(tx, v2)
+
+	e.x.Set(tx)
+	e.y.Set(ty)
+	e.z.Set(tz)
+
+	t0.Put(pool)
+	t1.Put(pool)
+	tx.Put(pool)
+	ty.Put(pool)
+	tz.Put(pool)
+	v0.Put(pool)
+	v1.Put(pool)
+	v2.Put(pool)
+	return e
+}
+
+func (e *gfP6) MulScalar(a *gfP6, b *gfP2, pool *bnPool) *gfP6 {
+	e.x.Mul(a.x, b, pool)
+	e.y.Mul(a.y, b, pool)
+	e.z.Mul(a.z, b, pool)
+	return e
+}
+
+func (e *gfP6) MulGFP(a *gfP6, b *big.Int) *gfP6 {
+	e.x.MulScalar(a.x, b)
+	e.y.MulScalar(a.y, b)
+	e.z.MulScalar(a.z, b)
+	return e
+}
+
+// MulTau computes τ·(aτ²+bτ+c) = bτ²+cτ+aξ
+func (e *gfP6) MulTau(a *gfP6, pool *bnPool) {
+	tz := newGFp2(pool)
+	tz.MulXi(a.x, pool)
+	ty := newGFp2(pool)
+	ty.Set(a.y)
+	e.y.Set(a.z)
+	e.x.Set(ty)
+	e.z.Set(tz)
+	tz.Put(pool)
+	ty.Put(pool)
+}
+
+func (e *gfP6) Square(a *gfP6, pool *bnPool) *gfP6 {
+	v0 := newGFp2(pool).Square(a.z, pool)
+	v1 := newGFp2(pool).Square(a.y, pool)
+	v2 := newGFp2(pool).Square(a.x, pool)
+
+	c0 := newGFp2(pool).Add(a.x, a.y)
+	c0.Square(c0, pool)
+	c0.Sub(c0, v1)
+	c0.Sub(c0, v2)
+	c0.MulXi(c0, pool)
+	c0.Add(c0, v0)
+
+	c1 := newGFp2(pool).Add(a.y, a.z)
+	c1.Square(c1, pool)
+	c1.Sub(c1, v0)
+	c1.Sub(c1, v1)
+	xiV2 := newGFp2(pool).MulXi(v2, pool)
+	c1.Add(c1, xiV2)
+
+	c2 := newGFp2(pool).Add(a.x, a.z)
+	c2.Square(c2, pool)
+	c2.Sub(c2, v0)
+	c2.Add(c2, v1)
+	c2.Sub(c2, v2)
+
+	e.x.Set(c2)
+	e.y.Set(c1)
+	e.z.Set(c0)
+
+	v0.Put(pool)
+	v1.Put(pool)
+	v2.Put(pool)
+	c0.Put(pool)
+	c1.Put(pool)
+	c2.Put(pool)
+	xiV2.Put(pool)
+
+	return e
+}
+
+func (e *gfP6) Invert(a *gfP6, pool *bnPool) *gfP6 {
+	// See "Implementing cryptographic pairings", M. Scott, section 3.2.
+	// ftp://136.206.11.249/pub/crypto/pairings.pdf
+
+	// Here we can give a short explanation of how it works: let j be a cubic root of
+	// unity in GF(p²) so that 1+j+j²=0.
+	// Then (xτ² + yτ + z)(xj²τ² + yjτ + z)(xjτ² + yj²τ + z)
+	// = (xτ² + yτ + z)(Cτ²+Bτ+A)
+	// = (x³ξ²+y³ξ+z³-3ξxyz) = F is an element of the base field (the norm).
+	//
+	// On the other hand (xj²τ² + yjτ + z)(xjτ² + yj²τ + z)
+	// = τ²(y²-ξxz) + τ(ξx²-yz) + (z²-ξxy)
+	//
+	// So that's why A = (z²-ξxy), B = (ξx²-yz), C = (y²-ξxz)
+	t1 := newGFp2(pool)
+
+	A := newGFp2(pool)
+	A.Square(a.z, pool)
+	t1.Mul(a.x, a.y, pool)
+	t1.MulXi(t1, pool)
+	A.Sub(A, t1)
+
+	B := newGFp2(pool)
+	B.Square(a.x, pool)
+	B.MulXi(B, pool)
+	t1.Mul(a.y, a.z, pool)
+	B.Sub(B, t1)
+
+	C := newGFp2(pool)
+	C.Square(a.y, pool)
+	t1.Mul(a.x, a.z, pool)
+	C.Sub(C, t1)
+
+	F := newGFp2(pool)
+	F.Mul(C, a.y, pool)
+	F.MulXi(F, pool)
+	t1.Mul(A, a.z, pool)
+	F.Add(F, t1)
+	t1.Mul(B, a.x, pool)
+	t1.MulXi(t1, pool)
+	F.Add(F, t1)
+
+	F.Invert(F, pool)
+
+	e.x.Mul(C, F, pool)
+	e.y.Mul(B, F, pool)
+	e.z.Mul(A, F, pool)
+
+	t1.Put(pool)
+	A.Put(pool)
+	B.Put(pool)
+	C.Put(pool)
+	F.Put(pool)
+
+	return e
+}
diff --git a/vendor/golang.org/x/crypto/bn256/optate.go b/vendor/golang.org/x/crypto/bn256/optate.go
new file mode 100644
index 0000000000..7ae0746eb1
--- /dev/null
+++ b/vendor/golang.org/x/crypto/bn256/optate.go
@@ -0,0 +1,395 @@
+// 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 bn256
+
+func lineFunctionAdd(r, p *twistPoint, q *curvePoint, r2 *gfP2, pool *bnPool) (a, b, c *gfP2, rOut *twistPoint) {
+	// See the mixed addition algorithm from "Faster Computation of the
+	// Tate Pairing", http://arxiv.org/pdf/0904.0854v3.pdf
+
+	B := newGFp2(pool).Mul(p.x, r.t, pool)
+
+	D := newGFp2(pool).Add(p.y, r.z)
+	D.Square(D, pool)
+	D.Sub(D, r2)
+	D.Sub(D, r.t)
+	D.Mul(D, r.t, pool)
+
+	H := newGFp2(pool).Sub(B, r.x)
+	I := newGFp2(pool).Square(H, pool)
+
+	E := newGFp2(pool).Add(I, I)
+	E.Add(E, E)
+
+	J := newGFp2(pool).Mul(H, E, pool)
+
+	L1 := newGFp2(pool).Sub(D, r.y)
+	L1.Sub(L1, r.y)
+
+	V := newGFp2(pool).Mul(r.x, E, pool)
+
+	rOut = newTwistPoint(pool)
+	rOut.x.Square(L1, pool)
+	rOut.x.Sub(rOut.x, J)
+	rOut.x.Sub(rOut.x, V)
+	rOut.x.Sub(rOut.x, V)
+
+	rOut.z.Add(r.z, H)
+	rOut.z.Square(rOut.z, pool)
+	rOut.z.Sub(rOut.z, r.t)
+	rOut.z.Sub(rOut.z, I)
+
+	t := newGFp2(pool).Sub(V, rOut.x)
+	t.Mul(t, L1, pool)
+	t2 := newGFp2(pool).Mul(r.y, J, pool)
+	t2.Add(t2, t2)
+	rOut.y.Sub(t, t2)
+
+	rOut.t.Square(rOut.z, pool)
+
+	t.Add(p.y, rOut.z)
+	t.Square(t, pool)
+	t.Sub(t, r2)
+	t.Sub(t, rOut.t)
+
+	t2.Mul(L1, p.x, pool)
+	t2.Add(t2, t2)
+	a = newGFp2(pool)
+	a.Sub(t2, t)
+
+	c = newGFp2(pool)
+	c.MulScalar(rOut.z, q.y)
+	c.Add(c, c)
+
+	b = newGFp2(pool)
+	b.SetZero()
+	b.Sub(b, L1)
+	b.MulScalar(b, q.x)
+	b.Add(b, b)
+
+	B.Put(pool)
+	D.Put(pool)
+	H.Put(pool)
+	I.Put(pool)
+	E.Put(pool)
+	J.Put(pool)
+	L1.Put(pool)
+	V.Put(pool)
+	t.Put(pool)
+	t2.Put(pool)
+
+	return
+}
+
+func lineFunctionDouble(r *twistPoint, q *curvePoint, pool *bnPool) (a, b, c *gfP2, rOut *twistPoint) {
+	// See the doubling algorithm for a=0 from "Faster Computation of the
+	// Tate Pairing", http://arxiv.org/pdf/0904.0854v3.pdf
+
+	A := newGFp2(pool).Square(r.x, pool)
+	B := newGFp2(pool).Square(r.y, pool)
+	C := newGFp2(pool).Square(B, pool)
+
+	D := newGFp2(pool).Add(r.x, B)
+	D.Square(D, pool)
+	D.Sub(D, A)
+	D.Sub(D, C)
+	D.Add(D, D)
+
+	E := newGFp2(pool).Add(A, A)
+	E.Add(E, A)
+
+	G := newGFp2(pool).Square(E, pool)
+
+	rOut = newTwistPoint(pool)
+	rOut.x.Sub(G, D)
+	rOut.x.Sub(rOut.x, D)
+
+	rOut.z.Add(r.y, r.z)
+	rOut.z.Square(rOut.z, pool)
+	rOut.z.Sub(rOut.z, B)
+	rOut.z.Sub(rOut.z, r.t)
+
+	rOut.y.Sub(D, rOut.x)
+	rOut.y.Mul(rOut.y, E, pool)
+	t := newGFp2(pool).Add(C, C)
+	t.Add(t, t)
+	t.Add(t, t)
+	rOut.y.Sub(rOut.y, t)
+
+	rOut.t.Square(rOut.z, pool)
+
+	t.Mul(E, r.t, pool)
+	t.Add(t, t)
+	b = newGFp2(pool)
+	b.SetZero()
+	b.Sub(b, t)
+	b.MulScalar(b, q.x)
+
+	a = newGFp2(pool)
+	a.Add(r.x, E)
+	a.Square(a, pool)
+	a.Sub(a, A)
+	a.Sub(a, G)
+	t.Add(B, B)
+	t.Add(t, t)
+	a.Sub(a, t)
+
+	c = newGFp2(pool)
+	c.Mul(rOut.z, r.t, pool)
+	c.Add(c, c)
+	c.MulScalar(c, q.y)
+
+	A.Put(pool)
+	B.Put(pool)
+	C.Put(pool)
+	D.Put(pool)
+	E.Put(pool)
+	G.Put(pool)
+	t.Put(pool)
+
+	return
+}
+
+func mulLine(ret *gfP12, a, b, c *gfP2, pool *bnPool) {
+	a2 := newGFp6(pool)
+	a2.x.SetZero()
+	a2.y.Set(a)
+	a2.z.Set(b)
+	a2.Mul(a2, ret.x, pool)
+	t3 := newGFp6(pool).MulScalar(ret.y, c, pool)
+
+	t := newGFp2(pool)
+	t.Add(b, c)
+	t2 := newGFp6(pool)
+	t2.x.SetZero()
+	t2.y.Set(a)
+	t2.z.Set(t)
+	ret.x.Add(ret.x, ret.y)
+
+	ret.y.Set(t3)
+
+	ret.x.Mul(ret.x, t2, pool)
+	ret.x.Sub(ret.x, a2)
+	ret.x.Sub(ret.x, ret.y)
+	a2.MulTau(a2, pool)
+	ret.y.Add(ret.y, a2)
+
+	a2.Put(pool)
+	t3.Put(pool)
+	t2.Put(pool)
+	t.Put(pool)
+}
+
+// sixuPlus2NAF is 6u+2 in non-adjacent form.
+var sixuPlus2NAF = []int8{0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, -1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, -1, 0, 1, 0, 0, 0, 1, 0, -1, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, -1, 0, 0, 0, 0, 1, 0, 0, 0, 1}
+
+// miller implements the Miller loop for calculating the Optimal Ate pairing.
+// See algorithm 1 from http://cryptojedi.org/papers/dclxvi-20100714.pdf
+func miller(q *twistPoint, p *curvePoint, pool *bnPool) *gfP12 {
+	ret := newGFp12(pool)
+	ret.SetOne()
+
+	aAffine := newTwistPoint(pool)
+	aAffine.Set(q)
+	aAffine.MakeAffine(pool)
+
+	bAffine := newCurvePoint(pool)
+	bAffine.Set(p)
+	bAffine.MakeAffine(pool)
+
+	minusA := newTwistPoint(pool)
+	minusA.Negative(aAffine, pool)
+
+	r := newTwistPoint(pool)
+	r.Set(aAffine)
+
+	r2 := newGFp2(pool)
+	r2.Square(aAffine.y, pool)
+
+	for i := len(sixuPlus2NAF) - 1; i > 0; i-- {
+		a, b, c, newR := lineFunctionDouble(r, bAffine, pool)
+		if i != len(sixuPlus2NAF)-1 {
+			ret.Square(ret, pool)
+		}
+
+		mulLine(ret, a, b, c, pool)
+		a.Put(pool)
+		b.Put(pool)
+		c.Put(pool)
+		r.Put(pool)
+		r = newR
+
+		switch sixuPlus2NAF[i-1] {
+		case 1:
+			a, b, c, newR = lineFunctionAdd(r, aAffine, bAffine, r2, pool)
+		case -1:
+			a, b, c, newR = lineFunctionAdd(r, minusA, bAffine, r2, pool)
+		default:
+			continue
+		}
+
+		mulLine(ret, a, b, c, pool)
+		a.Put(pool)
+		b.Put(pool)
+		c.Put(pool)
+		r.Put(pool)
+		r = newR
+	}
+
+	// In order to calculate Q1 we have to convert q from the sextic twist
+	// to the full GF(p^12) group, apply the Frobenius there, and convert
+	// back.
+	//
+	// The twist isomorphism is (x', y') -> (xω², yω³). If we consider just
+	// x for a moment, then after applying the Frobenius, we have x̄ω^(2p)
+	// where x̄ is the conjugate of x. If we are going to apply the inverse
+	// isomorphism we need a value with a single coefficient of ω² so we
+	// rewrite this as x̄ω^(2p-2)ω². ξ⁶ = ω and, due to the construction of
+	// p, 2p-2 is a multiple of six. Therefore we can rewrite as
+	// x̄ξ^((p-1)/3)ω² and applying the inverse isomorphism eliminates the
+	// ω².
+	//
+	// A similar argument can be made for the y value.
+
+	q1 := newTwistPoint(pool)
+	q1.x.Conjugate(aAffine.x)
+	q1.x.Mul(q1.x, xiToPMinus1Over3, pool)
+	q1.y.Conjugate(aAffine.y)
+	q1.y.Mul(q1.y, xiToPMinus1Over2, pool)
+	q1.z.SetOne()
+	q1.t.SetOne()
+
+	// For Q2 we are applying the p² Frobenius. The two conjugations cancel
+	// out and we are left only with the factors from the isomorphism. In
+	// the case of x, we end up with a pure number which is why
+	// xiToPSquaredMinus1Over3 is ∈ GF(p). With y we get a factor of -1. We
+	// ignore this to end up with -Q2.
+
+	minusQ2 := newTwistPoint(pool)
+	minusQ2.x.MulScalar(aAffine.x, xiToPSquaredMinus1Over3)
+	minusQ2.y.Set(aAffine.y)
+	minusQ2.z.SetOne()
+	minusQ2.t.SetOne()
+
+	r2.Square(q1.y, pool)
+	a, b, c, newR := lineFunctionAdd(r, q1, bAffine, r2, pool)
+	mulLine(ret, a, b, c, pool)
+	a.Put(pool)
+	b.Put(pool)
+	c.Put(pool)
+	r.Put(pool)
+	r = newR
+
+	r2.Square(minusQ2.y, pool)
+	a, b, c, newR = lineFunctionAdd(r, minusQ2, bAffine, r2, pool)
+	mulLine(ret, a, b, c, pool)
+	a.Put(pool)
+	b.Put(pool)
+	c.Put(pool)
+	r.Put(pool)
+	r = newR
+
+	aAffine.Put(pool)
+	bAffine.Put(pool)
+	minusA.Put(pool)
+	r.Put(pool)
+	r2.Put(pool)
+
+	return ret
+}
+
+// finalExponentiation computes the (p¹²-1)/Order-th power of an element of
+// GF(p¹²) to obtain an element of GT (steps 13-15 of algorithm 1 from
+// http://cryptojedi.org/papers/dclxvi-20100714.pdf)
+func finalExponentiation(in *gfP12, pool *bnPool) *gfP12 {
+	t1 := newGFp12(pool)
+
+	// This is the p^6-Frobenius
+	t1.x.Negative(in.x)
+	t1.y.Set(in.y)
+
+	inv := newGFp12(pool)
+	inv.Invert(in, pool)
+	t1.Mul(t1, inv, pool)
+
+	t2 := newGFp12(pool).FrobeniusP2(t1, pool)
+	t1.Mul(t1, t2, pool)
+
+	fp := newGFp12(pool).Frobenius(t1, pool)
+	fp2 := newGFp12(pool).FrobeniusP2(t1, pool)
+	fp3 := newGFp12(pool).Frobenius(fp2, pool)
+
+	fu, fu2, fu3 := newGFp12(pool), newGFp12(pool), newGFp12(pool)
+	fu.Exp(t1, u, pool)
+	fu2.Exp(fu, u, pool)
+	fu3.Exp(fu2, u, pool)
+
+	y3 := newGFp12(pool).Frobenius(fu, pool)
+	fu2p := newGFp12(pool).Frobenius(fu2, pool)
+	fu3p := newGFp12(pool).Frobenius(fu3, pool)
+	y2 := newGFp12(pool).FrobeniusP2(fu2, pool)
+
+	y0 := newGFp12(pool)
+	y0.Mul(fp, fp2, pool)
+	y0.Mul(y0, fp3, pool)
+
+	y1, y4, y5 := newGFp12(pool), newGFp12(pool), newGFp12(pool)
+	y1.Conjugate(t1)
+	y5.Conjugate(fu2)
+	y3.Conjugate(y3)
+	y4.Mul(fu, fu2p, pool)
+	y4.Conjugate(y4)
+
+	y6 := newGFp12(pool)
+	y6.Mul(fu3, fu3p, pool)
+	y6.Conjugate(y6)
+
+	t0 := newGFp12(pool)
+	t0.Square(y6, pool)
+	t0.Mul(t0, y4, pool)
+	t0.Mul(t0, y5, pool)
+	t1.Mul(y3, y5, pool)
+	t1.Mul(t1, t0, pool)
+	t0.Mul(t0, y2, pool)
+	t1.Square(t1, pool)
+	t1.Mul(t1, t0, pool)
+	t1.Square(t1, pool)
+	t0.Mul(t1, y1, pool)
+	t1.Mul(t1, y0, pool)
+	t0.Square(t0, pool)
+	t0.Mul(t0, t1, pool)
+
+	inv.Put(pool)
+	t1.Put(pool)
+	t2.Put(pool)
+	fp.Put(pool)
+	fp2.Put(pool)
+	fp3.Put(pool)
+	fu.Put(pool)
+	fu2.Put(pool)
+	fu3.Put(pool)
+	fu2p.Put(pool)
+	fu3p.Put(pool)
+	y0.Put(pool)
+	y1.Put(pool)
+	y2.Put(pool)
+	y3.Put(pool)
+	y4.Put(pool)
+	y5.Put(pool)
+	y6.Put(pool)
+
+	return t0
+}
+
+func optimalAte(a *twistPoint, b *curvePoint, pool *bnPool) *gfP12 {
+	e := miller(a, b, pool)
+	ret := finalExponentiation(e, pool)
+	e.Put(pool)
+
+	if a.IsInfinity() || b.IsInfinity() {
+		ret.SetOne()
+	}
+
+	return ret
+}
diff --git a/vendor/golang.org/x/crypto/bn256/twist.go b/vendor/golang.org/x/crypto/bn256/twist.go
new file mode 100644
index 0000000000..056d80f18f
--- /dev/null
+++ b/vendor/golang.org/x/crypto/bn256/twist.go
@@ -0,0 +1,258 @@
+// 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 bn256
+
+import (
+	"math/big"
+)
+
+// twistPoint implements the elliptic curve y²=x³+3/ξ over GF(p²). Points are
+// kept in Jacobian form and t=z² when valid. The group G₂ is the set of
+// n-torsion points of this curve over GF(p²) (where n = Order)
+type twistPoint struct {
+	x, y, z, t *gfP2
+}
+
+var twistB = &gfP2{
+	bigFromBase10("6500054969564660373279643874235990574282535810762300357187714502686418407178"),
+	bigFromBase10("45500384786952622612957507119651934019977750675336102500314001518804928850249"),
+}
+
+// twistGen is the generator of group G₂.
+var twistGen = &twistPoint{
+	&gfP2{
+		bigFromBase10("21167961636542580255011770066570541300993051739349375019639421053990175267184"),
+		bigFromBase10("64746500191241794695844075326670126197795977525365406531717464316923369116492"),
+	},
+	&gfP2{
+		bigFromBase10("20666913350058776956210519119118544732556678129809273996262322366050359951122"),
+		bigFromBase10("17778617556404439934652658462602675281523610326338642107814333856843981424549"),
+	},
+	&gfP2{
+		bigFromBase10("0"),
+		bigFromBase10("1"),
+	},
+	&gfP2{
+		bigFromBase10("0"),
+		bigFromBase10("1"),
+	},
+}
+
+func newTwistPoint(pool *bnPool) *twistPoint {
+	return &twistPoint{
+		newGFp2(pool),
+		newGFp2(pool),
+		newGFp2(pool),
+		newGFp2(pool),
+	}
+}
+
+func (c *twistPoint) String() string {
+	return "(" + c.x.String() + ", " + c.y.String() + ", " + c.z.String() + ")"
+}
+
+func (c *twistPoint) Put(pool *bnPool) {
+	c.x.Put(pool)
+	c.y.Put(pool)
+	c.z.Put(pool)
+	c.t.Put(pool)
+}
+
+func (c *twistPoint) Set(a *twistPoint) {
+	c.x.Set(a.x)
+	c.y.Set(a.y)
+	c.z.Set(a.z)
+	c.t.Set(a.t)
+}
+
+// IsOnCurve returns true iff c is on the curve where c must be in affine form.
+func (c *twistPoint) IsOnCurve() bool {
+	pool := new(bnPool)
+	yy := newGFp2(pool).Square(c.y, pool)
+	xxx := newGFp2(pool).Square(c.x, pool)
+	xxx.Mul(xxx, c.x, pool)
+	yy.Sub(yy, xxx)
+	yy.Sub(yy, twistB)
+	yy.Minimal()
+	return yy.x.Sign() == 0 && yy.y.Sign() == 0
+}
+
+func (c *twistPoint) SetInfinity() {
+	c.z.SetZero()
+}
+
+func (c *twistPoint) IsInfinity() bool {
+	return c.z.IsZero()
+}
+
+func (c *twistPoint) Add(a, b *twistPoint, pool *bnPool) {
+	// For additional comments, see the same function in curve.go.
+
+	if a.IsInfinity() {
+		c.Set(b)
+		return
+	}
+	if b.IsInfinity() {
+		c.Set(a)
+		return
+	}
+
+	// See http://hyperelliptic.org/EFD/g1p/auto-code/shortw/jacobian-0/addition/add-2007-bl.op3
+	z1z1 := newGFp2(pool).Square(a.z, pool)
+	z2z2 := newGFp2(pool).Square(b.z, pool)
+	u1 := newGFp2(pool).Mul(a.x, z2z2, pool)
+	u2 := newGFp2(pool).Mul(b.x, z1z1, pool)
+
+	t := newGFp2(pool).Mul(b.z, z2z2, pool)
+	s1 := newGFp2(pool).Mul(a.y, t, pool)
+
+	t.Mul(a.z, z1z1, pool)
+	s2 := newGFp2(pool).Mul(b.y, t, pool)
+
+	h := newGFp2(pool).Sub(u2, u1)
+	xEqual := h.IsZero()
+
+	t.Add(h, h)
+	i := newGFp2(pool).Square(t, pool)
+	j := newGFp2(pool).Mul(h, i, pool)
+
+	t.Sub(s2, s1)
+	yEqual := t.IsZero()
+	if xEqual && yEqual {
+		c.Double(a, pool)
+		return
+	}
+	r := newGFp2(pool).Add(t, t)
+
+	v := newGFp2(pool).Mul(u1, i, pool)
+
+	t4 := newGFp2(pool).Square(r, pool)
+	t.Add(v, v)
+	t6 := newGFp2(pool).Sub(t4, j)
+	c.x.Sub(t6, t)
+
+	t.Sub(v, c.x)       // t7
+	t4.Mul(s1, j, pool) // t8
+	t6.Add(t4, t4)      // t9
+	t4.Mul(r, t, pool)  // t10
+	c.y.Sub(t4, t6)
+
+	t.Add(a.z, b.z)    // t11
+	t4.Square(t, pool) // t12
+	t.Sub(t4, z1z1)    // t13
+	t4.Sub(t, z2z2)    // t14
+	c.z.Mul(t4, h, pool)
+
+	z1z1.Put(pool)
+	z2z2.Put(pool)
+	u1.Put(pool)
+	u2.Put(pool)
+	t.Put(pool)
+	s1.Put(pool)
+	s2.Put(pool)
+	h.Put(pool)
+	i.Put(pool)
+	j.Put(pool)
+	r.Put(pool)
+	v.Put(pool)
+	t4.Put(pool)
+	t6.Put(pool)
+}
+
+func (c *twistPoint) Double(a *twistPoint, pool *bnPool) {
+	// See http://hyperelliptic.org/EFD/g1p/auto-code/shortw/jacobian-0/doubling/dbl-2009-l.op3
+	A := newGFp2(pool).Square(a.x, pool)
+	B := newGFp2(pool).Square(a.y, pool)
+	C := newGFp2(pool).Square(B, pool)
+
+	t := newGFp2(pool).Add(a.x, B)
+	t2 := newGFp2(pool).Square(t, pool)
+	t.Sub(t2, A)
+	t2.Sub(t, C)
+	d := newGFp2(pool).Add(t2, t2)
+	t.Add(A, A)
+	e := newGFp2(pool).Add(t, A)
+	f := newGFp2(pool).Square(e, pool)
+
+	t.Add(d, d)
+	c.x.Sub(f, t)
+
+	t.Add(C, C)
+	t2.Add(t, t)
+	t.Add(t2, t2)
+	c.y.Sub(d, c.x)
+	t2.Mul(e, c.y, pool)
+	c.y.Sub(t2, t)
+
+	t.Mul(a.y, a.z, pool)
+	c.z.Add(t, t)
+
+	A.Put(pool)
+	B.Put(pool)
+	C.Put(pool)
+	t.Put(pool)
+	t2.Put(pool)
+	d.Put(pool)
+	e.Put(pool)
+	f.Put(pool)
+}
+
+func (c *twistPoint) Mul(a *twistPoint, scalar *big.Int, pool *bnPool) *twistPoint {
+	sum := newTwistPoint(pool)
+	sum.SetInfinity()
+	t := newTwistPoint(pool)
+
+	for i := scalar.BitLen(); i >= 0; i-- {
+		t.Double(sum, pool)
+		if scalar.Bit(i) != 0 {
+			sum.Add(t, a, pool)
+		} else {
+			sum.Set(t)
+		}
+	}
+
+	c.Set(sum)
+	sum.Put(pool)
+	t.Put(pool)
+	return c
+}
+
+// MakeAffine converts c to affine form and returns c. If c is ∞, then it sets
+// c to 0 : 1 : 0.
+func (c *twistPoint) MakeAffine(pool *bnPool) *twistPoint {
+	if c.z.IsOne() {
+		return c
+	}
+	if c.IsInfinity() {
+		c.x.SetZero()
+		c.y.SetOne()
+		c.z.SetZero()
+		c.t.SetZero()
+		return c
+	}
+
+	zInv := newGFp2(pool).Invert(c.z, pool)
+	t := newGFp2(pool).Mul(c.y, zInv, pool)
+	zInv2 := newGFp2(pool).Square(zInv, pool)
+	c.y.Mul(t, zInv2, pool)
+	t.Mul(c.x, zInv2, pool)
+	c.x.Set(t)
+	c.z.SetOne()
+	c.t.SetOne()
+
+	zInv.Put(pool)
+	t.Put(pool)
+	zInv2.Put(pool)
+
+	return c
+}
+
+func (c *twistPoint) Negative(a *twistPoint, pool *bnPool) {
+	c.x.Set(a.x)
+	c.y.SetZero()
+	c.y.Sub(c.y, a.y)
+	c.z.Set(a.z)
+	c.t.SetZero()
+}
diff --git a/vendor/golang.org/x/crypto/cast5/cast5.go b/vendor/golang.org/x/crypto/cast5/cast5.go
new file mode 100644
index 0000000000..ddcbeb6f2a
--- /dev/null
+++ b/vendor/golang.org/x/crypto/cast5/cast5.go
@@ -0,0 +1,533 @@
+// Copyright 2010 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 cast5 implements CAST5, as defined in RFC 2144.
+//
+// CAST5 is a legacy cipher and its short block size makes it vulnerable to
+// birthday bound attacks (see https://sweet32.info). It should only be used
+// where compatibility with legacy systems, not security, is the goal.
+//
+// Deprecated: any new system should use AES (from crypto/aes, if necessary in
+// an AEAD mode like crypto/cipher.NewGCM) or XChaCha20-Poly1305 (from
+// golang.org/x/crypto/chacha20poly1305).
+package cast5 // import "golang.org/x/crypto/cast5"
+
+import "errors"
+
+const BlockSize = 8
+const KeySize = 16
+
+type Cipher struct {
+	masking [16]uint32
+	rotate  [16]uint8
+}
+
+func NewCipher(key []byte) (c *Cipher, err error) {
+	if len(key) != KeySize {
+		return nil, errors.New("CAST5: keys must be 16 bytes")
+	}
+
+	c = new(Cipher)
+	c.keySchedule(key)
+	return
+}
+
+func (c *Cipher) BlockSize() int {
+	return BlockSize
+}
+
+func (c *Cipher) Encrypt(dst, src []byte) {
+	l := uint32(src[0])<<24 | uint32(src[1])<<16 | uint32(src[2])<<8 | uint32(src[3])
+	r := uint32(src[4])<<24 | uint32(src[5])<<16 | uint32(src[6])<<8 | uint32(src[7])
+
+	l, r = r, l^f1(r, c.masking[0], c.rotate[0])
+	l, r = r, l^f2(r, c.masking[1], c.rotate[1])
+	l, r = r, l^f3(r, c.masking[2], c.rotate[2])
+	l, r = r, l^f1(r, c.masking[3], c.rotate[3])
+
+	l, r = r, l^f2(r, c.masking[4], c.rotate[4])
+	l, r = r, l^f3(r, c.masking[5], c.rotate[5])
+	l, r = r, l^f1(r, c.masking[6], c.rotate[6])
+	l, r = r, l^f2(r, c.masking[7], c.rotate[7])
+
+	l, r = r, l^f3(r, c.masking[8], c.rotate[8])
+	l, r = r, l^f1(r, c.masking[9], c.rotate[9])
+	l, r = r, l^f2(r, c.masking[10], c.rotate[10])
+	l, r = r, l^f3(r, c.masking[11], c.rotate[11])
+
+	l, r = r, l^f1(r, c.masking[12], c.rotate[12])
+	l, r = r, l^f2(r, c.masking[13], c.rotate[13])
+	l, r = r, l^f3(r, c.masking[14], c.rotate[14])
+	l, r = r, l^f1(r, c.masking[15], c.rotate[15])
+
+	dst[0] = uint8(r >> 24)
+	dst[1] = uint8(r >> 16)
+	dst[2] = uint8(r >> 8)
+	dst[3] = uint8(r)
+	dst[4] = uint8(l >> 24)
+	dst[5] = uint8(l >> 16)
+	dst[6] = uint8(l >> 8)
+	dst[7] = uint8(l)
+}
+
+func (c *Cipher) Decrypt(dst, src []byte) {
+	l := uint32(src[0])<<24 | uint32(src[1])<<16 | uint32(src[2])<<8 | uint32(src[3])
+	r := uint32(src[4])<<24 | uint32(src[5])<<16 | uint32(src[6])<<8 | uint32(src[7])
+
+	l, r = r, l^f1(r, c.masking[15], c.rotate[15])
+	l, r = r, l^f3(r, c.masking[14], c.rotate[14])
+	l, r = r, l^f2(r, c.masking[13], c.rotate[13])
+	l, r = r, l^f1(r, c.masking[12], c.rotate[12])
+
+	l, r = r, l^f3(r, c.masking[11], c.rotate[11])
+	l, r = r, l^f2(r, c.masking[10], c.rotate[10])
+	l, r = r, l^f1(r, c.masking[9], c.rotate[9])
+	l, r = r, l^f3(r, c.masking[8], c.rotate[8])
+
+	l, r = r, l^f2(r, c.masking[7], c.rotate[7])
+	l, r = r, l^f1(r, c.masking[6], c.rotate[6])
+	l, r = r, l^f3(r, c.masking[5], c.rotate[5])
+	l, r = r, l^f2(r, c.masking[4], c.rotate[4])
+
+	l, r = r, l^f1(r, c.masking[3], c.rotate[3])
+	l, r = r, l^f3(r, c.masking[2], c.rotate[2])
+	l, r = r, l^f2(r, c.masking[1], c.rotate[1])
+	l, r = r, l^f1(r, c.masking[0], c.rotate[0])
+
+	dst[0] = uint8(r >> 24)
+	dst[1] = uint8(r >> 16)
+	dst[2] = uint8(r >> 8)
+	dst[3] = uint8(r)
+	dst[4] = uint8(l >> 24)
+	dst[5] = uint8(l >> 16)
+	dst[6] = uint8(l >> 8)
+	dst[7] = uint8(l)
+}
+
+type keyScheduleA [4][7]uint8
+type keyScheduleB [4][5]uint8
+
+// keyScheduleRound contains the magic values for a round of the key schedule.
+// The keyScheduleA deals with the lines like:
+//   z0z1z2z3 = x0x1x2x3 ^ S5[xD] ^ S6[xF] ^ S7[xC] ^ S8[xE] ^ S7[x8]
+// Conceptually, both x and z are in the same array, x first. The first
+// element describes which word of this array gets written to and the
+// second, which word gets read. So, for the line above, it's "4, 0", because
+// it's writing to the first word of z, which, being after x, is word 4, and
+// reading from the first word of x: word 0.
+//
+// Next are the indexes into the S-boxes. Now the array is treated as bytes. So
+// "xD" is 0xd. The first byte of z is written as "16 + 0", just to be clear
+// that it's z that we're indexing.
+//
+// keyScheduleB deals with lines like:
+//   K1 = S5[z8] ^ S6[z9] ^ S7[z7] ^ S8[z6] ^ S5[z2]
+// "K1" is ignored because key words are always written in order. So the five
+// elements are the S-box indexes. They use the same form as in keyScheduleA,
+// above.
+
+type keyScheduleRound struct{}
+type keySchedule []keyScheduleRound
+
+var schedule = []struct {
+	a keyScheduleA
+	b keyScheduleB
+}{
+	{
+		keyScheduleA{
+			{4, 0, 0xd, 0xf, 0xc, 0xe, 0x8},
+			{5, 2, 16 + 0, 16 + 2, 16 + 1, 16 + 3, 0xa},
+			{6, 3, 16 + 7, 16 + 6, 16 + 5, 16 + 4, 9},
+			{7, 1, 16 + 0xa, 16 + 9, 16 + 0xb, 16 + 8, 0xb},
+		},
+		keyScheduleB{
+			{16 + 8, 16 + 9, 16 + 7, 16 + 6, 16 + 2},
+			{16 + 0xa, 16 + 0xb, 16 + 5, 16 + 4, 16 + 6},
+			{16 + 0xc, 16 + 0xd, 16 + 3, 16 + 2, 16 + 9},
+			{16 + 0xe, 16 + 0xf, 16 + 1, 16 + 0, 16 + 0xc},
+		},
+	},
+	{
+		keyScheduleA{
+			{0, 6, 16 + 5, 16 + 7, 16 + 4, 16 + 6, 16 + 0},
+			{1, 4, 0, 2, 1, 3, 16 + 2},
+			{2, 5, 7, 6, 5, 4, 16 + 1},
+			{3, 7, 0xa, 9, 0xb, 8, 16 + 3},
+		},
+		keyScheduleB{
+			{3, 2, 0xc, 0xd, 8},
+			{1, 0, 0xe, 0xf, 0xd},
+			{7, 6, 8, 9, 3},
+			{5, 4, 0xa, 0xb, 7},
+		},
+	},
+	{
+		keyScheduleA{
+			{4, 0, 0xd, 0xf, 0xc, 0xe, 8},
+			{5, 2, 16 + 0, 16 + 2, 16 + 1, 16 + 3, 0xa},
+			{6, 3, 16 + 7, 16 + 6, 16 + 5, 16 + 4, 9},
+			{7, 1, 16 + 0xa, 16 + 9, 16 + 0xb, 16 + 8, 0xb},
+		},
+		keyScheduleB{
+			{16 + 3, 16 + 2, 16 + 0xc, 16 + 0xd, 16 + 9},
+			{16 + 1, 16 + 0, 16 + 0xe, 16 + 0xf, 16 + 0xc},
+			{16 + 7, 16 + 6, 16 + 8, 16 + 9, 16 + 2},
+			{16 + 5, 16 + 4, 16 + 0xa, 16 + 0xb, 16 + 6},
+		},
+	},
+	{
+		keyScheduleA{
+			{0, 6, 16 + 5, 16 + 7, 16 + 4, 16 + 6, 16 + 0},
+			{1, 4, 0, 2, 1, 3, 16 + 2},
+			{2, 5, 7, 6, 5, 4, 16 + 1},
+			{3, 7, 0xa, 9, 0xb, 8, 16 + 3},
+		},
+		keyScheduleB{
+			{8, 9, 7, 6, 3},
+			{0xa, 0xb, 5, 4, 7},
+			{0xc, 0xd, 3, 2, 8},
+			{0xe, 0xf, 1, 0, 0xd},
+		},
+	},
+}
+
+func (c *Cipher) keySchedule(in []byte) {
+	var t [8]uint32
+	var k [32]uint32
+
+	for i := 0; i < 4; i++ {
+		j := i * 4
+		t[i] = uint32(in[j])<<24 | uint32(in[j+1])<<16 | uint32(in[j+2])<<8 | uint32(in[j+3])
+	}
+
+	x := []byte{6, 7, 4, 5}
+	ki := 0
+
+	for half := 0; half < 2; half++ {
+		for _, round := range schedule {
+			for j := 0; j < 4; j++ {
+				var a [7]uint8
+				copy(a[:], round.a[j][:])
+				w := t[a[1]]
+				w ^= sBox[4][(t[a[2]>>2]>>(24-8*(a[2]&3)))&0xff]
+				w ^= sBox[5][(t[a[3]>>2]>>(24-8*(a[3]&3)))&0xff]
+				w ^= sBox[6][(t[a[4]>>2]>>(24-8*(a[4]&3)))&0xff]
+				w ^= sBox[7][(t[a[5]>>2]>>(24-8*(a[5]&3)))&0xff]
+				w ^= sBox[x[j]][(t[a[6]>>2]>>(24-8*(a[6]&3)))&0xff]
+				t[a[0]] = w
+			}
+
+			for j := 0; j < 4; j++ {
+				var b [5]uint8
+				copy(b[:], round.b[j][:])
+				w := sBox[4][(t[b[0]>>2]>>(24-8*(b[0]&3)))&0xff]
+				w ^= sBox[5][(t[b[1]>>2]>>(24-8*(b[1]&3)))&0xff]
+				w ^= sBox[6][(t[b[2]>>2]>>(24-8*(b[2]&3)))&0xff]
+				w ^= sBox[7][(t[b[3]>>2]>>(24-8*(b[3]&3)))&0xff]
+				w ^= sBox[4+j][(t[b[4]>>2]>>(24-8*(b[4]&3)))&0xff]
+				k[ki] = w
+				ki++
+			}
+		}
+	}
+
+	for i := 0; i < 16; i++ {
+		c.masking[i] = k[i]
+		c.rotate[i] = uint8(k[16+i] & 0x1f)
+	}
+}
+
+// These are the three 'f' functions. See RFC 2144, section 2.2.
+func f1(d, m uint32, r uint8) uint32 {
+	t := m + d
+	I := (t << r) | (t >> (32 - r))
+	return ((sBox[0][I>>24] ^ sBox[1][(I>>16)&0xff]) - sBox[2][(I>>8)&0xff]) + sBox[3][I&0xff]
+}
+
+func f2(d, m uint32, r uint8) uint32 {
+	t := m ^ d
+	I := (t << r) | (t >> (32 - r))
+	return ((sBox[0][I>>24] - sBox[1][(I>>16)&0xff]) + sBox[2][(I>>8)&0xff]) ^ sBox[3][I&0xff]
+}
+
+func f3(d, m uint32, r uint8) uint32 {
+	t := m - d
+	I := (t << r) | (t >> (32 - r))
+	return ((sBox[0][I>>24] + sBox[1][(I>>16)&0xff]) ^ sBox[2][(I>>8)&0xff]) - sBox[3][I&0xff]
+}
+
+var sBox = [8][256]uint32{
+	{
+		0x30fb40d4, 0x9fa0ff0b, 0x6beccd2f, 0x3f258c7a, 0x1e213f2f, 0x9c004dd3, 0x6003e540, 0xcf9fc949,
+		0xbfd4af27, 0x88bbbdb5, 0xe2034090, 0x98d09675, 0x6e63a0e0, 0x15c361d2, 0xc2e7661d, 0x22d4ff8e,
+		0x28683b6f, 0xc07fd059, 0xff2379c8, 0x775f50e2, 0x43c340d3, 0xdf2f8656, 0x887ca41a, 0xa2d2bd2d,
+		0xa1c9e0d6, 0x346c4819, 0x61b76d87, 0x22540f2f, 0x2abe32e1, 0xaa54166b, 0x22568e3a, 0xa2d341d0,
+		0x66db40c8, 0xa784392f, 0x004dff2f, 0x2db9d2de, 0x97943fac, 0x4a97c1d8, 0x527644b7, 0xb5f437a7,
+		0xb82cbaef, 0xd751d159, 0x6ff7f0ed, 0x5a097a1f, 0x827b68d0, 0x90ecf52e, 0x22b0c054, 0xbc8e5935,
+		0x4b6d2f7f, 0x50bb64a2, 0xd2664910, 0xbee5812d, 0xb7332290, 0xe93b159f, 0xb48ee411, 0x4bff345d,
+		0xfd45c240, 0xad31973f, 0xc4f6d02e, 0x55fc8165, 0xd5b1caad, 0xa1ac2dae, 0xa2d4b76d, 0xc19b0c50,
+		0x882240f2, 0x0c6e4f38, 0xa4e4bfd7, 0x4f5ba272, 0x564c1d2f, 0xc59c5319, 0xb949e354, 0xb04669fe,
+		0xb1b6ab8a, 0xc71358dd, 0x6385c545, 0x110f935d, 0x57538ad5, 0x6a390493, 0xe63d37e0, 0x2a54f6b3,
+		0x3a787d5f, 0x6276a0b5, 0x19a6fcdf, 0x7a42206a, 0x29f9d4d5, 0xf61b1891, 0xbb72275e, 0xaa508167,
+		0x38901091, 0xc6b505eb, 0x84c7cb8c, 0x2ad75a0f, 0x874a1427, 0xa2d1936b, 0x2ad286af, 0xaa56d291,
+		0xd7894360, 0x425c750d, 0x93b39e26, 0x187184c9, 0x6c00b32d, 0x73e2bb14, 0xa0bebc3c, 0x54623779,
+		0x64459eab, 0x3f328b82, 0x7718cf82, 0x59a2cea6, 0x04ee002e, 0x89fe78e6, 0x3fab0950, 0x325ff6c2,
+		0x81383f05, 0x6963c5c8, 0x76cb5ad6, 0xd49974c9, 0xca180dcf, 0x380782d5, 0xc7fa5cf6, 0x8ac31511,
+		0x35e79e13, 0x47da91d0, 0xf40f9086, 0xa7e2419e, 0x31366241, 0x051ef495, 0xaa573b04, 0x4a805d8d,
+		0x548300d0, 0x00322a3c, 0xbf64cddf, 0xba57a68e, 0x75c6372b, 0x50afd341, 0xa7c13275, 0x915a0bf5,
+		0x6b54bfab, 0x2b0b1426, 0xab4cc9d7, 0x449ccd82, 0xf7fbf265, 0xab85c5f3, 0x1b55db94, 0xaad4e324,
+		0xcfa4bd3f, 0x2deaa3e2, 0x9e204d02, 0xc8bd25ac, 0xeadf55b3, 0xd5bd9e98, 0xe31231b2, 0x2ad5ad6c,
+		0x954329de, 0xadbe4528, 0xd8710f69, 0xaa51c90f, 0xaa786bf6, 0x22513f1e, 0xaa51a79b, 0x2ad344cc,
+		0x7b5a41f0, 0xd37cfbad, 0x1b069505, 0x41ece491, 0xb4c332e6, 0x032268d4, 0xc9600acc, 0xce387e6d,
+		0xbf6bb16c, 0x6a70fb78, 0x0d03d9c9, 0xd4df39de, 0xe01063da, 0x4736f464, 0x5ad328d8, 0xb347cc96,
+		0x75bb0fc3, 0x98511bfb, 0x4ffbcc35, 0xb58bcf6a, 0xe11f0abc, 0xbfc5fe4a, 0xa70aec10, 0xac39570a,
+		0x3f04442f, 0x6188b153, 0xe0397a2e, 0x5727cb79, 0x9ceb418f, 0x1cacd68d, 0x2ad37c96, 0x0175cb9d,
+		0xc69dff09, 0xc75b65f0, 0xd9db40d8, 0xec0e7779, 0x4744ead4, 0xb11c3274, 0xdd24cb9e, 0x7e1c54bd,
+		0xf01144f9, 0xd2240eb1, 0x9675b3fd, 0xa3ac3755, 0xd47c27af, 0x51c85f4d, 0x56907596, 0xa5bb15e6,
+		0x580304f0, 0xca042cf1, 0x011a37ea, 0x8dbfaadb, 0x35ba3e4a, 0x3526ffa0, 0xc37b4d09, 0xbc306ed9,
+		0x98a52666, 0x5648f725, 0xff5e569d, 0x0ced63d0, 0x7c63b2cf, 0x700b45e1, 0xd5ea50f1, 0x85a92872,
+		0xaf1fbda7, 0xd4234870, 0xa7870bf3, 0x2d3b4d79, 0x42e04198, 0x0cd0ede7, 0x26470db8, 0xf881814c,
+		0x474d6ad7, 0x7c0c5e5c, 0xd1231959, 0x381b7298, 0xf5d2f4db, 0xab838653, 0x6e2f1e23, 0x83719c9e,
+		0xbd91e046, 0x9a56456e, 0xdc39200c, 0x20c8c571, 0x962bda1c, 0xe1e696ff, 0xb141ab08, 0x7cca89b9,
+		0x1a69e783, 0x02cc4843, 0xa2f7c579, 0x429ef47d, 0x427b169c, 0x5ac9f049, 0xdd8f0f00, 0x5c8165bf,
+	},
+	{
+		0x1f201094, 0xef0ba75b, 0x69e3cf7e, 0x393f4380, 0xfe61cf7a, 0xeec5207a, 0x55889c94, 0x72fc0651,
+		0xada7ef79, 0x4e1d7235, 0xd55a63ce, 0xde0436ba, 0x99c430ef, 0x5f0c0794, 0x18dcdb7d, 0xa1d6eff3,
+		0xa0b52f7b, 0x59e83605, 0xee15b094, 0xe9ffd909, 0xdc440086, 0xef944459, 0xba83ccb3, 0xe0c3cdfb,
+		0xd1da4181, 0x3b092ab1, 0xf997f1c1, 0xa5e6cf7b, 0x01420ddb, 0xe4e7ef5b, 0x25a1ff41, 0xe180f806,
+		0x1fc41080, 0x179bee7a, 0xd37ac6a9, 0xfe5830a4, 0x98de8b7f, 0x77e83f4e, 0x79929269, 0x24fa9f7b,
+		0xe113c85b, 0xacc40083, 0xd7503525, 0xf7ea615f, 0x62143154, 0x0d554b63, 0x5d681121, 0xc866c359,
+		0x3d63cf73, 0xcee234c0, 0xd4d87e87, 0x5c672b21, 0x071f6181, 0x39f7627f, 0x361e3084, 0xe4eb573b,
+		0x602f64a4, 0xd63acd9c, 0x1bbc4635, 0x9e81032d, 0x2701f50c, 0x99847ab4, 0xa0e3df79, 0xba6cf38c,
+		0x10843094, 0x2537a95e, 0xf46f6ffe, 0xa1ff3b1f, 0x208cfb6a, 0x8f458c74, 0xd9e0a227, 0x4ec73a34,
+		0xfc884f69, 0x3e4de8df, 0xef0e0088, 0x3559648d, 0x8a45388c, 0x1d804366, 0x721d9bfd, 0xa58684bb,
+		0xe8256333, 0x844e8212, 0x128d8098, 0xfed33fb4, 0xce280ae1, 0x27e19ba5, 0xd5a6c252, 0xe49754bd,
+		0xc5d655dd, 0xeb667064, 0x77840b4d, 0xa1b6a801, 0x84db26a9, 0xe0b56714, 0x21f043b7, 0xe5d05860,
+		0x54f03084, 0x066ff472, 0xa31aa153, 0xdadc4755, 0xb5625dbf, 0x68561be6, 0x83ca6b94, 0x2d6ed23b,
+		0xeccf01db, 0xa6d3d0ba, 0xb6803d5c, 0xaf77a709, 0x33b4a34c, 0x397bc8d6, 0x5ee22b95, 0x5f0e5304,
+		0x81ed6f61, 0x20e74364, 0xb45e1378, 0xde18639b, 0x881ca122, 0xb96726d1, 0x8049a7e8, 0x22b7da7b,
+		0x5e552d25, 0x5272d237, 0x79d2951c, 0xc60d894c, 0x488cb402, 0x1ba4fe5b, 0xa4b09f6b, 0x1ca815cf,
+		0xa20c3005, 0x8871df63, 0xb9de2fcb, 0x0cc6c9e9, 0x0beeff53, 0xe3214517, 0xb4542835, 0x9f63293c,
+		0xee41e729, 0x6e1d2d7c, 0x50045286, 0x1e6685f3, 0xf33401c6, 0x30a22c95, 0x31a70850, 0x60930f13,
+		0x73f98417, 0xa1269859, 0xec645c44, 0x52c877a9, 0xcdff33a6, 0xa02b1741, 0x7cbad9a2, 0x2180036f,
+		0x50d99c08, 0xcb3f4861, 0xc26bd765, 0x64a3f6ab, 0x80342676, 0x25a75e7b, 0xe4e6d1fc, 0x20c710e6,
+		0xcdf0b680, 0x17844d3b, 0x31eef84d, 0x7e0824e4, 0x2ccb49eb, 0x846a3bae, 0x8ff77888, 0xee5d60f6,
+		0x7af75673, 0x2fdd5cdb, 0xa11631c1, 0x30f66f43, 0xb3faec54, 0x157fd7fa, 0xef8579cc, 0xd152de58,
+		0xdb2ffd5e, 0x8f32ce19, 0x306af97a, 0x02f03ef8, 0x99319ad5, 0xc242fa0f, 0xa7e3ebb0, 0xc68e4906,
+		0xb8da230c, 0x80823028, 0xdcdef3c8, 0xd35fb171, 0x088a1bc8, 0xbec0c560, 0x61a3c9e8, 0xbca8f54d,
+		0xc72feffa, 0x22822e99, 0x82c570b4, 0xd8d94e89, 0x8b1c34bc, 0x301e16e6, 0x273be979, 0xb0ffeaa6,
+		0x61d9b8c6, 0x00b24869, 0xb7ffce3f, 0x08dc283b, 0x43daf65a, 0xf7e19798, 0x7619b72f, 0x8f1c9ba4,
+		0xdc8637a0, 0x16a7d3b1, 0x9fc393b7, 0xa7136eeb, 0xc6bcc63e, 0x1a513742, 0xef6828bc, 0x520365d6,
+		0x2d6a77ab, 0x3527ed4b, 0x821fd216, 0x095c6e2e, 0xdb92f2fb, 0x5eea29cb, 0x145892f5, 0x91584f7f,
+		0x5483697b, 0x2667a8cc, 0x85196048, 0x8c4bacea, 0x833860d4, 0x0d23e0f9, 0x6c387e8a, 0x0ae6d249,
+		0xb284600c, 0xd835731d, 0xdcb1c647, 0xac4c56ea, 0x3ebd81b3, 0x230eabb0, 0x6438bc87, 0xf0b5b1fa,
+		0x8f5ea2b3, 0xfc184642, 0x0a036b7a, 0x4fb089bd, 0x649da589, 0xa345415e, 0x5c038323, 0x3e5d3bb9,
+		0x43d79572, 0x7e6dd07c, 0x06dfdf1e, 0x6c6cc4ef, 0x7160a539, 0x73bfbe70, 0x83877605, 0x4523ecf1,
+	},
+	{
+		0x8defc240, 0x25fa5d9f, 0xeb903dbf, 0xe810c907, 0x47607fff, 0x369fe44b, 0x8c1fc644, 0xaececa90,
+		0xbeb1f9bf, 0xeefbcaea, 0xe8cf1950, 0x51df07ae, 0x920e8806, 0xf0ad0548, 0xe13c8d83, 0x927010d5,
+		0x11107d9f, 0x07647db9, 0xb2e3e4d4, 0x3d4f285e, 0xb9afa820, 0xfade82e0, 0xa067268b, 0x8272792e,
+		0x553fb2c0, 0x489ae22b, 0xd4ef9794, 0x125e3fbc, 0x21fffcee, 0x825b1bfd, 0x9255c5ed, 0x1257a240,
+		0x4e1a8302, 0xbae07fff, 0x528246e7, 0x8e57140e, 0x3373f7bf, 0x8c9f8188, 0xa6fc4ee8, 0xc982b5a5,
+		0xa8c01db7, 0x579fc264, 0x67094f31, 0xf2bd3f5f, 0x40fff7c1, 0x1fb78dfc, 0x8e6bd2c1, 0x437be59b,
+		0x99b03dbf, 0xb5dbc64b, 0x638dc0e6, 0x55819d99, 0xa197c81c, 0x4a012d6e, 0xc5884a28, 0xccc36f71,
+		0xb843c213, 0x6c0743f1, 0x8309893c, 0x0feddd5f, 0x2f7fe850, 0xd7c07f7e, 0x02507fbf, 0x5afb9a04,
+		0xa747d2d0, 0x1651192e, 0xaf70bf3e, 0x58c31380, 0x5f98302e, 0x727cc3c4, 0x0a0fb402, 0x0f7fef82,
+		0x8c96fdad, 0x5d2c2aae, 0x8ee99a49, 0x50da88b8, 0x8427f4a0, 0x1eac5790, 0x796fb449, 0x8252dc15,
+		0xefbd7d9b, 0xa672597d, 0xada840d8, 0x45f54504, 0xfa5d7403, 0xe83ec305, 0x4f91751a, 0x925669c2,
+		0x23efe941, 0xa903f12e, 0x60270df2, 0x0276e4b6, 0x94fd6574, 0x927985b2, 0x8276dbcb, 0x02778176,
+		0xf8af918d, 0x4e48f79e, 0x8f616ddf, 0xe29d840e, 0x842f7d83, 0x340ce5c8, 0x96bbb682, 0x93b4b148,
+		0xef303cab, 0x984faf28, 0x779faf9b, 0x92dc560d, 0x224d1e20, 0x8437aa88, 0x7d29dc96, 0x2756d3dc,
+		0x8b907cee, 0xb51fd240, 0xe7c07ce3, 0xe566b4a1, 0xc3e9615e, 0x3cf8209d, 0x6094d1e3, 0xcd9ca341,
+		0x5c76460e, 0x00ea983b, 0xd4d67881, 0xfd47572c, 0xf76cedd9, 0xbda8229c, 0x127dadaa, 0x438a074e,
+		0x1f97c090, 0x081bdb8a, 0x93a07ebe, 0xb938ca15, 0x97b03cff, 0x3dc2c0f8, 0x8d1ab2ec, 0x64380e51,
+		0x68cc7bfb, 0xd90f2788, 0x12490181, 0x5de5ffd4, 0xdd7ef86a, 0x76a2e214, 0xb9a40368, 0x925d958f,
+		0x4b39fffa, 0xba39aee9, 0xa4ffd30b, 0xfaf7933b, 0x6d498623, 0x193cbcfa, 0x27627545, 0x825cf47a,
+		0x61bd8ba0, 0xd11e42d1, 0xcead04f4, 0x127ea392, 0x10428db7, 0x8272a972, 0x9270c4a8, 0x127de50b,
+		0x285ba1c8, 0x3c62f44f, 0x35c0eaa5, 0xe805d231, 0x428929fb, 0xb4fcdf82, 0x4fb66a53, 0x0e7dc15b,
+		0x1f081fab, 0x108618ae, 0xfcfd086d, 0xf9ff2889, 0x694bcc11, 0x236a5cae, 0x12deca4d, 0x2c3f8cc5,
+		0xd2d02dfe, 0xf8ef5896, 0xe4cf52da, 0x95155b67, 0x494a488c, 0xb9b6a80c, 0x5c8f82bc, 0x89d36b45,
+		0x3a609437, 0xec00c9a9, 0x44715253, 0x0a874b49, 0xd773bc40, 0x7c34671c, 0x02717ef6, 0x4feb5536,
+		0xa2d02fff, 0xd2bf60c4, 0xd43f03c0, 0x50b4ef6d, 0x07478cd1, 0x006e1888, 0xa2e53f55, 0xb9e6d4bc,
+		0xa2048016, 0x97573833, 0xd7207d67, 0xde0f8f3d, 0x72f87b33, 0xabcc4f33, 0x7688c55d, 0x7b00a6b0,
+		0x947b0001, 0x570075d2, 0xf9bb88f8, 0x8942019e, 0x4264a5ff, 0x856302e0, 0x72dbd92b, 0xee971b69,
+		0x6ea22fde, 0x5f08ae2b, 0xaf7a616d, 0xe5c98767, 0xcf1febd2, 0x61efc8c2, 0xf1ac2571, 0xcc8239c2,
+		0x67214cb8, 0xb1e583d1, 0xb7dc3e62, 0x7f10bdce, 0xf90a5c38, 0x0ff0443d, 0x606e6dc6, 0x60543a49,
+		0x5727c148, 0x2be98a1d, 0x8ab41738, 0x20e1be24, 0xaf96da0f, 0x68458425, 0x99833be5, 0x600d457d,
+		0x282f9350, 0x8334b362, 0xd91d1120, 0x2b6d8da0, 0x642b1e31, 0x9c305a00, 0x52bce688, 0x1b03588a,
+		0xf7baefd5, 0x4142ed9c, 0xa4315c11, 0x83323ec5, 0xdfef4636, 0xa133c501, 0xe9d3531c, 0xee353783,
+	},
+	{
+		0x9db30420, 0x1fb6e9de, 0xa7be7bef, 0xd273a298, 0x4a4f7bdb, 0x64ad8c57, 0x85510443, 0xfa020ed1,
+		0x7e287aff, 0xe60fb663, 0x095f35a1, 0x79ebf120, 0xfd059d43, 0x6497b7b1, 0xf3641f63, 0x241e4adf,
+		0x28147f5f, 0x4fa2b8cd, 0xc9430040, 0x0cc32220, 0xfdd30b30, 0xc0a5374f, 0x1d2d00d9, 0x24147b15,
+		0xee4d111a, 0x0fca5167, 0x71ff904c, 0x2d195ffe, 0x1a05645f, 0x0c13fefe, 0x081b08ca, 0x05170121,
+		0x80530100, 0xe83e5efe, 0xac9af4f8, 0x7fe72701, 0xd2b8ee5f, 0x06df4261, 0xbb9e9b8a, 0x7293ea25,
+		0xce84ffdf, 0xf5718801, 0x3dd64b04, 0xa26f263b, 0x7ed48400, 0x547eebe6, 0x446d4ca0, 0x6cf3d6f5,
+		0x2649abdf, 0xaea0c7f5, 0x36338cc1, 0x503f7e93, 0xd3772061, 0x11b638e1, 0x72500e03, 0xf80eb2bb,
+		0xabe0502e, 0xec8d77de, 0x57971e81, 0xe14f6746, 0xc9335400, 0x6920318f, 0x081dbb99, 0xffc304a5,
+		0x4d351805, 0x7f3d5ce3, 0xa6c866c6, 0x5d5bcca9, 0xdaec6fea, 0x9f926f91, 0x9f46222f, 0x3991467d,
+		0xa5bf6d8e, 0x1143c44f, 0x43958302, 0xd0214eeb, 0x022083b8, 0x3fb6180c, 0x18f8931e, 0x281658e6,
+		0x26486e3e, 0x8bd78a70, 0x7477e4c1, 0xb506e07c, 0xf32d0a25, 0x79098b02, 0xe4eabb81, 0x28123b23,
+		0x69dead38, 0x1574ca16, 0xdf871b62, 0x211c40b7, 0xa51a9ef9, 0x0014377b, 0x041e8ac8, 0x09114003,
+		0xbd59e4d2, 0xe3d156d5, 0x4fe876d5, 0x2f91a340, 0x557be8de, 0x00eae4a7, 0x0ce5c2ec, 0x4db4bba6,
+		0xe756bdff, 0xdd3369ac, 0xec17b035, 0x06572327, 0x99afc8b0, 0x56c8c391, 0x6b65811c, 0x5e146119,
+		0x6e85cb75, 0xbe07c002, 0xc2325577, 0x893ff4ec, 0x5bbfc92d, 0xd0ec3b25, 0xb7801ab7, 0x8d6d3b24,
+		0x20c763ef, 0xc366a5fc, 0x9c382880, 0x0ace3205, 0xaac9548a, 0xeca1d7c7, 0x041afa32, 0x1d16625a,
+		0x6701902c, 0x9b757a54, 0x31d477f7, 0x9126b031, 0x36cc6fdb, 0xc70b8b46, 0xd9e66a48, 0x56e55a79,
+		0x026a4ceb, 0x52437eff, 0x2f8f76b4, 0x0df980a5, 0x8674cde3, 0xedda04eb, 0x17a9be04, 0x2c18f4df,
+		0xb7747f9d, 0xab2af7b4, 0xefc34d20, 0x2e096b7c, 0x1741a254, 0xe5b6a035, 0x213d42f6, 0x2c1c7c26,
+		0x61c2f50f, 0x6552daf9, 0xd2c231f8, 0x25130f69, 0xd8167fa2, 0x0418f2c8, 0x001a96a6, 0x0d1526ab,
+		0x63315c21, 0x5e0a72ec, 0x49bafefd, 0x187908d9, 0x8d0dbd86, 0x311170a7, 0x3e9b640c, 0xcc3e10d7,
+		0xd5cad3b6, 0x0caec388, 0xf73001e1, 0x6c728aff, 0x71eae2a1, 0x1f9af36e, 0xcfcbd12f, 0xc1de8417,
+		0xac07be6b, 0xcb44a1d8, 0x8b9b0f56, 0x013988c3, 0xb1c52fca, 0xb4be31cd, 0xd8782806, 0x12a3a4e2,
+		0x6f7de532, 0x58fd7eb6, 0xd01ee900, 0x24adffc2, 0xf4990fc5, 0x9711aac5, 0x001d7b95, 0x82e5e7d2,
+		0x109873f6, 0x00613096, 0xc32d9521, 0xada121ff, 0x29908415, 0x7fbb977f, 0xaf9eb3db, 0x29c9ed2a,
+		0x5ce2a465, 0xa730f32c, 0xd0aa3fe8, 0x8a5cc091, 0xd49e2ce7, 0x0ce454a9, 0xd60acd86, 0x015f1919,
+		0x77079103, 0xdea03af6, 0x78a8565e, 0xdee356df, 0x21f05cbe, 0x8b75e387, 0xb3c50651, 0xb8a5c3ef,
+		0xd8eeb6d2, 0xe523be77, 0xc2154529, 0x2f69efdf, 0xafe67afb, 0xf470c4b2, 0xf3e0eb5b, 0xd6cc9876,
+		0x39e4460c, 0x1fda8538, 0x1987832f, 0xca007367, 0xa99144f8, 0x296b299e, 0x492fc295, 0x9266beab,
+		0xb5676e69, 0x9bd3ddda, 0xdf7e052f, 0xdb25701c, 0x1b5e51ee, 0xf65324e6, 0x6afce36c, 0x0316cc04,
+		0x8644213e, 0xb7dc59d0, 0x7965291f, 0xccd6fd43, 0x41823979, 0x932bcdf6, 0xb657c34d, 0x4edfd282,
+		0x7ae5290c, 0x3cb9536b, 0x851e20fe, 0x9833557e, 0x13ecf0b0, 0xd3ffb372, 0x3f85c5c1, 0x0aef7ed2,
+	},
+	{
+		0x7ec90c04, 0x2c6e74b9, 0x9b0e66df, 0xa6337911, 0xb86a7fff, 0x1dd358f5, 0x44dd9d44, 0x1731167f,
+		0x08fbf1fa, 0xe7f511cc, 0xd2051b00, 0x735aba00, 0x2ab722d8, 0x386381cb, 0xacf6243a, 0x69befd7a,
+		0xe6a2e77f, 0xf0c720cd, 0xc4494816, 0xccf5c180, 0x38851640, 0x15b0a848, 0xe68b18cb, 0x4caadeff,
+		0x5f480a01, 0x0412b2aa, 0x259814fc, 0x41d0efe2, 0x4e40b48d, 0x248eb6fb, 0x8dba1cfe, 0x41a99b02,
+		0x1a550a04, 0xba8f65cb, 0x7251f4e7, 0x95a51725, 0xc106ecd7, 0x97a5980a, 0xc539b9aa, 0x4d79fe6a,
+		0xf2f3f763, 0x68af8040, 0xed0c9e56, 0x11b4958b, 0xe1eb5a88, 0x8709e6b0, 0xd7e07156, 0x4e29fea7,
+		0x6366e52d, 0x02d1c000, 0xc4ac8e05, 0x9377f571, 0x0c05372a, 0x578535f2, 0x2261be02, 0xd642a0c9,
+		0xdf13a280, 0x74b55bd2, 0x682199c0, 0xd421e5ec, 0x53fb3ce8, 0xc8adedb3, 0x28a87fc9, 0x3d959981,
+		0x5c1ff900, 0xfe38d399, 0x0c4eff0b, 0x062407ea, 0xaa2f4fb1, 0x4fb96976, 0x90c79505, 0xb0a8a774,
+		0xef55a1ff, 0xe59ca2c2, 0xa6b62d27, 0xe66a4263, 0xdf65001f, 0x0ec50966, 0xdfdd55bc, 0x29de0655,
+		0x911e739a, 0x17af8975, 0x32c7911c, 0x89f89468, 0x0d01e980, 0x524755f4, 0x03b63cc9, 0x0cc844b2,
+		0xbcf3f0aa, 0x87ac36e9, 0xe53a7426, 0x01b3d82b, 0x1a9e7449, 0x64ee2d7e, 0xcddbb1da, 0x01c94910,
+		0xb868bf80, 0x0d26f3fd, 0x9342ede7, 0x04a5c284, 0x636737b6, 0x50f5b616, 0xf24766e3, 0x8eca36c1,
+		0x136e05db, 0xfef18391, 0xfb887a37, 0xd6e7f7d4, 0xc7fb7dc9, 0x3063fcdf, 0xb6f589de, 0xec2941da,
+		0x26e46695, 0xb7566419, 0xf654efc5, 0xd08d58b7, 0x48925401, 0xc1bacb7f, 0xe5ff550f, 0xb6083049,
+		0x5bb5d0e8, 0x87d72e5a, 0xab6a6ee1, 0x223a66ce, 0xc62bf3cd, 0x9e0885f9, 0x68cb3e47, 0x086c010f,
+		0xa21de820, 0xd18b69de, 0xf3f65777, 0xfa02c3f6, 0x407edac3, 0xcbb3d550, 0x1793084d, 0xb0d70eba,
+		0x0ab378d5, 0xd951fb0c, 0xded7da56, 0x4124bbe4, 0x94ca0b56, 0x0f5755d1, 0xe0e1e56e, 0x6184b5be,
+		0x580a249f, 0x94f74bc0, 0xe327888e, 0x9f7b5561, 0xc3dc0280, 0x05687715, 0x646c6bd7, 0x44904db3,
+		0x66b4f0a3, 0xc0f1648a, 0x697ed5af, 0x49e92ff6, 0x309e374f, 0x2cb6356a, 0x85808573, 0x4991f840,
+		0x76f0ae02, 0x083be84d, 0x28421c9a, 0x44489406, 0x736e4cb8, 0xc1092910, 0x8bc95fc6, 0x7d869cf4,
+		0x134f616f, 0x2e77118d, 0xb31b2be1, 0xaa90b472, 0x3ca5d717, 0x7d161bba, 0x9cad9010, 0xaf462ba2,
+		0x9fe459d2, 0x45d34559, 0xd9f2da13, 0xdbc65487, 0xf3e4f94e, 0x176d486f, 0x097c13ea, 0x631da5c7,
+		0x445f7382, 0x175683f4, 0xcdc66a97, 0x70be0288, 0xb3cdcf72, 0x6e5dd2f3, 0x20936079, 0x459b80a5,
+		0xbe60e2db, 0xa9c23101, 0xeba5315c, 0x224e42f2, 0x1c5c1572, 0xf6721b2c, 0x1ad2fff3, 0x8c25404e,
+		0x324ed72f, 0x4067b7fd, 0x0523138e, 0x5ca3bc78, 0xdc0fd66e, 0x75922283, 0x784d6b17, 0x58ebb16e,
+		0x44094f85, 0x3f481d87, 0xfcfeae7b, 0x77b5ff76, 0x8c2302bf, 0xaaf47556, 0x5f46b02a, 0x2b092801,
+		0x3d38f5f7, 0x0ca81f36, 0x52af4a8a, 0x66d5e7c0, 0xdf3b0874, 0x95055110, 0x1b5ad7a8, 0xf61ed5ad,
+		0x6cf6e479, 0x20758184, 0xd0cefa65, 0x88f7be58, 0x4a046826, 0x0ff6f8f3, 0xa09c7f70, 0x5346aba0,
+		0x5ce96c28, 0xe176eda3, 0x6bac307f, 0x376829d2, 0x85360fa9, 0x17e3fe2a, 0x24b79767, 0xf5a96b20,
+		0xd6cd2595, 0x68ff1ebf, 0x7555442c, 0xf19f06be, 0xf9e0659a, 0xeeb9491d, 0x34010718, 0xbb30cab8,
+		0xe822fe15, 0x88570983, 0x750e6249, 0xda627e55, 0x5e76ffa8, 0xb1534546, 0x6d47de08, 0xefe9e7d4,
+	},
+	{
+		0xf6fa8f9d, 0x2cac6ce1, 0x4ca34867, 0xe2337f7c, 0x95db08e7, 0x016843b4, 0xeced5cbc, 0x325553ac,
+		0xbf9f0960, 0xdfa1e2ed, 0x83f0579d, 0x63ed86b9, 0x1ab6a6b8, 0xde5ebe39, 0xf38ff732, 0x8989b138,
+		0x33f14961, 0xc01937bd, 0xf506c6da, 0xe4625e7e, 0xa308ea99, 0x4e23e33c, 0x79cbd7cc, 0x48a14367,
+		0xa3149619, 0xfec94bd5, 0xa114174a, 0xeaa01866, 0xa084db2d, 0x09a8486f, 0xa888614a, 0x2900af98,
+		0x01665991, 0xe1992863, 0xc8f30c60, 0x2e78ef3c, 0xd0d51932, 0xcf0fec14, 0xf7ca07d2, 0xd0a82072,
+		0xfd41197e, 0x9305a6b0, 0xe86be3da, 0x74bed3cd, 0x372da53c, 0x4c7f4448, 0xdab5d440, 0x6dba0ec3,
+		0x083919a7, 0x9fbaeed9, 0x49dbcfb0, 0x4e670c53, 0x5c3d9c01, 0x64bdb941, 0x2c0e636a, 0xba7dd9cd,
+		0xea6f7388, 0xe70bc762, 0x35f29adb, 0x5c4cdd8d, 0xf0d48d8c, 0xb88153e2, 0x08a19866, 0x1ae2eac8,
+		0x284caf89, 0xaa928223, 0x9334be53, 0x3b3a21bf, 0x16434be3, 0x9aea3906, 0xefe8c36e, 0xf890cdd9,
+		0x80226dae, 0xc340a4a3, 0xdf7e9c09, 0xa694a807, 0x5b7c5ecc, 0x221db3a6, 0x9a69a02f, 0x68818a54,
+		0xceb2296f, 0x53c0843a, 0xfe893655, 0x25bfe68a, 0xb4628abc, 0xcf222ebf, 0x25ac6f48, 0xa9a99387,
+		0x53bddb65, 0xe76ffbe7, 0xe967fd78, 0x0ba93563, 0x8e342bc1, 0xe8a11be9, 0x4980740d, 0xc8087dfc,
+		0x8de4bf99, 0xa11101a0, 0x7fd37975, 0xda5a26c0, 0xe81f994f, 0x9528cd89, 0xfd339fed, 0xb87834bf,
+		0x5f04456d, 0x22258698, 0xc9c4c83b, 0x2dc156be, 0x4f628daa, 0x57f55ec5, 0xe2220abe, 0xd2916ebf,
+		0x4ec75b95, 0x24f2c3c0, 0x42d15d99, 0xcd0d7fa0, 0x7b6e27ff, 0xa8dc8af0, 0x7345c106, 0xf41e232f,
+		0x35162386, 0xe6ea8926, 0x3333b094, 0x157ec6f2, 0x372b74af, 0x692573e4, 0xe9a9d848, 0xf3160289,
+		0x3a62ef1d, 0xa787e238, 0xf3a5f676, 0x74364853, 0x20951063, 0x4576698d, 0xb6fad407, 0x592af950,
+		0x36f73523, 0x4cfb6e87, 0x7da4cec0, 0x6c152daa, 0xcb0396a8, 0xc50dfe5d, 0xfcd707ab, 0x0921c42f,
+		0x89dff0bb, 0x5fe2be78, 0x448f4f33, 0x754613c9, 0x2b05d08d, 0x48b9d585, 0xdc049441, 0xc8098f9b,
+		0x7dede786, 0xc39a3373, 0x42410005, 0x6a091751, 0x0ef3c8a6, 0x890072d6, 0x28207682, 0xa9a9f7be,
+		0xbf32679d, 0xd45b5b75, 0xb353fd00, 0xcbb0e358, 0x830f220a, 0x1f8fb214, 0xd372cf08, 0xcc3c4a13,
+		0x8cf63166, 0x061c87be, 0x88c98f88, 0x6062e397, 0x47cf8e7a, 0xb6c85283, 0x3cc2acfb, 0x3fc06976,
+		0x4e8f0252, 0x64d8314d, 0xda3870e3, 0x1e665459, 0xc10908f0, 0x513021a5, 0x6c5b68b7, 0x822f8aa0,
+		0x3007cd3e, 0x74719eef, 0xdc872681, 0x073340d4, 0x7e432fd9, 0x0c5ec241, 0x8809286c, 0xf592d891,
+		0x08a930f6, 0x957ef305, 0xb7fbffbd, 0xc266e96f, 0x6fe4ac98, 0xb173ecc0, 0xbc60b42a, 0x953498da,
+		0xfba1ae12, 0x2d4bd736, 0x0f25faab, 0xa4f3fceb, 0xe2969123, 0x257f0c3d, 0x9348af49, 0x361400bc,
+		0xe8816f4a, 0x3814f200, 0xa3f94043, 0x9c7a54c2, 0xbc704f57, 0xda41e7f9, 0xc25ad33a, 0x54f4a084,
+		0xb17f5505, 0x59357cbe, 0xedbd15c8, 0x7f97c5ab, 0xba5ac7b5, 0xb6f6deaf, 0x3a479c3a, 0x5302da25,
+		0x653d7e6a, 0x54268d49, 0x51a477ea, 0x5017d55b, 0xd7d25d88, 0x44136c76, 0x0404a8c8, 0xb8e5a121,
+		0xb81a928a, 0x60ed5869, 0x97c55b96, 0xeaec991b, 0x29935913, 0x01fdb7f1, 0x088e8dfa, 0x9ab6f6f5,
+		0x3b4cbf9f, 0x4a5de3ab, 0xe6051d35, 0xa0e1d855, 0xd36b4cf1, 0xf544edeb, 0xb0e93524, 0xbebb8fbd,
+		0xa2d762cf, 0x49c92f54, 0x38b5f331, 0x7128a454, 0x48392905, 0xa65b1db8, 0x851c97bd, 0xd675cf2f,
+	},
+	{
+		0x85e04019, 0x332bf567, 0x662dbfff, 0xcfc65693, 0x2a8d7f6f, 0xab9bc912, 0xde6008a1, 0x2028da1f,
+		0x0227bce7, 0x4d642916, 0x18fac300, 0x50f18b82, 0x2cb2cb11, 0xb232e75c, 0x4b3695f2, 0xb28707de,
+		0xa05fbcf6, 0xcd4181e9, 0xe150210c, 0xe24ef1bd, 0xb168c381, 0xfde4e789, 0x5c79b0d8, 0x1e8bfd43,
+		0x4d495001, 0x38be4341, 0x913cee1d, 0x92a79c3f, 0x089766be, 0xbaeeadf4, 0x1286becf, 0xb6eacb19,
+		0x2660c200, 0x7565bde4, 0x64241f7a, 0x8248dca9, 0xc3b3ad66, 0x28136086, 0x0bd8dfa8, 0x356d1cf2,
+		0x107789be, 0xb3b2e9ce, 0x0502aa8f, 0x0bc0351e, 0x166bf52a, 0xeb12ff82, 0xe3486911, 0xd34d7516,
+		0x4e7b3aff, 0x5f43671b, 0x9cf6e037, 0x4981ac83, 0x334266ce, 0x8c9341b7, 0xd0d854c0, 0xcb3a6c88,
+		0x47bc2829, 0x4725ba37, 0xa66ad22b, 0x7ad61f1e, 0x0c5cbafa, 0x4437f107, 0xb6e79962, 0x42d2d816,
+		0x0a961288, 0xe1a5c06e, 0x13749e67, 0x72fc081a, 0xb1d139f7, 0xf9583745, 0xcf19df58, 0xbec3f756,
+		0xc06eba30, 0x07211b24, 0x45c28829, 0xc95e317f, 0xbc8ec511, 0x38bc46e9, 0xc6e6fa14, 0xbae8584a,
+		0xad4ebc46, 0x468f508b, 0x7829435f, 0xf124183b, 0x821dba9f, 0xaff60ff4, 0xea2c4e6d, 0x16e39264,
+		0x92544a8b, 0x009b4fc3, 0xaba68ced, 0x9ac96f78, 0x06a5b79a, 0xb2856e6e, 0x1aec3ca9, 0xbe838688,
+		0x0e0804e9, 0x55f1be56, 0xe7e5363b, 0xb3a1f25d, 0xf7debb85, 0x61fe033c, 0x16746233, 0x3c034c28,
+		0xda6d0c74, 0x79aac56c, 0x3ce4e1ad, 0x51f0c802, 0x98f8f35a, 0x1626a49f, 0xeed82b29, 0x1d382fe3,
+		0x0c4fb99a, 0xbb325778, 0x3ec6d97b, 0x6e77a6a9, 0xcb658b5c, 0xd45230c7, 0x2bd1408b, 0x60c03eb7,
+		0xb9068d78, 0xa33754f4, 0xf430c87d, 0xc8a71302, 0xb96d8c32, 0xebd4e7be, 0xbe8b9d2d, 0x7979fb06,
+		0xe7225308, 0x8b75cf77, 0x11ef8da4, 0xe083c858, 0x8d6b786f, 0x5a6317a6, 0xfa5cf7a0, 0x5dda0033,
+		0xf28ebfb0, 0xf5b9c310, 0xa0eac280, 0x08b9767a, 0xa3d9d2b0, 0x79d34217, 0x021a718d, 0x9ac6336a,
+		0x2711fd60, 0x438050e3, 0x069908a8, 0x3d7fedc4, 0x826d2bef, 0x4eeb8476, 0x488dcf25, 0x36c9d566,
+		0x28e74e41, 0xc2610aca, 0x3d49a9cf, 0xbae3b9df, 0xb65f8de6, 0x92aeaf64, 0x3ac7d5e6, 0x9ea80509,
+		0xf22b017d, 0xa4173f70, 0xdd1e16c3, 0x15e0d7f9, 0x50b1b887, 0x2b9f4fd5, 0x625aba82, 0x6a017962,
+		0x2ec01b9c, 0x15488aa9, 0xd716e740, 0x40055a2c, 0x93d29a22, 0xe32dbf9a, 0x058745b9, 0x3453dc1e,
+		0xd699296e, 0x496cff6f, 0x1c9f4986, 0xdfe2ed07, 0xb87242d1, 0x19de7eae, 0x053e561a, 0x15ad6f8c,
+		0x66626c1c, 0x7154c24c, 0xea082b2a, 0x93eb2939, 0x17dcb0f0, 0x58d4f2ae, 0x9ea294fb, 0x52cf564c,
+		0x9883fe66, 0x2ec40581, 0x763953c3, 0x01d6692e, 0xd3a0c108, 0xa1e7160e, 0xe4f2dfa6, 0x693ed285,
+		0x74904698, 0x4c2b0edd, 0x4f757656, 0x5d393378, 0xa132234f, 0x3d321c5d, 0xc3f5e194, 0x4b269301,
+		0xc79f022f, 0x3c997e7e, 0x5e4f9504, 0x3ffafbbd, 0x76f7ad0e, 0x296693f4, 0x3d1fce6f, 0xc61e45be,
+		0xd3b5ab34, 0xf72bf9b7, 0x1b0434c0, 0x4e72b567, 0x5592a33d, 0xb5229301, 0xcfd2a87f, 0x60aeb767,
+		0x1814386b, 0x30bcc33d, 0x38a0c07d, 0xfd1606f2, 0xc363519b, 0x589dd390, 0x5479f8e6, 0x1cb8d647,
+		0x97fd61a9, 0xea7759f4, 0x2d57539d, 0x569a58cf, 0xe84e63ad, 0x462e1b78, 0x6580f87e, 0xf3817914,
+		0x91da55f4, 0x40a230f3, 0xd1988f35, 0xb6e318d2, 0x3ffa50bc, 0x3d40f021, 0xc3c0bdae, 0x4958c24c,
+		0x518f36b2, 0x84b1d370, 0x0fedce83, 0x878ddada, 0xf2a279c7, 0x94e01be8, 0x90716f4b, 0x954b8aa3,
+	},
+	{
+		0xe216300d, 0xbbddfffc, 0xa7ebdabd, 0x35648095, 0x7789f8b7, 0xe6c1121b, 0x0e241600, 0x052ce8b5,
+		0x11a9cfb0, 0xe5952f11, 0xece7990a, 0x9386d174, 0x2a42931c, 0x76e38111, 0xb12def3a, 0x37ddddfc,
+		0xde9adeb1, 0x0a0cc32c, 0xbe197029, 0x84a00940, 0xbb243a0f, 0xb4d137cf, 0xb44e79f0, 0x049eedfd,
+		0x0b15a15d, 0x480d3168, 0x8bbbde5a, 0x669ded42, 0xc7ece831, 0x3f8f95e7, 0x72df191b, 0x7580330d,
+		0x94074251, 0x5c7dcdfa, 0xabbe6d63, 0xaa402164, 0xb301d40a, 0x02e7d1ca, 0x53571dae, 0x7a3182a2,
+		0x12a8ddec, 0xfdaa335d, 0x176f43e8, 0x71fb46d4, 0x38129022, 0xce949ad4, 0xb84769ad, 0x965bd862,
+		0x82f3d055, 0x66fb9767, 0x15b80b4e, 0x1d5b47a0, 0x4cfde06f, 0xc28ec4b8, 0x57e8726e, 0x647a78fc,
+		0x99865d44, 0x608bd593, 0x6c200e03, 0x39dc5ff6, 0x5d0b00a3, 0xae63aff2, 0x7e8bd632, 0x70108c0c,
+		0xbbd35049, 0x2998df04, 0x980cf42a, 0x9b6df491, 0x9e7edd53, 0x06918548, 0x58cb7e07, 0x3b74ef2e,
+		0x522fffb1, 0xd24708cc, 0x1c7e27cd, 0xa4eb215b, 0x3cf1d2e2, 0x19b47a38, 0x424f7618, 0x35856039,
+		0x9d17dee7, 0x27eb35e6, 0xc9aff67b, 0x36baf5b8, 0x09c467cd, 0xc18910b1, 0xe11dbf7b, 0x06cd1af8,
+		0x7170c608, 0x2d5e3354, 0xd4de495a, 0x64c6d006, 0xbcc0c62c, 0x3dd00db3, 0x708f8f34, 0x77d51b42,
+		0x264f620f, 0x24b8d2bf, 0x15c1b79e, 0x46a52564, 0xf8d7e54e, 0x3e378160, 0x7895cda5, 0x859c15a5,
+		0xe6459788, 0xc37bc75f, 0xdb07ba0c, 0x0676a3ab, 0x7f229b1e, 0x31842e7b, 0x24259fd7, 0xf8bef472,
+		0x835ffcb8, 0x6df4c1f2, 0x96f5b195, 0xfd0af0fc, 0xb0fe134c, 0xe2506d3d, 0x4f9b12ea, 0xf215f225,
+		0xa223736f, 0x9fb4c428, 0x25d04979, 0x34c713f8, 0xc4618187, 0xea7a6e98, 0x7cd16efc, 0x1436876c,
+		0xf1544107, 0xbedeee14, 0x56e9af27, 0xa04aa441, 0x3cf7c899, 0x92ecbae6, 0xdd67016d, 0x151682eb,
+		0xa842eedf, 0xfdba60b4, 0xf1907b75, 0x20e3030f, 0x24d8c29e, 0xe139673b, 0xefa63fb8, 0x71873054,
+		0xb6f2cf3b, 0x9f326442, 0xcb15a4cc, 0xb01a4504, 0xf1e47d8d, 0x844a1be5, 0xbae7dfdc, 0x42cbda70,
+		0xcd7dae0a, 0x57e85b7a, 0xd53f5af6, 0x20cf4d8c, 0xcea4d428, 0x79d130a4, 0x3486ebfb, 0x33d3cddc,
+		0x77853b53, 0x37effcb5, 0xc5068778, 0xe580b3e6, 0x4e68b8f4, 0xc5c8b37e, 0x0d809ea2, 0x398feb7c,
+		0x132a4f94, 0x43b7950e, 0x2fee7d1c, 0x223613bd, 0xdd06caa2, 0x37df932b, 0xc4248289, 0xacf3ebc3,
+		0x5715f6b7, 0xef3478dd, 0xf267616f, 0xc148cbe4, 0x9052815e, 0x5e410fab, 0xb48a2465, 0x2eda7fa4,
+		0xe87b40e4, 0xe98ea084, 0x5889e9e1, 0xefd390fc, 0xdd07d35b, 0xdb485694, 0x38d7e5b2, 0x57720101,
+		0x730edebc, 0x5b643113, 0x94917e4f, 0x503c2fba, 0x646f1282, 0x7523d24a, 0xe0779695, 0xf9c17a8f,
+		0x7a5b2121, 0xd187b896, 0x29263a4d, 0xba510cdf, 0x81f47c9f, 0xad1163ed, 0xea7b5965, 0x1a00726e,
+		0x11403092, 0x00da6d77, 0x4a0cdd61, 0xad1f4603, 0x605bdfb0, 0x9eedc364, 0x22ebe6a8, 0xcee7d28a,
+		0xa0e736a0, 0x5564a6b9, 0x10853209, 0xc7eb8f37, 0x2de705ca, 0x8951570f, 0xdf09822b, 0xbd691a6c,
+		0xaa12e4f2, 0x87451c0f, 0xe0f6a27a, 0x3ada4819, 0x4cf1764f, 0x0d771c2b, 0x67cdb156, 0x350d8384,
+		0x5938fa0f, 0x42399ef3, 0x36997b07, 0x0e84093d, 0x4aa93e61, 0x8360d87b, 0x1fa98b0c, 0x1149382c,
+		0xe97625a5, 0x0614d1b7, 0x0e25244b, 0x0c768347, 0x589e8d82, 0x0d2059d1, 0xa466bb1e, 0xf8da0a82,
+		0x04f19130, 0xba6e4ec0, 0x99265164, 0x1ee7230d, 0x50b2ad80, 0xeaee6801, 0x8db2a283, 0xea8bf59e,
+	},
+}
diff --git a/vendor/golang.org/x/crypto/chacha20/chacha_arm64.go b/vendor/golang.org/x/crypto/chacha20/chacha_arm64.go
index b799e440b4..94c71ac1ac 100644
--- a/vendor/golang.org/x/crypto/chacha20/chacha_arm64.go
+++ b/vendor/golang.org/x/crypto/chacha20/chacha_arm64.go
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build go1.11,!gccgo,!purego
+//go:build go1.11 && gc && !purego
+// +build go1.11,gc,!purego
 
 package chacha20
 
diff --git a/vendor/golang.org/x/crypto/chacha20/chacha_arm64.s b/vendor/golang.org/x/crypto/chacha20/chacha_arm64.s
index 891481539a..63cae9e6f0 100644
--- a/vendor/golang.org/x/crypto/chacha20/chacha_arm64.s
+++ b/vendor/golang.org/x/crypto/chacha20/chacha_arm64.s
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build go1.11,!gccgo,!purego
+//go:build go1.11 && gc && !purego
+// +build go1.11,gc,!purego
 
 #include "textflag.h"
 
diff --git a/vendor/golang.org/x/crypto/chacha20/chacha_noasm.go b/vendor/golang.org/x/crypto/chacha20/chacha_noasm.go
index 4635307b8f..025b49897e 100644
--- a/vendor/golang.org/x/crypto/chacha20/chacha_noasm.go
+++ b/vendor/golang.org/x/crypto/chacha20/chacha_noasm.go
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build !arm64,!s390x,!ppc64le arm64,!go1.11 gccgo purego
+//go:build (!arm64 && !s390x && !ppc64le) || (arm64 && !go1.11) || !gc || purego
+// +build !arm64,!s390x,!ppc64le arm64,!go1.11 !gc purego
 
 package chacha20
 
diff --git a/vendor/golang.org/x/crypto/chacha20/chacha_ppc64le.go b/vendor/golang.org/x/crypto/chacha20/chacha_ppc64le.go
index b799330341..da420b2e97 100644
--- a/vendor/golang.org/x/crypto/chacha20/chacha_ppc64le.go
+++ b/vendor/golang.org/x/crypto/chacha20/chacha_ppc64le.go
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build !gccgo,!purego
+//go:build gc && !purego
+// +build gc,!purego
 
 package chacha20
 
diff --git a/vendor/golang.org/x/crypto/chacha20/chacha_ppc64le.s b/vendor/golang.org/x/crypto/chacha20/chacha_ppc64le.s
index 23c6021643..5c0fed26f8 100644
--- a/vendor/golang.org/x/crypto/chacha20/chacha_ppc64le.s
+++ b/vendor/golang.org/x/crypto/chacha20/chacha_ppc64le.s
@@ -19,7 +19,8 @@
 // The differences in this and the original implementation are
 // due to the calling conventions and initialization of constants.
 
-// +build !gccgo,!purego
+//go:build gc && !purego
+// +build gc,!purego
 
 #include "textflag.h"
 
diff --git a/vendor/golang.org/x/crypto/chacha20/chacha_s390x.go b/vendor/golang.org/x/crypto/chacha20/chacha_s390x.go
index a9244bdf4d..c5898db465 100644
--- a/vendor/golang.org/x/crypto/chacha20/chacha_s390x.go
+++ b/vendor/golang.org/x/crypto/chacha20/chacha_s390x.go
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build !gccgo,!purego
+//go:build gc && !purego
+// +build gc,!purego
 
 package chacha20
 
diff --git a/vendor/golang.org/x/crypto/chacha20/chacha_s390x.s b/vendor/golang.org/x/crypto/chacha20/chacha_s390x.s
index 89c658c410..f3ef5a019d 100644
--- a/vendor/golang.org/x/crypto/chacha20/chacha_s390x.s
+++ b/vendor/golang.org/x/crypto/chacha20/chacha_s390x.s
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build !gccgo,!purego
+//go:build gc && !purego
+// +build gc,!purego
 
 #include "go_asm.h"
 #include "textflag.h"
diff --git a/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305.go b/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305.go
new file mode 100644
index 0000000000..93da7322bc
--- /dev/null
+++ b/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305.go
@@ -0,0 +1,98 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package chacha20poly1305 implements the ChaCha20-Poly1305 AEAD and its
+// extended nonce variant XChaCha20-Poly1305, as specified in RFC 8439 and
+// draft-irtf-cfrg-xchacha-01.
+package chacha20poly1305 // import "golang.org/x/crypto/chacha20poly1305"
+
+import (
+	"crypto/cipher"
+	"errors"
+)
+
+const (
+	// KeySize is the size of the key used by this AEAD, in bytes.
+	KeySize = 32
+
+	// NonceSize is the size of the nonce used with the standard variant of this
+	// AEAD, in bytes.
+	//
+	// Note that this is too short to be safely generated at random if the same
+	// key is reused more than 2³² times.
+	NonceSize = 12
+
+	// NonceSizeX is the size of the nonce used with the XChaCha20-Poly1305
+	// variant of this AEAD, in bytes.
+	NonceSizeX = 24
+
+	// Overhead is the size of the Poly1305 authentication tag, and the
+	// difference between a ciphertext length and its plaintext.
+	Overhead = 16
+)
+
+type chacha20poly1305 struct {
+	key [KeySize]byte
+}
+
+// New returns a ChaCha20-Poly1305 AEAD that uses the given 256-bit key.
+func New(key []byte) (cipher.AEAD, error) {
+	if len(key) != KeySize {
+		return nil, errors.New("chacha20poly1305: bad key length")
+	}
+	ret := new(chacha20poly1305)
+	copy(ret.key[:], key)
+	return ret, nil
+}
+
+func (c *chacha20poly1305) NonceSize() int {
+	return NonceSize
+}
+
+func (c *chacha20poly1305) Overhead() int {
+	return Overhead
+}
+
+func (c *chacha20poly1305) Seal(dst, nonce, plaintext, additionalData []byte) []byte {
+	if len(nonce) != NonceSize {
+		panic("chacha20poly1305: bad nonce length passed to Seal")
+	}
+
+	if uint64(len(plaintext)) > (1<<38)-64 {
+		panic("chacha20poly1305: plaintext too large")
+	}
+
+	return c.seal(dst, nonce, plaintext, additionalData)
+}
+
+var errOpen = errors.New("chacha20poly1305: message authentication failed")
+
+func (c *chacha20poly1305) Open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) {
+	if len(nonce) != NonceSize {
+		panic("chacha20poly1305: bad nonce length passed to Open")
+	}
+	if len(ciphertext) < 16 {
+		return nil, errOpen
+	}
+	if uint64(len(ciphertext)) > (1<<38)-48 {
+		panic("chacha20poly1305: ciphertext too large")
+	}
+
+	return c.open(dst, nonce, ciphertext, additionalData)
+}
+
+// sliceForAppend takes a slice and a requested number of bytes. It returns a
+// slice with the contents of the given slice followed by that many bytes and a
+// second slice that aliases into it and contains only the extra bytes. If the
+// original slice has sufficient capacity then no allocation is performed.
+func sliceForAppend(in []byte, n int) (head, tail []byte) {
+	if total := len(in) + n; cap(in) >= total {
+		head = in[:total]
+	} else {
+		head = make([]byte, total)
+		copy(head, in)
+	}
+	tail = head[len(in):]
+	return
+}
diff --git a/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.go b/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.go
new file mode 100644
index 0000000000..25959b9a6e
--- /dev/null
+++ b/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.go
@@ -0,0 +1,87 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build gc && !purego
+// +build gc,!purego
+
+package chacha20poly1305
+
+import (
+	"encoding/binary"
+
+	"golang.org/x/crypto/internal/subtle"
+	"golang.org/x/sys/cpu"
+)
+
+//go:noescape
+func chacha20Poly1305Open(dst []byte, key []uint32, src, ad []byte) bool
+
+//go:noescape
+func chacha20Poly1305Seal(dst []byte, key []uint32, src, ad []byte)
+
+var (
+	useAVX2 = cpu.X86.HasAVX2 && cpu.X86.HasBMI2
+)
+
+// setupState writes a ChaCha20 input matrix to state. See
+// https://tools.ietf.org/html/rfc7539#section-2.3.
+func setupState(state *[16]uint32, key *[32]byte, nonce []byte) {
+	state[0] = 0x61707865
+	state[1] = 0x3320646e
+	state[2] = 0x79622d32
+	state[3] = 0x6b206574
+
+	state[4] = binary.LittleEndian.Uint32(key[0:4])
+	state[5] = binary.LittleEndian.Uint32(key[4:8])
+	state[6] = binary.LittleEndian.Uint32(key[8:12])
+	state[7] = binary.LittleEndian.Uint32(key[12:16])
+	state[8] = binary.LittleEndian.Uint32(key[16:20])
+	state[9] = binary.LittleEndian.Uint32(key[20:24])
+	state[10] = binary.LittleEndian.Uint32(key[24:28])
+	state[11] = binary.LittleEndian.Uint32(key[28:32])
+
+	state[12] = 0
+	state[13] = binary.LittleEndian.Uint32(nonce[0:4])
+	state[14] = binary.LittleEndian.Uint32(nonce[4:8])
+	state[15] = binary.LittleEndian.Uint32(nonce[8:12])
+}
+
+func (c *chacha20poly1305) seal(dst, nonce, plaintext, additionalData []byte) []byte {
+	if !cpu.X86.HasSSSE3 {
+		return c.sealGeneric(dst, nonce, plaintext, additionalData)
+	}
+
+	var state [16]uint32
+	setupState(&state, &c.key, nonce)
+
+	ret, out := sliceForAppend(dst, len(plaintext)+16)
+	if subtle.InexactOverlap(out, plaintext) {
+		panic("chacha20poly1305: invalid buffer overlap")
+	}
+	chacha20Poly1305Seal(out[:], state[:], plaintext, additionalData)
+	return ret
+}
+
+func (c *chacha20poly1305) open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) {
+	if !cpu.X86.HasSSSE3 {
+		return c.openGeneric(dst, nonce, ciphertext, additionalData)
+	}
+
+	var state [16]uint32
+	setupState(&state, &c.key, nonce)
+
+	ciphertext = ciphertext[:len(ciphertext)-16]
+	ret, out := sliceForAppend(dst, len(ciphertext))
+	if subtle.InexactOverlap(out, ciphertext) {
+		panic("chacha20poly1305: invalid buffer overlap")
+	}
+	if !chacha20Poly1305Open(out, state[:], ciphertext, additionalData) {
+		for i := range out {
+			out[i] = 0
+		}
+		return nil, errOpen
+	}
+
+	return ret, nil
+}
diff --git a/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.s b/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.s
new file mode 100644
index 0000000000..867c181a14
--- /dev/null
+++ b/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.s
@@ -0,0 +1,2696 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file was originally from https://golang.org/cl/24717 by Vlad Krasnov of CloudFlare.
+
+//go:build gc && !purego
+// +build gc,!purego
+
+#include "textflag.h"
+// General register allocation
+#define oup DI
+#define inp SI
+#define inl BX
+#define adp CX // free to reuse, after we hash the additional data
+#define keyp R8 // free to reuse, when we copy the key to stack
+#define itr2 R9 // general iterator
+#define itr1 CX // general iterator
+#define acc0 R10
+#define acc1 R11
+#define acc2 R12
+#define t0 R13
+#define t1 R14
+#define t2 R15
+#define t3 R8
+// Register and stack allocation for the SSE code
+#define rStore (0*16)(BP)
+#define sStore (1*16)(BP)
+#define state1Store (2*16)(BP)
+#define state2Store (3*16)(BP)
+#define tmpStore (4*16)(BP)
+#define ctr0Store (5*16)(BP)
+#define ctr1Store (6*16)(BP)
+#define ctr2Store (7*16)(BP)
+#define ctr3Store (8*16)(BP)
+#define A0 X0
+#define A1 X1
+#define A2 X2
+#define B0 X3
+#define B1 X4
+#define B2 X5
+#define C0 X6
+#define C1 X7
+#define C2 X8
+#define D0 X9
+#define D1 X10
+#define D2 X11
+#define T0 X12
+#define T1 X13
+#define T2 X14
+#define T3 X15
+#define A3 T0
+#define B3 T1
+#define C3 T2
+#define D3 T3
+// Register and stack allocation for the AVX2 code
+#define rsStoreAVX2 (0*32)(BP)
+#define state1StoreAVX2 (1*32)(BP)
+#define state2StoreAVX2 (2*32)(BP)
+#define ctr0StoreAVX2 (3*32)(BP)
+#define ctr1StoreAVX2 (4*32)(BP)
+#define ctr2StoreAVX2 (5*32)(BP)
+#define ctr3StoreAVX2 (6*32)(BP)
+#define tmpStoreAVX2 (7*32)(BP) // 256 bytes on stack
+#define AA0 Y0
+#define AA1 Y5
+#define AA2 Y6
+#define AA3 Y7
+#define BB0 Y14
+#define BB1 Y9
+#define BB2 Y10
+#define BB3 Y11
+#define CC0 Y12
+#define CC1 Y13
+#define CC2 Y8
+#define CC3 Y15
+#define DD0 Y4
+#define DD1 Y1
+#define DD2 Y2
+#define DD3 Y3
+#define TT0 DD3
+#define TT1 AA3
+#define TT2 BB3
+#define TT3 CC3
+// ChaCha20 constants
+DATA ·chacha20Constants<>+0x00(SB)/4, $0x61707865
+DATA ·chacha20Constants<>+0x04(SB)/4, $0x3320646e
+DATA ·chacha20Constants<>+0x08(SB)/4, $0x79622d32
+DATA ·chacha20Constants<>+0x0c(SB)/4, $0x6b206574
+DATA ·chacha20Constants<>+0x10(SB)/4, $0x61707865
+DATA ·chacha20Constants<>+0x14(SB)/4, $0x3320646e
+DATA ·chacha20Constants<>+0x18(SB)/4, $0x79622d32
+DATA ·chacha20Constants<>+0x1c(SB)/4, $0x6b206574
+// <<< 16 with PSHUFB
+DATA ·rol16<>+0x00(SB)/8, $0x0504070601000302
+DATA ·rol16<>+0x08(SB)/8, $0x0D0C0F0E09080B0A
+DATA ·rol16<>+0x10(SB)/8, $0x0504070601000302
+DATA ·rol16<>+0x18(SB)/8, $0x0D0C0F0E09080B0A
+// <<< 8 with PSHUFB
+DATA ·rol8<>+0x00(SB)/8, $0x0605040702010003
+DATA ·rol8<>+0x08(SB)/8, $0x0E0D0C0F0A09080B
+DATA ·rol8<>+0x10(SB)/8, $0x0605040702010003
+DATA ·rol8<>+0x18(SB)/8, $0x0E0D0C0F0A09080B
+
+DATA ·avx2InitMask<>+0x00(SB)/8, $0x0
+DATA ·avx2InitMask<>+0x08(SB)/8, $0x0
+DATA ·avx2InitMask<>+0x10(SB)/8, $0x1
+DATA ·avx2InitMask<>+0x18(SB)/8, $0x0
+
+DATA ·avx2IncMask<>+0x00(SB)/8, $0x2
+DATA ·avx2IncMask<>+0x08(SB)/8, $0x0
+DATA ·avx2IncMask<>+0x10(SB)/8, $0x2
+DATA ·avx2IncMask<>+0x18(SB)/8, $0x0
+// Poly1305 key clamp
+DATA ·polyClampMask<>+0x00(SB)/8, $0x0FFFFFFC0FFFFFFF
+DATA ·polyClampMask<>+0x08(SB)/8, $0x0FFFFFFC0FFFFFFC
+DATA ·polyClampMask<>+0x10(SB)/8, $0xFFFFFFFFFFFFFFFF
+DATA ·polyClampMask<>+0x18(SB)/8, $0xFFFFFFFFFFFFFFFF
+
+DATA ·sseIncMask<>+0x00(SB)/8, $0x1
+DATA ·sseIncMask<>+0x08(SB)/8, $0x0
+// To load/store the last < 16 bytes in a buffer
+DATA ·andMask<>+0x00(SB)/8, $0x00000000000000ff
+DATA ·andMask<>+0x08(SB)/8, $0x0000000000000000
+DATA ·andMask<>+0x10(SB)/8, $0x000000000000ffff
+DATA ·andMask<>+0x18(SB)/8, $0x0000000000000000
+DATA ·andMask<>+0x20(SB)/8, $0x0000000000ffffff
+DATA ·andMask<>+0x28(SB)/8, $0x0000000000000000
+DATA ·andMask<>+0x30(SB)/8, $0x00000000ffffffff
+DATA ·andMask<>+0x38(SB)/8, $0x0000000000000000
+DATA ·andMask<>+0x40(SB)/8, $0x000000ffffffffff
+DATA ·andMask<>+0x48(SB)/8, $0x0000000000000000
+DATA ·andMask<>+0x50(SB)/8, $0x0000ffffffffffff
+DATA ·andMask<>+0x58(SB)/8, $0x0000000000000000
+DATA ·andMask<>+0x60(SB)/8, $0x00ffffffffffffff
+DATA ·andMask<>+0x68(SB)/8, $0x0000000000000000
+DATA ·andMask<>+0x70(SB)/8, $0xffffffffffffffff
+DATA ·andMask<>+0x78(SB)/8, $0x0000000000000000
+DATA ·andMask<>+0x80(SB)/8, $0xffffffffffffffff
+DATA ·andMask<>+0x88(SB)/8, $0x00000000000000ff
+DATA ·andMask<>+0x90(SB)/8, $0xffffffffffffffff
+DATA ·andMask<>+0x98(SB)/8, $0x000000000000ffff
+DATA ·andMask<>+0xa0(SB)/8, $0xffffffffffffffff
+DATA ·andMask<>+0xa8(SB)/8, $0x0000000000ffffff
+DATA ·andMask<>+0xb0(SB)/8, $0xffffffffffffffff
+DATA ·andMask<>+0xb8(SB)/8, $0x00000000ffffffff
+DATA ·andMask<>+0xc0(SB)/8, $0xffffffffffffffff
+DATA ·andMask<>+0xc8(SB)/8, $0x000000ffffffffff
+DATA ·andMask<>+0xd0(SB)/8, $0xffffffffffffffff
+DATA ·andMask<>+0xd8(SB)/8, $0x0000ffffffffffff
+DATA ·andMask<>+0xe0(SB)/8, $0xffffffffffffffff
+DATA ·andMask<>+0xe8(SB)/8, $0x00ffffffffffffff
+
+GLOBL ·chacha20Constants<>(SB), (NOPTR+RODATA), $32
+GLOBL ·rol16<>(SB), (NOPTR+RODATA), $32
+GLOBL ·rol8<>(SB), (NOPTR+RODATA), $32
+GLOBL ·sseIncMask<>(SB), (NOPTR+RODATA), $16
+GLOBL ·avx2IncMask<>(SB), (NOPTR+RODATA), $32
+GLOBL ·avx2InitMask<>(SB), (NOPTR+RODATA), $32
+GLOBL ·polyClampMask<>(SB), (NOPTR+RODATA), $32
+GLOBL ·andMask<>(SB), (NOPTR+RODATA), $240
+// No PALIGNR in Go ASM yet (but VPALIGNR is present).
+#define shiftB0Left BYTE $0x66; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xdb; BYTE $0x04 // PALIGNR $4, X3, X3
+#define shiftB1Left BYTE $0x66; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xe4; BYTE $0x04 // PALIGNR $4, X4, X4
+#define shiftB2Left BYTE $0x66; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xed; BYTE $0x04 // PALIGNR $4, X5, X5
+#define shiftB3Left BYTE $0x66; BYTE $0x45; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xed; BYTE $0x04 // PALIGNR $4, X13, X13
+#define shiftC0Left BYTE $0x66; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xf6; BYTE $0x08 // PALIGNR $8, X6, X6
+#define shiftC1Left BYTE $0x66; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xff; BYTE $0x08 // PALIGNR $8, X7, X7
+#define shiftC2Left BYTE $0x66; BYTE $0x45; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xc0; BYTE $0x08 // PALIGNR $8, X8, X8
+#define shiftC3Left BYTE $0x66; BYTE $0x45; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xf6; BYTE $0x08 // PALIGNR $8, X14, X14
+#define shiftD0Left BYTE $0x66; BYTE $0x45; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xc9; BYTE $0x0c // PALIGNR $12, X9, X9
+#define shiftD1Left BYTE $0x66; BYTE $0x45; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xd2; BYTE $0x0c // PALIGNR $12, X10, X10
+#define shiftD2Left BYTE $0x66; BYTE $0x45; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xdb; BYTE $0x0c // PALIGNR $12, X11, X11
+#define shiftD3Left BYTE $0x66; BYTE $0x45; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xff; BYTE $0x0c // PALIGNR $12, X15, X15
+#define shiftB0Right BYTE $0x66; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xdb; BYTE $0x0c // PALIGNR $12, X3, X3
+#define shiftB1Right BYTE $0x66; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xe4; BYTE $0x0c // PALIGNR $12, X4, X4
+#define shiftB2Right BYTE $0x66; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xed; BYTE $0x0c // PALIGNR $12, X5, X5
+#define shiftB3Right BYTE $0x66; BYTE $0x45; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xed; BYTE $0x0c // PALIGNR $12, X13, X13
+#define shiftC0Right shiftC0Left
+#define shiftC1Right shiftC1Left
+#define shiftC2Right shiftC2Left
+#define shiftC3Right shiftC3Left
+#define shiftD0Right BYTE $0x66; BYTE $0x45; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xc9; BYTE $0x04 // PALIGNR $4, X9, X9
+#define shiftD1Right BYTE $0x66; BYTE $0x45; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xd2; BYTE $0x04 // PALIGNR $4, X10, X10
+#define shiftD2Right BYTE $0x66; BYTE $0x45; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xdb; BYTE $0x04 // PALIGNR $4, X11, X11
+#define shiftD3Right BYTE $0x66; BYTE $0x45; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xff; BYTE $0x04 // PALIGNR $4, X15, X15
+// Some macros
+#define chachaQR(A, B, C, D, T) \
+	PADDD B, A; PXOR A, D; PSHUFB ·rol16<>(SB), D                            \
+	PADDD D, C; PXOR C, B; MOVO B, T; PSLLL $12, T; PSRLL $20, B; PXOR T, B \
+	PADDD B, A; PXOR A, D; PSHUFB ·rol8<>(SB), D                             \
+	PADDD D, C; PXOR C, B; MOVO B, T; PSLLL $7, T; PSRLL $25, B; PXOR T, B
+
+#define chachaQR_AVX2(A, B, C, D, T) \
+	VPADDD B, A, A; VPXOR A, D, D; VPSHUFB ·rol16<>(SB), D, D                         \
+	VPADDD D, C, C; VPXOR C, B, B; VPSLLD $12, B, T; VPSRLD $20, B, B; VPXOR T, B, B \
+	VPADDD B, A, A; VPXOR A, D, D; VPSHUFB ·rol8<>(SB), D, D                          \
+	VPADDD D, C, C; VPXOR C, B, B; VPSLLD $7, B, T; VPSRLD $25, B, B; VPXOR T, B, B
+
+#define polyAdd(S) ADDQ S, acc0; ADCQ 8+S, acc1; ADCQ $1, acc2
+#define polyMulStage1 MOVQ (0*8)(BP), AX; MOVQ AX, t2; MULQ acc0; MOVQ AX, t0; MOVQ DX, t1; MOVQ (0*8)(BP), AX; MULQ acc1; IMULQ acc2, t2; ADDQ AX, t1; ADCQ DX, t2
+#define polyMulStage2 MOVQ (1*8)(BP), AX; MOVQ AX, t3; MULQ acc0; ADDQ AX, t1; ADCQ $0, DX; MOVQ DX, acc0; MOVQ (1*8)(BP), AX; MULQ acc1; ADDQ AX, t2; ADCQ $0, DX
+#define polyMulStage3 IMULQ acc2, t3; ADDQ acc0, t2; ADCQ DX, t3
+#define polyMulReduceStage MOVQ t0, acc0; MOVQ t1, acc1; MOVQ t2, acc2; ANDQ $3, acc2; MOVQ t2, t0; ANDQ $-4, t0; MOVQ t3, t1; SHRQ $2, t3, t2; SHRQ $2, t3; ADDQ t0, acc0; ADCQ t1, acc1; ADCQ $0, acc2; ADDQ t2, acc0; ADCQ t3, acc1; ADCQ $0, acc2
+
+#define polyMulStage1_AVX2 MOVQ (0*8)(BP), DX; MOVQ DX, t2; MULXQ acc0, t0, t1; IMULQ acc2, t2; MULXQ acc1, AX, DX; ADDQ AX, t1; ADCQ DX, t2
+#define polyMulStage2_AVX2 MOVQ (1*8)(BP), DX; MULXQ acc0, acc0, AX; ADDQ acc0, t1; MULXQ acc1, acc1, t3; ADCQ acc1, t2; ADCQ $0, t3
+#define polyMulStage3_AVX2 IMULQ acc2, DX; ADDQ AX, t2; ADCQ DX, t3
+
+#define polyMul polyMulStage1; polyMulStage2; polyMulStage3; polyMulReduceStage
+#define polyMulAVX2 polyMulStage1_AVX2; polyMulStage2_AVX2; polyMulStage3_AVX2; polyMulReduceStage
+// ----------------------------------------------------------------------------
+TEXT polyHashADInternal<>(SB), NOSPLIT, $0
+	// adp points to beginning of additional data
+	// itr2 holds ad length
+	XORQ acc0, acc0
+	XORQ acc1, acc1
+	XORQ acc2, acc2
+	CMPQ itr2, $13
+	JNE  hashADLoop
+
+openFastTLSAD:
+	// Special treatment for the TLS case of 13 bytes
+	MOVQ (adp), acc0
+	MOVQ 5(adp), acc1
+	SHRQ $24, acc1
+	MOVQ $1, acc2
+	polyMul
+	RET
+
+hashADLoop:
+	// Hash in 16 byte chunks
+	CMPQ itr2, $16
+	JB   hashADTail
+	polyAdd(0(adp))
+	LEAQ (1*16)(adp), adp
+	SUBQ $16, itr2
+	polyMul
+	JMP  hashADLoop
+
+hashADTail:
+	CMPQ itr2, $0
+	JE   hashADDone
+
+	// Hash last < 16 byte tail
+	XORQ t0, t0
+	XORQ t1, t1
+	XORQ t2, t2
+	ADDQ itr2, adp
+
+hashADTailLoop:
+	SHLQ $8, t0, t1
+	SHLQ $8, t0
+	MOVB -1(adp), t2
+	XORQ t2, t0
+	DECQ adp
+	DECQ itr2
+	JNE  hashADTailLoop
+
+hashADTailFinish:
+	ADDQ t0, acc0; ADCQ t1, acc1; ADCQ $1, acc2
+	polyMul
+
+	// Finished AD
+hashADDone:
+	RET
+
+// ----------------------------------------------------------------------------
+// func chacha20Poly1305Open(dst, key, src, ad []byte) bool
+TEXT ·chacha20Poly1305Open(SB), 0, $288-97
+	// For aligned stack access
+	MOVQ SP, BP
+	ADDQ $32, BP
+	ANDQ $-32, BP
+	MOVQ dst+0(FP), oup
+	MOVQ key+24(FP), keyp
+	MOVQ src+48(FP), inp
+	MOVQ src_len+56(FP), inl
+	MOVQ ad+72(FP), adp
+
+	// Check for AVX2 support
+	CMPB ·useAVX2(SB), $1
+	JE   chacha20Poly1305Open_AVX2
+
+	// Special optimization, for very short buffers
+	CMPQ inl, $128
+	JBE  openSSE128 // About 16% faster
+
+	// For long buffers, prepare the poly key first
+	MOVOU ·chacha20Constants<>(SB), A0
+	MOVOU (1*16)(keyp), B0
+	MOVOU (2*16)(keyp), C0
+	MOVOU (3*16)(keyp), D0
+	MOVO  D0, T1
+
+	// Store state on stack for future use
+	MOVO B0, state1Store
+	MOVO C0, state2Store
+	MOVO D0, ctr3Store
+	MOVQ $10, itr2
+
+openSSEPreparePolyKey:
+	chachaQR(A0, B0, C0, D0, T0)
+	shiftB0Left;  shiftC0Left; shiftD0Left
+	chachaQR(A0, B0, C0, D0, T0)
+	shiftB0Right; shiftC0Right; shiftD0Right
+	DECQ          itr2
+	JNE           openSSEPreparePolyKey
+
+	// A0|B0 hold the Poly1305 32-byte key, C0,D0 can be discarded
+	PADDL ·chacha20Constants<>(SB), A0; PADDL state1Store, B0
+
+	// Clamp and store the key
+	PAND ·polyClampMask<>(SB), A0
+	MOVO A0, rStore; MOVO B0, sStore
+
+	// Hash AAD
+	MOVQ ad_len+80(FP), itr2
+	CALL polyHashADInternal<>(SB)
+
+openSSEMainLoop:
+	CMPQ inl, $256
+	JB   openSSEMainLoopDone
+
+	// Load state, increment counter blocks
+	MOVO ·chacha20Constants<>(SB), A0; MOVO state1Store, B0; MOVO state2Store, C0; MOVO ctr3Store, D0; PADDL ·sseIncMask<>(SB), D0
+	MOVO A0, A1; MOVO B0, B1; MOVO C0, C1; MOVO D0, D1; PADDL ·sseIncMask<>(SB), D1
+	MOVO A1, A2; MOVO B1, B2; MOVO C1, C2; MOVO D1, D2; PADDL ·sseIncMask<>(SB), D2
+	MOVO A2, A3; MOVO B2, B3; MOVO C2, C3; MOVO D2, D3; PADDL ·sseIncMask<>(SB), D3
+
+	// Store counters
+	MOVO D0, ctr0Store; MOVO D1, ctr1Store; MOVO D2, ctr2Store; MOVO D3, ctr3Store
+
+	// There are 10 ChaCha20 iterations of 2QR each, so for 6 iterations we hash 2 blocks, and for the remaining 4 only 1 block - for a total of 16
+	MOVQ $4, itr1
+	MOVQ inp, itr2
+
+openSSEInternalLoop:
+	MOVO          C3, tmpStore
+	chachaQR(A0, B0, C0, D0, C3); chachaQR(A1, B1, C1, D1, C3); chachaQR(A2, B2, C2, D2, C3)
+	MOVO          tmpStore, C3
+	MOVO          C1, tmpStore
+	chachaQR(A3, B3, C3, D3, C1)
+	MOVO          tmpStore, C1
+	polyAdd(0(itr2))
+	shiftB0Left;  shiftB1Left; shiftB2Left; shiftB3Left
+	shiftC0Left;  shiftC1Left; shiftC2Left; shiftC3Left
+	shiftD0Left;  shiftD1Left; shiftD2Left; shiftD3Left
+	polyMulStage1
+	polyMulStage2
+	LEAQ          (2*8)(itr2), itr2
+	MOVO          C3, tmpStore
+	chachaQR(A0, B0, C0, D0, C3); chachaQR(A1, B1, C1, D1, C3); chachaQR(A2, B2, C2, D2, C3)
+	MOVO          tmpStore, C3
+	MOVO          C1, tmpStore
+	polyMulStage3
+	chachaQR(A3, B3, C3, D3, C1)
+	MOVO          tmpStore, C1
+	polyMulReduceStage
+	shiftB0Right; shiftB1Right; shiftB2Right; shiftB3Right
+	shiftC0Right; shiftC1Right; shiftC2Right; shiftC3Right
+	shiftD0Right; shiftD1Right; shiftD2Right; shiftD3Right
+	DECQ          itr1
+	JGE           openSSEInternalLoop
+
+	polyAdd(0(itr2))
+	polyMul
+	LEAQ (2*8)(itr2), itr2
+
+	CMPQ itr1, $-6
+	JG   openSSEInternalLoop
+
+	// Add in the state
+	PADDD ·chacha20Constants<>(SB), A0; PADDD ·chacha20Constants<>(SB), A1; PADDD ·chacha20Constants<>(SB), A2; PADDD ·chacha20Constants<>(SB), A3
+	PADDD state1Store, B0; PADDD state1Store, B1; PADDD state1Store, B2; PADDD state1Store, B3
+	PADDD state2Store, C0; PADDD state2Store, C1; PADDD state2Store, C2; PADDD state2Store, C3
+	PADDD ctr0Store, D0; PADDD ctr1Store, D1; PADDD ctr2Store, D2; PADDD ctr3Store, D3
+
+	// Load - xor - store
+	MOVO  D3, tmpStore
+	MOVOU (0*16)(inp), D3; PXOR D3, A0; MOVOU A0, (0*16)(oup)
+	MOVOU (1*16)(inp), D3; PXOR D3, B0; MOVOU B0, (1*16)(oup)
+	MOVOU (2*16)(inp), D3; PXOR D3, C0; MOVOU C0, (2*16)(oup)
+	MOVOU (3*16)(inp), D3; PXOR D3, D0; MOVOU D0, (3*16)(oup)
+	MOVOU (4*16)(inp), D0; PXOR D0, A1; MOVOU A1, (4*16)(oup)
+	MOVOU (5*16)(inp), D0; PXOR D0, B1; MOVOU B1, (5*16)(oup)
+	MOVOU (6*16)(inp), D0; PXOR D0, C1; MOVOU C1, (6*16)(oup)
+	MOVOU (7*16)(inp), D0; PXOR D0, D1; MOVOU D1, (7*16)(oup)
+	MOVOU (8*16)(inp), D0; PXOR D0, A2; MOVOU A2, (8*16)(oup)
+	MOVOU (9*16)(inp), D0; PXOR D0, B2; MOVOU B2, (9*16)(oup)
+	MOVOU (10*16)(inp), D0; PXOR D0, C2; MOVOU C2, (10*16)(oup)
+	MOVOU (11*16)(inp), D0; PXOR D0, D2; MOVOU D2, (11*16)(oup)
+	MOVOU (12*16)(inp), D0; PXOR D0, A3; MOVOU A3, (12*16)(oup)
+	MOVOU (13*16)(inp), D0; PXOR D0, B3; MOVOU B3, (13*16)(oup)
+	MOVOU (14*16)(inp), D0; PXOR D0, C3; MOVOU C3, (14*16)(oup)
+	MOVOU (15*16)(inp), D0; PXOR tmpStore, D0; MOVOU D0, (15*16)(oup)
+	LEAQ  256(inp), inp
+	LEAQ  256(oup), oup
+	SUBQ  $256, inl
+	JMP   openSSEMainLoop
+
+openSSEMainLoopDone:
+	// Handle the various tail sizes efficiently
+	TESTQ inl, inl
+	JE    openSSEFinalize
+	CMPQ  inl, $64
+	JBE   openSSETail64
+	CMPQ  inl, $128
+	JBE   openSSETail128
+	CMPQ  inl, $192
+	JBE   openSSETail192
+	JMP   openSSETail256
+
+openSSEFinalize:
+	// Hash in the PT, AAD lengths
+	ADDQ ad_len+80(FP), acc0; ADCQ src_len+56(FP), acc1; ADCQ $1, acc2
+	polyMul
+
+	// Final reduce
+	MOVQ    acc0, t0
+	MOVQ    acc1, t1
+	MOVQ    acc2, t2
+	SUBQ    $-5, acc0
+	SBBQ    $-1, acc1
+	SBBQ    $3, acc2
+	CMOVQCS t0, acc0
+	CMOVQCS t1, acc1
+	CMOVQCS t2, acc2
+
+	// Add in the "s" part of the key
+	ADDQ 0+sStore, acc0
+	ADCQ 8+sStore, acc1
+
+	// Finally, constant time compare to the tag at the end of the message
+	XORQ    AX, AX
+	MOVQ    $1, DX
+	XORQ    (0*8)(inp), acc0
+	XORQ    (1*8)(inp), acc1
+	ORQ     acc1, acc0
+	CMOVQEQ DX, AX
+
+	// Return true iff tags are equal
+	MOVB AX, ret+96(FP)
+	RET
+
+// ----------------------------------------------------------------------------
+// Special optimization for buffers smaller than 129 bytes
+openSSE128:
+	// For up to 128 bytes of ciphertext and 64 bytes for the poly key, we require to process three blocks
+	MOVOU ·chacha20Constants<>(SB), A0; MOVOU (1*16)(keyp), B0; MOVOU (2*16)(keyp), C0; MOVOU (3*16)(keyp), D0
+	MOVO  A0, A1; MOVO B0, B1; MOVO C0, C1; MOVO D0, D1; PADDL ·sseIncMask<>(SB), D1
+	MOVO  A1, A2; MOVO B1, B2; MOVO C1, C2; MOVO D1, D2; PADDL ·sseIncMask<>(SB), D2
+	MOVO  B0, T1; MOVO C0, T2; MOVO D1, T3
+	MOVQ  $10, itr2
+
+openSSE128InnerCipherLoop:
+	chachaQR(A0, B0, C0, D0, T0); chachaQR(A1, B1, C1, D1, T0); chachaQR(A2, B2, C2, D2, T0)
+	shiftB0Left;  shiftB1Left; shiftB2Left
+	shiftC0Left;  shiftC1Left; shiftC2Left
+	shiftD0Left;  shiftD1Left; shiftD2Left
+	chachaQR(A0, B0, C0, D0, T0); chachaQR(A1, B1, C1, D1, T0); chachaQR(A2, B2, C2, D2, T0)
+	shiftB0Right; shiftB1Right; shiftB2Right
+	shiftC0Right; shiftC1Right; shiftC2Right
+	shiftD0Right; shiftD1Right; shiftD2Right
+	DECQ          itr2
+	JNE           openSSE128InnerCipherLoop
+
+	// A0|B0 hold the Poly1305 32-byte key, C0,D0 can be discarded
+	PADDL ·chacha20Constants<>(SB), A0; PADDL ·chacha20Constants<>(SB), A1; PADDL ·chacha20Constants<>(SB), A2
+	PADDL T1, B0; PADDL T1, B1; PADDL T1, B2
+	PADDL T2, C1; PADDL T2, C2
+	PADDL T3, D1; PADDL ·sseIncMask<>(SB), T3; PADDL T3, D2
+
+	// Clamp and store the key
+	PAND  ·polyClampMask<>(SB), A0
+	MOVOU A0, rStore; MOVOU B0, sStore
+
+	// Hash
+	MOVQ ad_len+80(FP), itr2
+	CALL polyHashADInternal<>(SB)
+
+openSSE128Open:
+	CMPQ inl, $16
+	JB   openSSETail16
+	SUBQ $16, inl
+
+	// Load for hashing
+	polyAdd(0(inp))
+
+	// Load for decryption
+	MOVOU (inp), T0; PXOR T0, A1; MOVOU A1, (oup)
+	LEAQ  (1*16)(inp), inp
+	LEAQ  (1*16)(oup), oup
+	polyMul
+
+	// Shift the stream "left"
+	MOVO B1, A1
+	MOVO C1, B1
+	MOVO D1, C1
+	MOVO A2, D1
+	MOVO B2, A2
+	MOVO C2, B2
+	MOVO D2, C2
+	JMP  openSSE128Open
+
+openSSETail16:
+	TESTQ inl, inl
+	JE    openSSEFinalize
+
+	// We can safely load the CT from the end, because it is padded with the MAC
+	MOVQ   inl, itr2
+	SHLQ   $4, itr2
+	LEAQ   ·andMask<>(SB), t0
+	MOVOU  (inp), T0
+	ADDQ   inl, inp
+	PAND   -16(t0)(itr2*1), T0
+	MOVO   T0, 0+tmpStore
+	MOVQ   T0, t0
+	MOVQ   8+tmpStore, t1
+	PXOR   A1, T0
+
+	// We can only store one byte at a time, since plaintext can be shorter than 16 bytes
+openSSETail16Store:
+	MOVQ T0, t3
+	MOVB t3, (oup)
+	PSRLDQ $1, T0
+	INCQ   oup
+	DECQ   inl
+	JNE    openSSETail16Store
+	ADDQ   t0, acc0; ADCQ t1, acc1; ADCQ $1, acc2
+	polyMul
+	JMP    openSSEFinalize
+
+// ----------------------------------------------------------------------------
+// Special optimization for the last 64 bytes of ciphertext
+openSSETail64:
+	// Need to decrypt up to 64 bytes - prepare single block
+	MOVO ·chacha20Constants<>(SB), A0; MOVO state1Store, B0; MOVO state2Store, C0; MOVO ctr3Store, D0; PADDL ·sseIncMask<>(SB), D0; MOVO D0, ctr0Store
+	XORQ itr2, itr2
+	MOVQ inl, itr1
+	CMPQ itr1, $16
+	JB   openSSETail64LoopB
+
+openSSETail64LoopA:
+	// Perform ChaCha rounds, while hashing the remaining input
+	polyAdd(0(inp)(itr2*1))
+	polyMul
+	SUBQ $16, itr1
+
+openSSETail64LoopB:
+	ADDQ          $16, itr2
+	chachaQR(A0, B0, C0, D0, T0)
+	shiftB0Left;  shiftC0Left; shiftD0Left
+	chachaQR(A0, B0, C0, D0, T0)
+	shiftB0Right; shiftC0Right; shiftD0Right
+
+	CMPQ itr1, $16
+	JAE  openSSETail64LoopA
+
+	CMPQ itr2, $160
+	JNE  openSSETail64LoopB
+
+	PADDL ·chacha20Constants<>(SB), A0; PADDL state1Store, B0; PADDL state2Store, C0; PADDL ctr0Store, D0
+
+openSSETail64DecLoop:
+	CMPQ  inl, $16
+	JB    openSSETail64DecLoopDone
+	SUBQ  $16, inl
+	MOVOU (inp), T0
+	PXOR  T0, A0
+	MOVOU A0, (oup)
+	LEAQ  16(inp), inp
+	LEAQ  16(oup), oup
+	MOVO  B0, A0
+	MOVO  C0, B0
+	MOVO  D0, C0
+	JMP   openSSETail64DecLoop
+
+openSSETail64DecLoopDone:
+	MOVO A0, A1
+	JMP  openSSETail16
+
+// ----------------------------------------------------------------------------
+// Special optimization for the last 128 bytes of ciphertext
+openSSETail128:
+	// Need to decrypt up to 128 bytes - prepare two blocks
+	MOVO ·chacha20Constants<>(SB), A1; MOVO state1Store, B1; MOVO state2Store, C1; MOVO ctr3Store, D1; PADDL ·sseIncMask<>(SB), D1; MOVO D1, ctr0Store
+	MOVO A1, A0; MOVO B1, B0; MOVO C1, C0; MOVO D1, D0; PADDL ·sseIncMask<>(SB), D0; MOVO D0, ctr1Store
+	XORQ itr2, itr2
+	MOVQ inl, itr1
+	ANDQ $-16, itr1
+
+openSSETail128LoopA:
+	// Perform ChaCha rounds, while hashing the remaining input
+	polyAdd(0(inp)(itr2*1))
+	polyMul
+
+openSSETail128LoopB:
+	ADDQ          $16, itr2
+	chachaQR(A0, B0, C0, D0, T0); chachaQR(A1, B1, C1, D1, T0)
+	shiftB0Left;  shiftC0Left; shiftD0Left
+	shiftB1Left;  shiftC1Left; shiftD1Left
+	chachaQR(A0, B0, C0, D0, T0); chachaQR(A1, B1, C1, D1, T0)
+	shiftB0Right; shiftC0Right; shiftD0Right
+	shiftB1Right; shiftC1Right; shiftD1Right
+
+	CMPQ itr2, itr1
+	JB   openSSETail128LoopA
+
+	CMPQ itr2, $160
+	JNE  openSSETail128LoopB
+
+	PADDL ·chacha20Constants<>(SB), A0; PADDL ·chacha20Constants<>(SB), A1
+	PADDL state1Store, B0; PADDL state1Store, B1
+	PADDL state2Store, C0; PADDL state2Store, C1
+	PADDL ctr1Store, D0; PADDL ctr0Store, D1
+
+	MOVOU (0*16)(inp), T0; MOVOU (1*16)(inp), T1; MOVOU (2*16)(inp), T2; MOVOU (3*16)(inp), T3
+	PXOR  T0, A1; PXOR T1, B1; PXOR T2, C1; PXOR T3, D1
+	MOVOU A1, (0*16)(oup); MOVOU B1, (1*16)(oup); MOVOU C1, (2*16)(oup); MOVOU D1, (3*16)(oup)
+
+	SUBQ $64, inl
+	LEAQ 64(inp), inp
+	LEAQ 64(oup), oup
+	JMP  openSSETail64DecLoop
+
+// ----------------------------------------------------------------------------
+// Special optimization for the last 192 bytes of ciphertext
+openSSETail192:
+	// Need to decrypt up to 192 bytes - prepare three blocks
+	MOVO ·chacha20Constants<>(SB), A2; MOVO state1Store, B2; MOVO state2Store, C2; MOVO ctr3Store, D2; PADDL ·sseIncMask<>(SB), D2; MOVO D2, ctr0Store
+	MOVO A2, A1; MOVO B2, B1; MOVO C2, C1; MOVO D2, D1; PADDL ·sseIncMask<>(SB), D1; MOVO D1, ctr1Store
+	MOVO A1, A0; MOVO B1, B0; MOVO C1, C0; MOVO D1, D0; PADDL ·sseIncMask<>(SB), D0; MOVO D0, ctr2Store
+
+	MOVQ    inl, itr1
+	MOVQ    $160, itr2
+	CMPQ    itr1, $160
+	CMOVQGT itr2, itr1
+	ANDQ    $-16, itr1
+	XORQ    itr2, itr2
+
+openSSLTail192LoopA:
+	// Perform ChaCha rounds, while hashing the remaining input
+	polyAdd(0(inp)(itr2*1))
+	polyMul
+
+openSSLTail192LoopB:
+	ADDQ         $16, itr2
+	chachaQR(A0, B0, C0, D0, T0); chachaQR(A1, B1, C1, D1, T0); chachaQR(A2, B2, C2, D2, T0)
+	shiftB0Left; shiftC0Left; shiftD0Left
+	shiftB1Left; shiftC1Left; shiftD1Left
+	shiftB2Left; shiftC2Left; shiftD2Left
+
+	chachaQR(A0, B0, C0, D0, T0); chachaQR(A1, B1, C1, D1, T0); chachaQR(A2, B2, C2, D2, T0)
+	shiftB0Right; shiftC0Right; shiftD0Right
+	shiftB1Right; shiftC1Right; shiftD1Right
+	shiftB2Right; shiftC2Right; shiftD2Right
+
+	CMPQ itr2, itr1
+	JB   openSSLTail192LoopA
+
+	CMPQ itr2, $160
+	JNE  openSSLTail192LoopB
+
+	CMPQ inl, $176
+	JB   openSSLTail192Store
+
+	polyAdd(160(inp))
+	polyMul
+
+	CMPQ inl, $192
+	JB   openSSLTail192Store
+
+	polyAdd(176(inp))
+	polyMul
+
+openSSLTail192Store:
+	PADDL ·chacha20Constants<>(SB), A0; PADDL ·chacha20Constants<>(SB), A1; PADDL ·chacha20Constants<>(SB), A2
+	PADDL state1Store, B0; PADDL state1Store, B1; PADDL state1Store, B2
+	PADDL state2Store, C0; PADDL state2Store, C1; PADDL state2Store, C2
+	PADDL ctr2Store, D0; PADDL ctr1Store, D1; PADDL ctr0Store, D2
+
+	MOVOU (0*16)(inp), T0; MOVOU (1*16)(inp), T1; MOVOU (2*16)(inp), T2; MOVOU (3*16)(inp), T3
+	PXOR  T0, A2; PXOR T1, B2; PXOR T2, C2; PXOR T3, D2
+	MOVOU A2, (0*16)(oup); MOVOU B2, (1*16)(oup); MOVOU C2, (2*16)(oup); MOVOU D2, (3*16)(oup)
+
+	MOVOU (4*16)(inp), T0; MOVOU (5*16)(inp), T1; MOVOU (6*16)(inp), T2; MOVOU (7*16)(inp), T3
+	PXOR  T0, A1; PXOR T1, B1; PXOR T2, C1; PXOR T3, D1
+	MOVOU A1, (4*16)(oup); MOVOU B1, (5*16)(oup); MOVOU C1, (6*16)(oup); MOVOU D1, (7*16)(oup)
+
+	SUBQ $128, inl
+	LEAQ 128(inp), inp
+	LEAQ 128(oup), oup
+	JMP  openSSETail64DecLoop
+
+// ----------------------------------------------------------------------------
+// Special optimization for the last 256 bytes of ciphertext
+openSSETail256:
+	// Need to decrypt up to 256 bytes - prepare four blocks
+	MOVO ·chacha20Constants<>(SB), A0; MOVO state1Store, B0; MOVO state2Store, C0; MOVO ctr3Store, D0; PADDL ·sseIncMask<>(SB), D0
+	MOVO A0, A1; MOVO B0, B1; MOVO C0, C1; MOVO D0, D1; PADDL ·sseIncMask<>(SB), D1
+	MOVO A1, A2; MOVO B1, B2; MOVO C1, C2; MOVO D1, D2; PADDL ·sseIncMask<>(SB), D2
+	MOVO A2, A3; MOVO B2, B3; MOVO C2, C3; MOVO D2, D3; PADDL ·sseIncMask<>(SB), D3
+
+	// Store counters
+	MOVO D0, ctr0Store; MOVO D1, ctr1Store; MOVO D2, ctr2Store; MOVO D3, ctr3Store
+	XORQ itr2, itr2
+
+openSSETail256Loop:
+	// This loop inteleaves 8 ChaCha quarter rounds with 1 poly multiplication
+	polyAdd(0(inp)(itr2*1))
+	MOVO          C3, tmpStore
+	chachaQR(A0, B0, C0, D0, C3); chachaQR(A1, B1, C1, D1, C3); chachaQR(A2, B2, C2, D2, C3)
+	MOVO          tmpStore, C3
+	MOVO          C1, tmpStore
+	chachaQR(A3, B3, C3, D3, C1)
+	MOVO          tmpStore, C1
+	shiftB0Left;  shiftB1Left; shiftB2Left; shiftB3Left
+	shiftC0Left;  shiftC1Left; shiftC2Left; shiftC3Left
+	shiftD0Left;  shiftD1Left; shiftD2Left; shiftD3Left
+	polyMulStage1
+	polyMulStage2
+	MOVO          C3, tmpStore
+	chachaQR(A0, B0, C0, D0, C3); chachaQR(A1, B1, C1, D1, C3); chachaQR(A2, B2, C2, D2, C3)
+	MOVO          tmpStore, C3
+	MOVO          C1, tmpStore
+	chachaQR(A3, B3, C3, D3, C1)
+	MOVO          tmpStore, C1
+	polyMulStage3
+	polyMulReduceStage
+	shiftB0Right; shiftB1Right; shiftB2Right; shiftB3Right
+	shiftC0Right; shiftC1Right; shiftC2Right; shiftC3Right
+	shiftD0Right; shiftD1Right; shiftD2Right; shiftD3Right
+	ADDQ          $2*8, itr2
+	CMPQ          itr2, $160
+	JB            openSSETail256Loop
+	MOVQ          inl, itr1
+	ANDQ          $-16, itr1
+
+openSSETail256HashLoop:
+	polyAdd(0(inp)(itr2*1))
+	polyMul
+	ADDQ $2*8, itr2
+	CMPQ itr2, itr1
+	JB   openSSETail256HashLoop
+
+	// Add in the state
+	PADDD ·chacha20Constants<>(SB), A0; PADDD ·chacha20Constants<>(SB), A1; PADDD ·chacha20Constants<>(SB), A2; PADDD ·chacha20Constants<>(SB), A3
+	PADDD state1Store, B0; PADDD state1Store, B1; PADDD state1Store, B2; PADDD state1Store, B3
+	PADDD state2Store, C0; PADDD state2Store, C1; PADDD state2Store, C2; PADDD state2Store, C3
+	PADDD ctr0Store, D0; PADDD ctr1Store, D1; PADDD ctr2Store, D2; PADDD ctr3Store, D3
+	MOVO  D3, tmpStore
+
+	// Load - xor - store
+	MOVOU (0*16)(inp), D3; PXOR D3, A0
+	MOVOU (1*16)(inp), D3; PXOR D3, B0
+	MOVOU (2*16)(inp), D3; PXOR D3, C0
+	MOVOU (3*16)(inp), D3; PXOR D3, D0
+	MOVOU A0, (0*16)(oup)
+	MOVOU B0, (1*16)(oup)
+	MOVOU C0, (2*16)(oup)
+	MOVOU D0, (3*16)(oup)
+	MOVOU (4*16)(inp), A0; MOVOU (5*16)(inp), B0; MOVOU (6*16)(inp), C0; MOVOU (7*16)(inp), D0
+	PXOR  A0, A1; PXOR B0, B1; PXOR C0, C1; PXOR D0, D1
+	MOVOU A1, (4*16)(oup); MOVOU B1, (5*16)(oup); MOVOU C1, (6*16)(oup); MOVOU D1, (7*16)(oup)
+	MOVOU (8*16)(inp), A0; MOVOU (9*16)(inp), B0; MOVOU (10*16)(inp), C0; MOVOU (11*16)(inp), D0
+	PXOR  A0, A2; PXOR B0, B2; PXOR C0, C2; PXOR D0, D2
+	MOVOU A2, (8*16)(oup); MOVOU B2, (9*16)(oup); MOVOU C2, (10*16)(oup); MOVOU D2, (11*16)(oup)
+	LEAQ  192(inp), inp
+	LEAQ  192(oup), oup
+	SUBQ  $192, inl
+	MOVO  A3, A0
+	MOVO  B3, B0
+	MOVO  C3, C0
+	MOVO  tmpStore, D0
+
+	JMP openSSETail64DecLoop
+
+// ----------------------------------------------------------------------------
+// ------------------------- AVX2 Code ----------------------------------------
+chacha20Poly1305Open_AVX2:
+	VZEROUPPER
+	VMOVDQU ·chacha20Constants<>(SB), AA0
+	BYTE    $0xc4; BYTE $0x42; BYTE $0x7d; BYTE $0x5a; BYTE $0x70; BYTE $0x10 // broadcasti128 16(r8), ymm14
+	BYTE    $0xc4; BYTE $0x42; BYTE $0x7d; BYTE $0x5a; BYTE $0x60; BYTE $0x20 // broadcasti128 32(r8), ymm12
+	BYTE    $0xc4; BYTE $0xc2; BYTE $0x7d; BYTE $0x5a; BYTE $0x60; BYTE $0x30 // broadcasti128 48(r8), ymm4
+	VPADDD  ·avx2InitMask<>(SB), DD0, DD0
+
+	// Special optimization, for very short buffers
+	CMPQ inl, $192
+	JBE  openAVX2192
+	CMPQ inl, $320
+	JBE  openAVX2320
+
+	// For the general key prepare the key first - as a byproduct we have 64 bytes of cipher stream
+	VMOVDQA BB0, state1StoreAVX2
+	VMOVDQA CC0, state2StoreAVX2
+	VMOVDQA DD0, ctr3StoreAVX2
+	MOVQ    $10, itr2
+
+openAVX2PreparePolyKey:
+	chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0)
+	VPALIGNR $4, BB0, BB0, BB0; VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $12, DD0, DD0, DD0
+	chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0)
+	VPALIGNR $12, BB0, BB0, BB0; VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $4, DD0, DD0, DD0
+	DECQ     itr2
+	JNE      openAVX2PreparePolyKey
+
+	VPADDD ·chacha20Constants<>(SB), AA0, AA0
+	VPADDD state1StoreAVX2, BB0, BB0
+	VPADDD state2StoreAVX2, CC0, CC0
+	VPADDD ctr3StoreAVX2, DD0, DD0
+
+	VPERM2I128 $0x02, AA0, BB0, TT0
+
+	// Clamp and store poly key
+	VPAND   ·polyClampMask<>(SB), TT0, TT0
+	VMOVDQA TT0, rsStoreAVX2
+
+	// Stream for the first 64 bytes
+	VPERM2I128 $0x13, AA0, BB0, AA0
+	VPERM2I128 $0x13, CC0, DD0, BB0
+
+	// Hash AD + first 64 bytes
+	MOVQ ad_len+80(FP), itr2
+	CALL polyHashADInternal<>(SB)
+	XORQ itr1, itr1
+
+openAVX2InitialHash64:
+	polyAdd(0(inp)(itr1*1))
+	polyMulAVX2
+	ADDQ $16, itr1
+	CMPQ itr1, $64
+	JNE  openAVX2InitialHash64
+
+	// Decrypt the first 64 bytes
+	VPXOR   (0*32)(inp), AA0, AA0
+	VPXOR   (1*32)(inp), BB0, BB0
+	VMOVDQU AA0, (0*32)(oup)
+	VMOVDQU BB0, (1*32)(oup)
+	LEAQ    (2*32)(inp), inp
+	LEAQ    (2*32)(oup), oup
+	SUBQ    $64, inl
+
+openAVX2MainLoop:
+	CMPQ inl, $512
+	JB   openAVX2MainLoopDone
+
+	// Load state, increment counter blocks, store the incremented counters
+	VMOVDQU ·chacha20Constants<>(SB), AA0; VMOVDQA AA0, AA1; VMOVDQA AA0, AA2; VMOVDQA AA0, AA3
+	VMOVDQA state1StoreAVX2, BB0; VMOVDQA BB0, BB1; VMOVDQA BB0, BB2; VMOVDQA BB0, BB3
+	VMOVDQA state2StoreAVX2, CC0; VMOVDQA CC0, CC1; VMOVDQA CC0, CC2; VMOVDQA CC0, CC3
+	VMOVDQA ctr3StoreAVX2, DD0; VPADDD ·avx2IncMask<>(SB), DD0, DD0; VPADDD ·avx2IncMask<>(SB), DD0, DD1; VPADDD ·avx2IncMask<>(SB), DD1, DD2; VPADDD ·avx2IncMask<>(SB), DD2, DD3
+	VMOVDQA DD0, ctr0StoreAVX2; VMOVDQA DD1, ctr1StoreAVX2; VMOVDQA DD2, ctr2StoreAVX2; VMOVDQA DD3, ctr3StoreAVX2
+	XORQ    itr1, itr1
+
+openAVX2InternalLoop:
+	// Lets just say this spaghetti loop interleaves 2 quarter rounds with 3 poly multiplications
+	// Effectively per 512 bytes of stream we hash 480 bytes of ciphertext
+	polyAdd(0*8(inp)(itr1*1))
+	VPADDD   BB0, AA0, AA0; VPADDD BB1, AA1, AA1; VPADDD BB2, AA2, AA2; VPADDD BB3, AA3, AA3
+	polyMulStage1_AVX2
+	VPXOR    AA0, DD0, DD0; VPXOR AA1, DD1, DD1; VPXOR AA2, DD2, DD2; VPXOR AA3, DD3, DD3
+	VPSHUFB  ·rol16<>(SB), DD0, DD0; VPSHUFB ·rol16<>(SB), DD1, DD1; VPSHUFB ·rol16<>(SB), DD2, DD2; VPSHUFB ·rol16<>(SB), DD3, DD3
+	polyMulStage2_AVX2
+	VPADDD   DD0, CC0, CC0; VPADDD DD1, CC1, CC1; VPADDD DD2, CC2, CC2; VPADDD DD3, CC3, CC3
+	VPXOR    CC0, BB0, BB0; VPXOR CC1, BB1, BB1; VPXOR CC2, BB2, BB2; VPXOR CC3, BB3, BB3
+	polyMulStage3_AVX2
+	VMOVDQA  CC3, tmpStoreAVX2
+	VPSLLD   $12, BB0, CC3; VPSRLD $20, BB0, BB0; VPXOR CC3, BB0, BB0
+	VPSLLD   $12, BB1, CC3; VPSRLD $20, BB1, BB1; VPXOR CC3, BB1, BB1
+	VPSLLD   $12, BB2, CC3; VPSRLD $20, BB2, BB2; VPXOR CC3, BB2, BB2
+	VPSLLD   $12, BB3, CC3; VPSRLD $20, BB3, BB3; VPXOR CC3, BB3, BB3
+	VMOVDQA  tmpStoreAVX2, CC3
+	polyMulReduceStage
+	VPADDD   BB0, AA0, AA0; VPADDD BB1, AA1, AA1; VPADDD BB2, AA2, AA2; VPADDD BB3, AA3, AA3
+	VPXOR    AA0, DD0, DD0; VPXOR AA1, DD1, DD1; VPXOR AA2, DD2, DD2; VPXOR AA3, DD3, DD3
+	VPSHUFB  ·rol8<>(SB), DD0, DD0; VPSHUFB ·rol8<>(SB), DD1, DD1; VPSHUFB ·rol8<>(SB), DD2, DD2; VPSHUFB ·rol8<>(SB), DD3, DD3
+	polyAdd(2*8(inp)(itr1*1))
+	VPADDD   DD0, CC0, CC0; VPADDD DD1, CC1, CC1; VPADDD DD2, CC2, CC2; VPADDD DD3, CC3, CC3
+	polyMulStage1_AVX2
+	VPXOR    CC0, BB0, BB0; VPXOR CC1, BB1, BB1; VPXOR CC2, BB2, BB2; VPXOR CC3, BB3, BB3
+	VMOVDQA  CC3, tmpStoreAVX2
+	VPSLLD   $7, BB0, CC3; VPSRLD $25, BB0, BB0; VPXOR CC3, BB0, BB0
+	VPSLLD   $7, BB1, CC3; VPSRLD $25, BB1, BB1; VPXOR CC3, BB1, BB1
+	VPSLLD   $7, BB2, CC3; VPSRLD $25, BB2, BB2; VPXOR CC3, BB2, BB2
+	VPSLLD   $7, BB3, CC3; VPSRLD $25, BB3, BB3; VPXOR CC3, BB3, BB3
+	VMOVDQA  tmpStoreAVX2, CC3
+	polyMulStage2_AVX2
+	VPALIGNR $4, BB0, BB0, BB0; VPALIGNR $4, BB1, BB1, BB1; VPALIGNR $4, BB2, BB2, BB2; VPALIGNR $4, BB3, BB3, BB3
+	VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $8, CC2, CC2, CC2; VPALIGNR $8, CC3, CC3, CC3
+	VPALIGNR $12, DD0, DD0, DD0; VPALIGNR $12, DD1, DD1, DD1; VPALIGNR $12, DD2, DD2, DD2; VPALIGNR $12, DD3, DD3, DD3
+	VPADDD   BB0, AA0, AA0; VPADDD BB1, AA1, AA1; VPADDD BB2, AA2, AA2; VPADDD BB3, AA3, AA3
+	polyMulStage3_AVX2
+	VPXOR    AA0, DD0, DD0; VPXOR AA1, DD1, DD1; VPXOR AA2, DD2, DD2; VPXOR AA3, DD3, DD3
+	VPSHUFB  ·rol16<>(SB), DD0, DD0; VPSHUFB ·rol16<>(SB), DD1, DD1; VPSHUFB ·rol16<>(SB), DD2, DD2; VPSHUFB ·rol16<>(SB), DD3, DD3
+	polyMulReduceStage
+	VPADDD   DD0, CC0, CC0; VPADDD DD1, CC1, CC1; VPADDD DD2, CC2, CC2; VPADDD DD3, CC3, CC3
+	VPXOR    CC0, BB0, BB0; VPXOR CC1, BB1, BB1; VPXOR CC2, BB2, BB2; VPXOR CC3, BB3, BB3
+	polyAdd(4*8(inp)(itr1*1))
+	LEAQ     (6*8)(itr1), itr1
+	VMOVDQA  CC3, tmpStoreAVX2
+	VPSLLD   $12, BB0, CC3; VPSRLD $20, BB0, BB0; VPXOR CC3, BB0, BB0
+	VPSLLD   $12, BB1, CC3; VPSRLD $20, BB1, BB1; VPXOR CC3, BB1, BB1
+	VPSLLD   $12, BB2, CC3; VPSRLD $20, BB2, BB2; VPXOR CC3, BB2, BB2
+	VPSLLD   $12, BB3, CC3; VPSRLD $20, BB3, BB3; VPXOR CC3, BB3, BB3
+	VMOVDQA  tmpStoreAVX2, CC3
+	polyMulStage1_AVX2
+	VPADDD   BB0, AA0, AA0; VPADDD BB1, AA1, AA1; VPADDD BB2, AA2, AA2; VPADDD BB3, AA3, AA3
+	VPXOR    AA0, DD0, DD0; VPXOR AA1, DD1, DD1; VPXOR AA2, DD2, DD2; VPXOR AA3, DD3, DD3
+	polyMulStage2_AVX2
+	VPSHUFB  ·rol8<>(SB), DD0, DD0; VPSHUFB ·rol8<>(SB), DD1, DD1; VPSHUFB ·rol8<>(SB), DD2, DD2; VPSHUFB ·rol8<>(SB), DD3, DD3
+	VPADDD   DD0, CC0, CC0; VPADDD DD1, CC1, CC1; VPADDD DD2, CC2, CC2; VPADDD DD3, CC3, CC3
+	polyMulStage3_AVX2
+	VPXOR    CC0, BB0, BB0; VPXOR CC1, BB1, BB1; VPXOR CC2, BB2, BB2; VPXOR CC3, BB3, BB3
+	VMOVDQA  CC3, tmpStoreAVX2
+	VPSLLD   $7, BB0, CC3; VPSRLD $25, BB0, BB0; VPXOR CC3, BB0, BB0
+	VPSLLD   $7, BB1, CC3; VPSRLD $25, BB1, BB1; VPXOR CC3, BB1, BB1
+	VPSLLD   $7, BB2, CC3; VPSRLD $25, BB2, BB2; VPXOR CC3, BB2, BB2
+	VPSLLD   $7, BB3, CC3; VPSRLD $25, BB3, BB3; VPXOR CC3, BB3, BB3
+	VMOVDQA  tmpStoreAVX2, CC3
+	polyMulReduceStage
+	VPALIGNR $12, BB0, BB0, BB0; VPALIGNR $12, BB1, BB1, BB1; VPALIGNR $12, BB2, BB2, BB2; VPALIGNR $12, BB3, BB3, BB3
+	VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $8, CC2, CC2, CC2; VPALIGNR $8, CC3, CC3, CC3
+	VPALIGNR $4, DD0, DD0, DD0; VPALIGNR $4, DD1, DD1, DD1; VPALIGNR $4, DD2, DD2, DD2; VPALIGNR $4, DD3, DD3, DD3
+	CMPQ     itr1, $480
+	JNE      openAVX2InternalLoop
+
+	VPADDD  ·chacha20Constants<>(SB), AA0, AA0; VPADDD ·chacha20Constants<>(SB), AA1, AA1; VPADDD ·chacha20Constants<>(SB), AA2, AA2; VPADDD ·chacha20Constants<>(SB), AA3, AA3
+	VPADDD  state1StoreAVX2, BB0, BB0; VPADDD state1StoreAVX2, BB1, BB1; VPADDD state1StoreAVX2, BB2, BB2; VPADDD state1StoreAVX2, BB3, BB3
+	VPADDD  state2StoreAVX2, CC0, CC0; VPADDD state2StoreAVX2, CC1, CC1; VPADDD state2StoreAVX2, CC2, CC2; VPADDD state2StoreAVX2, CC3, CC3
+	VPADDD  ctr0StoreAVX2, DD0, DD0; VPADDD ctr1StoreAVX2, DD1, DD1; VPADDD ctr2StoreAVX2, DD2, DD2; VPADDD ctr3StoreAVX2, DD3, DD3
+	VMOVDQA CC3, tmpStoreAVX2
+
+	// We only hashed 480 of the 512 bytes available - hash the remaining 32 here
+	polyAdd(480(inp))
+	polyMulAVX2
+	VPERM2I128 $0x02, AA0, BB0, CC3; VPERM2I128 $0x13, AA0, BB0, BB0; VPERM2I128 $0x02, CC0, DD0, AA0; VPERM2I128 $0x13, CC0, DD0, CC0
+	VPXOR      (0*32)(inp), CC3, CC3; VPXOR (1*32)(inp), AA0, AA0; VPXOR (2*32)(inp), BB0, BB0; VPXOR (3*32)(inp), CC0, CC0
+	VMOVDQU    CC3, (0*32)(oup); VMOVDQU AA0, (1*32)(oup); VMOVDQU BB0, (2*32)(oup); VMOVDQU CC0, (3*32)(oup)
+	VPERM2I128 $0x02, AA1, BB1, AA0; VPERM2I128 $0x02, CC1, DD1, BB0; VPERM2I128 $0x13, AA1, BB1, CC0; VPERM2I128 $0x13, CC1, DD1, DD0
+	VPXOR      (4*32)(inp), AA0, AA0; VPXOR (5*32)(inp), BB0, BB0; VPXOR (6*32)(inp), CC0, CC0; VPXOR (7*32)(inp), DD0, DD0
+	VMOVDQU    AA0, (4*32)(oup); VMOVDQU BB0, (5*32)(oup); VMOVDQU CC0, (6*32)(oup); VMOVDQU DD0, (7*32)(oup)
+
+	// and here
+	polyAdd(496(inp))
+	polyMulAVX2
+	VPERM2I128 $0x02, AA2, BB2, AA0; VPERM2I128 $0x02, CC2, DD2, BB0; VPERM2I128 $0x13, AA2, BB2, CC0; VPERM2I128 $0x13, CC2, DD2, DD0
+	VPXOR      (8*32)(inp), AA0, AA0; VPXOR (9*32)(inp), BB0, BB0; VPXOR (10*32)(inp), CC0, CC0; VPXOR (11*32)(inp), DD0, DD0
+	VMOVDQU    AA0, (8*32)(oup); VMOVDQU BB0, (9*32)(oup); VMOVDQU CC0, (10*32)(oup); VMOVDQU DD0, (11*32)(oup)
+	VPERM2I128 $0x02, AA3, BB3, AA0; VPERM2I128 $0x02, tmpStoreAVX2, DD3, BB0; VPERM2I128 $0x13, AA3, BB3, CC0; VPERM2I128 $0x13, tmpStoreAVX2, DD3, DD0
+	VPXOR      (12*32)(inp), AA0, AA0; VPXOR (13*32)(inp), BB0, BB0; VPXOR (14*32)(inp), CC0, CC0; VPXOR (15*32)(inp), DD0, DD0
+	VMOVDQU    AA0, (12*32)(oup); VMOVDQU BB0, (13*32)(oup); VMOVDQU CC0, (14*32)(oup); VMOVDQU DD0, (15*32)(oup)
+	LEAQ       (32*16)(inp), inp
+	LEAQ       (32*16)(oup), oup
+	SUBQ       $(32*16), inl
+	JMP        openAVX2MainLoop
+
+openAVX2MainLoopDone:
+	// Handle the various tail sizes efficiently
+	TESTQ inl, inl
+	JE    openSSEFinalize
+	CMPQ  inl, $128
+	JBE   openAVX2Tail128
+	CMPQ  inl, $256
+	JBE   openAVX2Tail256
+	CMPQ  inl, $384
+	JBE   openAVX2Tail384
+	JMP   openAVX2Tail512
+
+// ----------------------------------------------------------------------------
+// Special optimization for buffers smaller than 193 bytes
+openAVX2192:
+	// For up to 192 bytes of ciphertext and 64 bytes for the poly key, we process four blocks
+	VMOVDQA AA0, AA1
+	VMOVDQA BB0, BB1
+	VMOVDQA CC0, CC1
+	VPADDD  ·avx2IncMask<>(SB), DD0, DD1
+	VMOVDQA AA0, AA2
+	VMOVDQA BB0, BB2
+	VMOVDQA CC0, CC2
+	VMOVDQA DD0, DD2
+	VMOVDQA DD1, TT3
+	MOVQ    $10, itr2
+
+openAVX2192InnerCipherLoop:
+	chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0); chachaQR_AVX2(AA1, BB1, CC1, DD1, TT0)
+	VPALIGNR   $4, BB0, BB0, BB0; VPALIGNR $4, BB1, BB1, BB1
+	VPALIGNR   $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1
+	VPALIGNR   $12, DD0, DD0, DD0; VPALIGNR $12, DD1, DD1, DD1
+	chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0); chachaQR_AVX2(AA1, BB1, CC1, DD1, TT0)
+	VPALIGNR   $12, BB0, BB0, BB0; VPALIGNR $12, BB1, BB1, BB1
+	VPALIGNR   $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1
+	VPALIGNR   $4, DD0, DD0, DD0; VPALIGNR $4, DD1, DD1, DD1
+	DECQ       itr2
+	JNE        openAVX2192InnerCipherLoop
+	VPADDD     AA2, AA0, AA0; VPADDD AA2, AA1, AA1
+	VPADDD     BB2, BB0, BB0; VPADDD BB2, BB1, BB1
+	VPADDD     CC2, CC0, CC0; VPADDD CC2, CC1, CC1
+	VPADDD     DD2, DD0, DD0; VPADDD TT3, DD1, DD1
+	VPERM2I128 $0x02, AA0, BB0, TT0
+
+	// Clamp and store poly key
+	VPAND   ·polyClampMask<>(SB), TT0, TT0
+	VMOVDQA TT0, rsStoreAVX2
+
+	// Stream for up to 192 bytes
+	VPERM2I128 $0x13, AA0, BB0, AA0
+	VPERM2I128 $0x13, CC0, DD0, BB0
+	VPERM2I128 $0x02, AA1, BB1, CC0
+	VPERM2I128 $0x02, CC1, DD1, DD0
+	VPERM2I128 $0x13, AA1, BB1, AA1
+	VPERM2I128 $0x13, CC1, DD1, BB1
+
+openAVX2ShortOpen:
+	// Hash
+	MOVQ ad_len+80(FP), itr2
+	CALL polyHashADInternal<>(SB)
+
+openAVX2ShortOpenLoop:
+	CMPQ inl, $32
+	JB   openAVX2ShortTail32
+	SUBQ $32, inl
+
+	// Load for hashing
+	polyAdd(0*8(inp))
+	polyMulAVX2
+	polyAdd(2*8(inp))
+	polyMulAVX2
+
+	// Load for decryption
+	VPXOR   (inp), AA0, AA0
+	VMOVDQU AA0, (oup)
+	LEAQ    (1*32)(inp), inp
+	LEAQ    (1*32)(oup), oup
+
+	// Shift stream left
+	VMOVDQA BB0, AA0
+	VMOVDQA CC0, BB0
+	VMOVDQA DD0, CC0
+	VMOVDQA AA1, DD0
+	VMOVDQA BB1, AA1
+	VMOVDQA CC1, BB1
+	VMOVDQA DD1, CC1
+	VMOVDQA AA2, DD1
+	VMOVDQA BB2, AA2
+	JMP     openAVX2ShortOpenLoop
+
+openAVX2ShortTail32:
+	CMPQ    inl, $16
+	VMOVDQA A0, A1
+	JB      openAVX2ShortDone
+
+	SUBQ $16, inl
+
+	// Load for hashing
+	polyAdd(0*8(inp))
+	polyMulAVX2
+
+	// Load for decryption
+	VPXOR      (inp), A0, T0
+	VMOVDQU    T0, (oup)
+	LEAQ       (1*16)(inp), inp
+	LEAQ       (1*16)(oup), oup
+	VPERM2I128 $0x11, AA0, AA0, AA0
+	VMOVDQA    A0, A1
+
+openAVX2ShortDone:
+	VZEROUPPER
+	JMP openSSETail16
+
+// ----------------------------------------------------------------------------
+// Special optimization for buffers smaller than 321 bytes
+openAVX2320:
+	// For up to 320 bytes of ciphertext and 64 bytes for the poly key, we process six blocks
+	VMOVDQA AA0, AA1; VMOVDQA BB0, BB1; VMOVDQA CC0, CC1; VPADDD ·avx2IncMask<>(SB), DD0, DD1
+	VMOVDQA AA0, AA2; VMOVDQA BB0, BB2; VMOVDQA CC0, CC2; VPADDD ·avx2IncMask<>(SB), DD1, DD2
+	VMOVDQA BB0, TT1; VMOVDQA CC0, TT2; VMOVDQA DD0, TT3
+	MOVQ    $10, itr2
+
+openAVX2320InnerCipherLoop:
+	chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0); chachaQR_AVX2(AA1, BB1, CC1, DD1, TT0); chachaQR_AVX2(AA2, BB2, CC2, DD2, TT0)
+	VPALIGNR $4, BB0, BB0, BB0; VPALIGNR $4, BB1, BB1, BB1; VPALIGNR $4, BB2, BB2, BB2
+	VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $8, CC2, CC2, CC2
+	VPALIGNR $12, DD0, DD0, DD0; VPALIGNR $12, DD1, DD1, DD1; VPALIGNR $12, DD2, DD2, DD2
+	chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0); chachaQR_AVX2(AA1, BB1, CC1, DD1, TT0); chachaQR_AVX2(AA2, BB2, CC2, DD2, TT0)
+	VPALIGNR $12, BB0, BB0, BB0; VPALIGNR $12, BB1, BB1, BB1; VPALIGNR $12, BB2, BB2, BB2
+	VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $8, CC2, CC2, CC2
+	VPALIGNR $4, DD0, DD0, DD0; VPALIGNR $4, DD1, DD1, DD1; VPALIGNR $4, DD2, DD2, DD2
+	DECQ     itr2
+	JNE      openAVX2320InnerCipherLoop
+
+	VMOVDQA ·chacha20Constants<>(SB), TT0
+	VPADDD  TT0, AA0, AA0; VPADDD TT0, AA1, AA1; VPADDD TT0, AA2, AA2
+	VPADDD  TT1, BB0, BB0; VPADDD TT1, BB1, BB1; VPADDD TT1, BB2, BB2
+	VPADDD  TT2, CC0, CC0; VPADDD TT2, CC1, CC1; VPADDD TT2, CC2, CC2
+	VMOVDQA ·avx2IncMask<>(SB), TT0
+	VPADDD  TT3, DD0, DD0; VPADDD TT0, TT3, TT3
+	VPADDD  TT3, DD1, DD1; VPADDD TT0, TT3, TT3
+	VPADDD  TT3, DD2, DD2
+
+	// Clamp and store poly key
+	VPERM2I128 $0x02, AA0, BB0, TT0
+	VPAND      ·polyClampMask<>(SB), TT0, TT0
+	VMOVDQA    TT0, rsStoreAVX2
+
+	// Stream for up to 320 bytes
+	VPERM2I128 $0x13, AA0, BB0, AA0
+	VPERM2I128 $0x13, CC0, DD0, BB0
+	VPERM2I128 $0x02, AA1, BB1, CC0
+	VPERM2I128 $0x02, CC1, DD1, DD0
+	VPERM2I128 $0x13, AA1, BB1, AA1
+	VPERM2I128 $0x13, CC1, DD1, BB1
+	VPERM2I128 $0x02, AA2, BB2, CC1
+	VPERM2I128 $0x02, CC2, DD2, DD1
+	VPERM2I128 $0x13, AA2, BB2, AA2
+	VPERM2I128 $0x13, CC2, DD2, BB2
+	JMP        openAVX2ShortOpen
+
+// ----------------------------------------------------------------------------
+// Special optimization for the last 128 bytes of ciphertext
+openAVX2Tail128:
+	// Need to decrypt up to 128 bytes - prepare two blocks
+	VMOVDQA ·chacha20Constants<>(SB), AA1
+	VMOVDQA state1StoreAVX2, BB1
+	VMOVDQA state2StoreAVX2, CC1
+	VMOVDQA ctr3StoreAVX2, DD1
+	VPADDD  ·avx2IncMask<>(SB), DD1, DD1
+	VMOVDQA DD1, DD0
+
+	XORQ  itr2, itr2
+	MOVQ  inl, itr1
+	ANDQ  $-16, itr1
+	TESTQ itr1, itr1
+	JE    openAVX2Tail128LoopB
+
+openAVX2Tail128LoopA:
+	// Perform ChaCha rounds, while hashing the remaining input
+	polyAdd(0(inp)(itr2*1))
+	polyMulAVX2
+
+openAVX2Tail128LoopB:
+	ADDQ     $16, itr2
+	chachaQR_AVX2(AA1, BB1, CC1, DD1, TT0)
+	VPALIGNR $4, BB1, BB1, BB1
+	VPALIGNR $8, CC1, CC1, CC1
+	VPALIGNR $12, DD1, DD1, DD1
+	chachaQR_AVX2(AA1, BB1, CC1, DD1, TT0)
+	VPALIGNR $12, BB1, BB1, BB1
+	VPALIGNR $8, CC1, CC1, CC1
+	VPALIGNR $4, DD1, DD1, DD1
+	CMPQ     itr2, itr1
+	JB       openAVX2Tail128LoopA
+	CMPQ     itr2, $160
+	JNE      openAVX2Tail128LoopB
+
+	VPADDD     ·chacha20Constants<>(SB), AA1, AA1
+	VPADDD     state1StoreAVX2, BB1, BB1
+	VPADDD     state2StoreAVX2, CC1, CC1
+	VPADDD     DD0, DD1, DD1
+	VPERM2I128 $0x02, AA1, BB1, AA0; VPERM2I128 $0x02, CC1, DD1, BB0; VPERM2I128 $0x13, AA1, BB1, CC0; VPERM2I128 $0x13, CC1, DD1, DD0
+
+openAVX2TailLoop:
+	CMPQ inl, $32
+	JB   openAVX2Tail
+	SUBQ $32, inl
+
+	// Load for decryption
+	VPXOR   (inp), AA0, AA0
+	VMOVDQU AA0, (oup)
+	LEAQ    (1*32)(inp), inp
+	LEAQ    (1*32)(oup), oup
+	VMOVDQA BB0, AA0
+	VMOVDQA CC0, BB0
+	VMOVDQA DD0, CC0
+	JMP     openAVX2TailLoop
+
+openAVX2Tail:
+	CMPQ    inl, $16
+	VMOVDQA A0, A1
+	JB      openAVX2TailDone
+	SUBQ    $16, inl
+
+	// Load for decryption
+	VPXOR      (inp), A0, T0
+	VMOVDQU    T0, (oup)
+	LEAQ       (1*16)(inp), inp
+	LEAQ       (1*16)(oup), oup
+	VPERM2I128 $0x11, AA0, AA0, AA0
+	VMOVDQA    A0, A1
+
+openAVX2TailDone:
+	VZEROUPPER
+	JMP openSSETail16
+
+// ----------------------------------------------------------------------------
+// Special optimization for the last 256 bytes of ciphertext
+openAVX2Tail256:
+	// Need to decrypt up to 256 bytes - prepare four blocks
+	VMOVDQA ·chacha20Constants<>(SB), AA0; VMOVDQA AA0, AA1
+	VMOVDQA state1StoreAVX2, BB0; VMOVDQA BB0, BB1
+	VMOVDQA state2StoreAVX2, CC0; VMOVDQA CC0, CC1
+	VMOVDQA ctr3StoreAVX2, DD0
+	VPADDD  ·avx2IncMask<>(SB), DD0, DD0
+	VPADDD  ·avx2IncMask<>(SB), DD0, DD1
+	VMOVDQA DD0, TT1
+	VMOVDQA DD1, TT2
+
+	// Compute the number of iterations that will hash data
+	MOVQ    inl, tmpStoreAVX2
+	MOVQ    inl, itr1
+	SUBQ    $128, itr1
+	SHRQ    $4, itr1
+	MOVQ    $10, itr2
+	CMPQ    itr1, $10
+	CMOVQGT itr2, itr1
+	MOVQ    inp, inl
+	XORQ    itr2, itr2
+
+openAVX2Tail256LoopA:
+	polyAdd(0(inl))
+	polyMulAVX2
+	LEAQ 16(inl), inl
+
+	// Perform ChaCha rounds, while hashing the remaining input
+openAVX2Tail256LoopB:
+	chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0); chachaQR_AVX2(AA1, BB1, CC1, DD1, TT0)
+	VPALIGNR $4, BB0, BB0, BB0; VPALIGNR $4, BB1, BB1, BB1
+	VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1
+	VPALIGNR $12, DD0, DD0, DD0; VPALIGNR $12, DD1, DD1, DD1
+	INCQ     itr2
+	chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0); chachaQR_AVX2(AA1, BB1, CC1, DD1, TT0)
+	VPALIGNR $12, BB0, BB0, BB0; VPALIGNR $12, BB1, BB1, BB1
+	VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1
+	VPALIGNR $4, DD0, DD0, DD0; VPALIGNR $4, DD1, DD1, DD1
+	CMPQ     itr2, itr1
+	JB       openAVX2Tail256LoopA
+
+	CMPQ itr2, $10
+	JNE  openAVX2Tail256LoopB
+
+	MOVQ inl, itr2
+	SUBQ inp, inl
+	MOVQ inl, itr1
+	MOVQ tmpStoreAVX2, inl
+
+	// Hash the remainder of data (if any)
+openAVX2Tail256Hash:
+	ADDQ $16, itr1
+	CMPQ itr1, inl
+	JGT  openAVX2Tail256HashEnd
+	polyAdd (0(itr2))
+	polyMulAVX2
+	LEAQ 16(itr2), itr2
+	JMP  openAVX2Tail256Hash
+
+// Store 128 bytes safely, then go to store loop
+openAVX2Tail256HashEnd:
+	VPADDD     ·chacha20Constants<>(SB), AA0, AA0; VPADDD ·chacha20Constants<>(SB), AA1, AA1
+	VPADDD     state1StoreAVX2, BB0, BB0; VPADDD state1StoreAVX2, BB1, BB1
+	VPADDD     state2StoreAVX2, CC0, CC0; VPADDD state2StoreAVX2, CC1, CC1
+	VPADDD     TT1, DD0, DD0; VPADDD TT2, DD1, DD1
+	VPERM2I128 $0x02, AA0, BB0, AA2; VPERM2I128 $0x02, CC0, DD0, BB2; VPERM2I128 $0x13, AA0, BB0, CC2; VPERM2I128 $0x13, CC0, DD0, DD2
+	VPERM2I128 $0x02, AA1, BB1, AA0; VPERM2I128 $0x02, CC1, DD1, BB0; VPERM2I128 $0x13, AA1, BB1, CC0; VPERM2I128 $0x13, CC1, DD1, DD0
+
+	VPXOR   (0*32)(inp), AA2, AA2; VPXOR (1*32)(inp), BB2, BB2; VPXOR (2*32)(inp), CC2, CC2; VPXOR (3*32)(inp), DD2, DD2
+	VMOVDQU AA2, (0*32)(oup); VMOVDQU BB2, (1*32)(oup); VMOVDQU CC2, (2*32)(oup); VMOVDQU DD2, (3*32)(oup)
+	LEAQ    (4*32)(inp), inp
+	LEAQ    (4*32)(oup), oup
+	SUBQ    $4*32, inl
+
+	JMP openAVX2TailLoop
+
+// ----------------------------------------------------------------------------
+// Special optimization for the last 384 bytes of ciphertext
+openAVX2Tail384:
+	// Need to decrypt up to 384 bytes - prepare six blocks
+	VMOVDQA ·chacha20Constants<>(SB), AA0; VMOVDQA AA0, AA1; VMOVDQA AA0, AA2
+	VMOVDQA state1StoreAVX2, BB0; VMOVDQA BB0, BB1; VMOVDQA BB0, BB2
+	VMOVDQA state2StoreAVX2, CC0; VMOVDQA CC0, CC1; VMOVDQA CC0, CC2
+	VMOVDQA ctr3StoreAVX2, DD0
+	VPADDD  ·avx2IncMask<>(SB), DD0, DD0
+	VPADDD  ·avx2IncMask<>(SB), DD0, DD1
+	VPADDD  ·avx2IncMask<>(SB), DD1, DD2
+	VMOVDQA DD0, ctr0StoreAVX2
+	VMOVDQA DD1, ctr1StoreAVX2
+	VMOVDQA DD2, ctr2StoreAVX2
+
+	// Compute the number of iterations that will hash two blocks of data
+	MOVQ    inl, tmpStoreAVX2
+	MOVQ    inl, itr1
+	SUBQ    $256, itr1
+	SHRQ    $4, itr1
+	ADDQ    $6, itr1
+	MOVQ    $10, itr2
+	CMPQ    itr1, $10
+	CMOVQGT itr2, itr1
+	MOVQ    inp, inl
+	XORQ    itr2, itr2
+
+	// Perform ChaCha rounds, while hashing the remaining input
+openAVX2Tail384LoopB:
+	polyAdd(0(inl))
+	polyMulAVX2
+	LEAQ 16(inl), inl
+
+openAVX2Tail384LoopA:
+	chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0); chachaQR_AVX2(AA1, BB1, CC1, DD1, TT0); chachaQR_AVX2(AA2, BB2, CC2, DD2, TT0)
+	VPALIGNR $4, BB0, BB0, BB0; VPALIGNR $4, BB1, BB1, BB1; VPALIGNR $4, BB2, BB2, BB2
+	VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $8, CC2, CC2, CC2
+	VPALIGNR $12, DD0, DD0, DD0; VPALIGNR $12, DD1, DD1, DD1; VPALIGNR $12, DD2, DD2, DD2
+	polyAdd(0(inl))
+	polyMulAVX2
+	LEAQ     16(inl), inl
+	INCQ     itr2
+	chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0); chachaQR_AVX2(AA1, BB1, CC1, DD1, TT0); chachaQR_AVX2(AA2, BB2, CC2, DD2, TT0)
+	VPALIGNR $12, BB0, BB0, BB0; VPALIGNR $12, BB1, BB1, BB1; VPALIGNR $12, BB2, BB2, BB2
+	VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $8, CC2, CC2, CC2
+	VPALIGNR $4, DD0, DD0, DD0; VPALIGNR $4, DD1, DD1, DD1; VPALIGNR $4, DD2, DD2, DD2
+
+	CMPQ itr2, itr1
+	JB   openAVX2Tail384LoopB
+
+	CMPQ itr2, $10
+	JNE  openAVX2Tail384LoopA
+
+	MOVQ inl, itr2
+	SUBQ inp, inl
+	MOVQ inl, itr1
+	MOVQ tmpStoreAVX2, inl
+
+openAVX2Tail384Hash:
+	ADDQ $16, itr1
+	CMPQ itr1, inl
+	JGT  openAVX2Tail384HashEnd
+	polyAdd(0(itr2))
+	polyMulAVX2
+	LEAQ 16(itr2), itr2
+	JMP  openAVX2Tail384Hash
+
+// Store 256 bytes safely, then go to store loop
+openAVX2Tail384HashEnd:
+	VPADDD     ·chacha20Constants<>(SB), AA0, AA0; VPADDD ·chacha20Constants<>(SB), AA1, AA1; VPADDD ·chacha20Constants<>(SB), AA2, AA2
+	VPADDD     state1StoreAVX2, BB0, BB0; VPADDD state1StoreAVX2, BB1, BB1; VPADDD state1StoreAVX2, BB2, BB2
+	VPADDD     state2StoreAVX2, CC0, CC0; VPADDD state2StoreAVX2, CC1, CC1; VPADDD state2StoreAVX2, CC2, CC2
+	VPADDD     ctr0StoreAVX2, DD0, DD0; VPADDD ctr1StoreAVX2, DD1, DD1; VPADDD ctr2StoreAVX2, DD2, DD2
+	VPERM2I128 $0x02, AA0, BB0, TT0; VPERM2I128 $0x02, CC0, DD0, TT1; VPERM2I128 $0x13, AA0, BB0, TT2; VPERM2I128 $0x13, CC0, DD0, TT3
+	VPXOR      (0*32)(inp), TT0, TT0; VPXOR (1*32)(inp), TT1, TT1; VPXOR (2*32)(inp), TT2, TT2; VPXOR (3*32)(inp), TT3, TT3
+	VMOVDQU    TT0, (0*32)(oup); VMOVDQU TT1, (1*32)(oup); VMOVDQU TT2, (2*32)(oup); VMOVDQU TT3, (3*32)(oup)
+	VPERM2I128 $0x02, AA1, BB1, TT0; VPERM2I128 $0x02, CC1, DD1, TT1; VPERM2I128 $0x13, AA1, BB1, TT2; VPERM2I128 $0x13, CC1, DD1, TT3
+	VPXOR      (4*32)(inp), TT0, TT0; VPXOR (5*32)(inp), TT1, TT1; VPXOR (6*32)(inp), TT2, TT2; VPXOR (7*32)(inp), TT3, TT3
+	VMOVDQU    TT0, (4*32)(oup); VMOVDQU TT1, (5*32)(oup); VMOVDQU TT2, (6*32)(oup); VMOVDQU TT3, (7*32)(oup)
+	VPERM2I128 $0x02, AA2, BB2, AA0; VPERM2I128 $0x02, CC2, DD2, BB0; VPERM2I128 $0x13, AA2, BB2, CC0; VPERM2I128 $0x13, CC2, DD2, DD0
+	LEAQ       (8*32)(inp), inp
+	LEAQ       (8*32)(oup), oup
+	SUBQ       $8*32, inl
+	JMP        openAVX2TailLoop
+
+// ----------------------------------------------------------------------------
+// Special optimization for the last 512 bytes of ciphertext
+openAVX2Tail512:
+	VMOVDQU ·chacha20Constants<>(SB), AA0; VMOVDQA AA0, AA1; VMOVDQA AA0, AA2; VMOVDQA AA0, AA3
+	VMOVDQA state1StoreAVX2, BB0; VMOVDQA BB0, BB1; VMOVDQA BB0, BB2; VMOVDQA BB0, BB3
+	VMOVDQA state2StoreAVX2, CC0; VMOVDQA CC0, CC1; VMOVDQA CC0, CC2; VMOVDQA CC0, CC3
+	VMOVDQA ctr3StoreAVX2, DD0; VPADDD ·avx2IncMask<>(SB), DD0, DD0; VPADDD ·avx2IncMask<>(SB), DD0, DD1; VPADDD ·avx2IncMask<>(SB), DD1, DD2; VPADDD ·avx2IncMask<>(SB), DD2, DD3
+	VMOVDQA DD0, ctr0StoreAVX2; VMOVDQA DD1, ctr1StoreAVX2; VMOVDQA DD2, ctr2StoreAVX2; VMOVDQA DD3, ctr3StoreAVX2
+	XORQ    itr1, itr1
+	MOVQ    inp, itr2
+
+openAVX2Tail512LoopB:
+	polyAdd(0(itr2))
+	polyMulAVX2
+	LEAQ (2*8)(itr2), itr2
+
+openAVX2Tail512LoopA:
+	VPADDD   BB0, AA0, AA0; VPADDD BB1, AA1, AA1; VPADDD BB2, AA2, AA2; VPADDD BB3, AA3, AA3
+	VPXOR    AA0, DD0, DD0; VPXOR AA1, DD1, DD1; VPXOR AA2, DD2, DD2; VPXOR AA3, DD3, DD3
+	VPSHUFB  ·rol16<>(SB), DD0, DD0; VPSHUFB ·rol16<>(SB), DD1, DD1; VPSHUFB ·rol16<>(SB), DD2, DD2; VPSHUFB ·rol16<>(SB), DD3, DD3
+	VPADDD   DD0, CC0, CC0; VPADDD DD1, CC1, CC1; VPADDD DD2, CC2, CC2; VPADDD DD3, CC3, CC3
+	VPXOR    CC0, BB0, BB0; VPXOR CC1, BB1, BB1; VPXOR CC2, BB2, BB2; VPXOR CC3, BB3, BB3
+	VMOVDQA  CC3, tmpStoreAVX2
+	VPSLLD   $12, BB0, CC3; VPSRLD $20, BB0, BB0; VPXOR CC3, BB0, BB0
+	VPSLLD   $12, BB1, CC3; VPSRLD $20, BB1, BB1; VPXOR CC3, BB1, BB1
+	VPSLLD   $12, BB2, CC3; VPSRLD $20, BB2, BB2; VPXOR CC3, BB2, BB2
+	VPSLLD   $12, BB3, CC3; VPSRLD $20, BB3, BB3; VPXOR CC3, BB3, BB3
+	VMOVDQA  tmpStoreAVX2, CC3
+	polyAdd(0*8(itr2))
+	polyMulAVX2
+	VPADDD   BB0, AA0, AA0; VPADDD BB1, AA1, AA1; VPADDD BB2, AA2, AA2; VPADDD BB3, AA3, AA3
+	VPXOR    AA0, DD0, DD0; VPXOR AA1, DD1, DD1; VPXOR AA2, DD2, DD2; VPXOR AA3, DD3, DD3
+	VPSHUFB  ·rol8<>(SB), DD0, DD0; VPSHUFB ·rol8<>(SB), DD1, DD1; VPSHUFB ·rol8<>(SB), DD2, DD2; VPSHUFB ·rol8<>(SB), DD3, DD3
+	VPADDD   DD0, CC0, CC0; VPADDD DD1, CC1, CC1; VPADDD DD2, CC2, CC2; VPADDD DD3, CC3, CC3
+	VPXOR    CC0, BB0, BB0; VPXOR CC1, BB1, BB1; VPXOR CC2, BB2, BB2; VPXOR CC3, BB3, BB3
+	VMOVDQA  CC3, tmpStoreAVX2
+	VPSLLD   $7, BB0, CC3; VPSRLD $25, BB0, BB0; VPXOR CC3, BB0, BB0
+	VPSLLD   $7, BB1, CC3; VPSRLD $25, BB1, BB1; VPXOR CC3, BB1, BB1
+	VPSLLD   $7, BB2, CC3; VPSRLD $25, BB2, BB2; VPXOR CC3, BB2, BB2
+	VPSLLD   $7, BB3, CC3; VPSRLD $25, BB3, BB3; VPXOR CC3, BB3, BB3
+	VMOVDQA  tmpStoreAVX2, CC3
+	VPALIGNR $4, BB0, BB0, BB0; VPALIGNR $4, BB1, BB1, BB1; VPALIGNR $4, BB2, BB2, BB2; VPALIGNR $4, BB3, BB3, BB3
+	VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $8, CC2, CC2, CC2; VPALIGNR $8, CC3, CC3, CC3
+	VPALIGNR $12, DD0, DD0, DD0; VPALIGNR $12, DD1, DD1, DD1; VPALIGNR $12, DD2, DD2, DD2; VPALIGNR $12, DD3, DD3, DD3
+	VPADDD   BB0, AA0, AA0; VPADDD BB1, AA1, AA1; VPADDD BB2, AA2, AA2; VPADDD BB3, AA3, AA3
+	VPXOR    AA0, DD0, DD0; VPXOR AA1, DD1, DD1; VPXOR AA2, DD2, DD2; VPXOR AA3, DD3, DD3
+	VPSHUFB  ·rol16<>(SB), DD0, DD0; VPSHUFB ·rol16<>(SB), DD1, DD1; VPSHUFB ·rol16<>(SB), DD2, DD2; VPSHUFB ·rol16<>(SB), DD3, DD3
+	VPADDD   DD0, CC0, CC0; VPADDD DD1, CC1, CC1; VPADDD DD2, CC2, CC2; VPADDD DD3, CC3, CC3
+	VPXOR    CC0, BB0, BB0; VPXOR CC1, BB1, BB1; VPXOR CC2, BB2, BB2; VPXOR CC3, BB3, BB3
+	polyAdd(2*8(itr2))
+	polyMulAVX2
+	LEAQ     (4*8)(itr2), itr2
+	VMOVDQA  CC3, tmpStoreAVX2
+	VPSLLD   $12, BB0, CC3; VPSRLD $20, BB0, BB0; VPXOR CC3, BB0, BB0
+	VPSLLD   $12, BB1, CC3; VPSRLD $20, BB1, BB1; VPXOR CC3, BB1, BB1
+	VPSLLD   $12, BB2, CC3; VPSRLD $20, BB2, BB2; VPXOR CC3, BB2, BB2
+	VPSLLD   $12, BB3, CC3; VPSRLD $20, BB3, BB3; VPXOR CC3, BB3, BB3
+	VMOVDQA  tmpStoreAVX2, CC3
+	VPADDD   BB0, AA0, AA0; VPADDD BB1, AA1, AA1; VPADDD BB2, AA2, AA2; VPADDD BB3, AA3, AA3
+	VPXOR    AA0, DD0, DD0; VPXOR AA1, DD1, DD1; VPXOR AA2, DD2, DD2; VPXOR AA3, DD3, DD3
+	VPSHUFB  ·rol8<>(SB), DD0, DD0; VPSHUFB ·rol8<>(SB), DD1, DD1; VPSHUFB ·rol8<>(SB), DD2, DD2; VPSHUFB ·rol8<>(SB), DD3, DD3
+	VPADDD   DD0, CC0, CC0; VPADDD DD1, CC1, CC1; VPADDD DD2, CC2, CC2; VPADDD DD3, CC3, CC3
+	VPXOR    CC0, BB0, BB0; VPXOR CC1, BB1, BB1; VPXOR CC2, BB2, BB2; VPXOR CC3, BB3, BB3
+	VMOVDQA  CC3, tmpStoreAVX2
+	VPSLLD   $7, BB0, CC3; VPSRLD $25, BB0, BB0; VPXOR CC3, BB0, BB0
+	VPSLLD   $7, BB1, CC3; VPSRLD $25, BB1, BB1; VPXOR CC3, BB1, BB1
+	VPSLLD   $7, BB2, CC3; VPSRLD $25, BB2, BB2; VPXOR CC3, BB2, BB2
+	VPSLLD   $7, BB3, CC3; VPSRLD $25, BB3, BB3; VPXOR CC3, BB3, BB3
+	VMOVDQA  tmpStoreAVX2, CC3
+	VPALIGNR $12, BB0, BB0, BB0; VPALIGNR $12, BB1, BB1, BB1; VPALIGNR $12, BB2, BB2, BB2; VPALIGNR $12, BB3, BB3, BB3
+	VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $8, CC2, CC2, CC2; VPALIGNR $8, CC3, CC3, CC3
+	VPALIGNR $4, DD0, DD0, DD0; VPALIGNR $4, DD1, DD1, DD1; VPALIGNR $4, DD2, DD2, DD2; VPALIGNR $4, DD3, DD3, DD3
+	INCQ     itr1
+	CMPQ     itr1, $4
+	JLT      openAVX2Tail512LoopB
+
+	CMPQ itr1, $10
+	JNE  openAVX2Tail512LoopA
+
+	MOVQ inl, itr1
+	SUBQ $384, itr1
+	ANDQ $-16, itr1
+
+openAVX2Tail512HashLoop:
+	TESTQ itr1, itr1
+	JE    openAVX2Tail512HashEnd
+	polyAdd(0(itr2))
+	polyMulAVX2
+	LEAQ  16(itr2), itr2
+	SUBQ  $16, itr1
+	JMP   openAVX2Tail512HashLoop
+
+openAVX2Tail512HashEnd:
+	VPADDD     ·chacha20Constants<>(SB), AA0, AA0; VPADDD ·chacha20Constants<>(SB), AA1, AA1; VPADDD ·chacha20Constants<>(SB), AA2, AA2; VPADDD ·chacha20Constants<>(SB), AA3, AA3
+	VPADDD     state1StoreAVX2, BB0, BB0; VPADDD state1StoreAVX2, BB1, BB1; VPADDD state1StoreAVX2, BB2, BB2; VPADDD state1StoreAVX2, BB3, BB3
+	VPADDD     state2StoreAVX2, CC0, CC0; VPADDD state2StoreAVX2, CC1, CC1; VPADDD state2StoreAVX2, CC2, CC2; VPADDD state2StoreAVX2, CC3, CC3
+	VPADDD     ctr0StoreAVX2, DD0, DD0; VPADDD ctr1StoreAVX2, DD1, DD1; VPADDD ctr2StoreAVX2, DD2, DD2; VPADDD ctr3StoreAVX2, DD3, DD3
+	VMOVDQA    CC3, tmpStoreAVX2
+	VPERM2I128 $0x02, AA0, BB0, CC3; VPERM2I128 $0x13, AA0, BB0, BB0; VPERM2I128 $0x02, CC0, DD0, AA0; VPERM2I128 $0x13, CC0, DD0, CC0
+	VPXOR      (0*32)(inp), CC3, CC3; VPXOR (1*32)(inp), AA0, AA0; VPXOR (2*32)(inp), BB0, BB0; VPXOR (3*32)(inp), CC0, CC0
+	VMOVDQU    CC3, (0*32)(oup); VMOVDQU AA0, (1*32)(oup); VMOVDQU BB0, (2*32)(oup); VMOVDQU CC0, (3*32)(oup)
+	VPERM2I128 $0x02, AA1, BB1, AA0; VPERM2I128 $0x02, CC1, DD1, BB0; VPERM2I128 $0x13, AA1, BB1, CC0; VPERM2I128 $0x13, CC1, DD1, DD0
+	VPXOR      (4*32)(inp), AA0, AA0; VPXOR (5*32)(inp), BB0, BB0; VPXOR (6*32)(inp), CC0, CC0; VPXOR (7*32)(inp), DD0, DD0
+	VMOVDQU    AA0, (4*32)(oup); VMOVDQU BB0, (5*32)(oup); VMOVDQU CC0, (6*32)(oup); VMOVDQU DD0, (7*32)(oup)
+	VPERM2I128 $0x02, AA2, BB2, AA0; VPERM2I128 $0x02, CC2, DD2, BB0; VPERM2I128 $0x13, AA2, BB2, CC0; VPERM2I128 $0x13, CC2, DD2, DD0
+	VPXOR      (8*32)(inp), AA0, AA0; VPXOR (9*32)(inp), BB0, BB0; VPXOR (10*32)(inp), CC0, CC0; VPXOR (11*32)(inp), DD0, DD0
+	VMOVDQU    AA0, (8*32)(oup); VMOVDQU BB0, (9*32)(oup); VMOVDQU CC0, (10*32)(oup); VMOVDQU DD0, (11*32)(oup)
+	VPERM2I128 $0x02, AA3, BB3, AA0; VPERM2I128 $0x02, tmpStoreAVX2, DD3, BB0; VPERM2I128 $0x13, AA3, BB3, CC0; VPERM2I128 $0x13, tmpStoreAVX2, DD3, DD0
+
+	LEAQ (12*32)(inp), inp
+	LEAQ (12*32)(oup), oup
+	SUBQ $12*32, inl
+
+	JMP openAVX2TailLoop
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+// func chacha20Poly1305Seal(dst, key, src, ad []byte)
+TEXT ·chacha20Poly1305Seal(SB), 0, $288-96
+	// For aligned stack access
+	MOVQ SP, BP
+	ADDQ $32, BP
+	ANDQ $-32, BP
+	MOVQ dst+0(FP), oup
+	MOVQ key+24(FP), keyp
+	MOVQ src+48(FP), inp
+	MOVQ src_len+56(FP), inl
+	MOVQ ad+72(FP), adp
+
+	CMPB ·useAVX2(SB), $1
+	JE   chacha20Poly1305Seal_AVX2
+
+	// Special optimization, for very short buffers
+	CMPQ inl, $128
+	JBE  sealSSE128 // About 15% faster
+
+	// In the seal case - prepare the poly key + 3 blocks of stream in the first iteration
+	MOVOU ·chacha20Constants<>(SB), A0
+	MOVOU (1*16)(keyp), B0
+	MOVOU (2*16)(keyp), C0
+	MOVOU (3*16)(keyp), D0
+
+	// Store state on stack for future use
+	MOVO B0, state1Store
+	MOVO C0, state2Store
+
+	// Load state, increment counter blocks
+	MOVO A0, A1; MOVO B0, B1; MOVO C0, C1; MOVO D0, D1; PADDL ·sseIncMask<>(SB), D1
+	MOVO A1, A2; MOVO B1, B2; MOVO C1, C2; MOVO D1, D2; PADDL ·sseIncMask<>(SB), D2
+	MOVO A2, A3; MOVO B2, B3; MOVO C2, C3; MOVO D2, D3; PADDL ·sseIncMask<>(SB), D3
+
+	// Store counters
+	MOVO D0, ctr0Store; MOVO D1, ctr1Store; MOVO D2, ctr2Store; MOVO D3, ctr3Store
+	MOVQ $10, itr2
+
+sealSSEIntroLoop:
+	MOVO         C3, tmpStore
+	chachaQR(A0, B0, C0, D0, C3); chachaQR(A1, B1, C1, D1, C3); chachaQR(A2, B2, C2, D2, C3)
+	MOVO         tmpStore, C3
+	MOVO         C1, tmpStore
+	chachaQR(A3, B3, C3, D3, C1)
+	MOVO         tmpStore, C1
+	shiftB0Left; shiftB1Left; shiftB2Left; shiftB3Left
+	shiftC0Left; shiftC1Left; shiftC2Left; shiftC3Left
+	shiftD0Left; shiftD1Left; shiftD2Left; shiftD3Left
+
+	MOVO          C3, tmpStore
+	chachaQR(A0, B0, C0, D0, C3); chachaQR(A1, B1, C1, D1, C3); chachaQR(A2, B2, C2, D2, C3)
+	MOVO          tmpStore, C3
+	MOVO          C1, tmpStore
+	chachaQR(A3, B3, C3, D3, C1)
+	MOVO          tmpStore, C1
+	shiftB0Right; shiftB1Right; shiftB2Right; shiftB3Right
+	shiftC0Right; shiftC1Right; shiftC2Right; shiftC3Right
+	shiftD0Right; shiftD1Right; shiftD2Right; shiftD3Right
+	DECQ          itr2
+	JNE           sealSSEIntroLoop
+
+	// Add in the state
+	PADDD ·chacha20Constants<>(SB), A0; PADDD ·chacha20Constants<>(SB), A1; PADDD ·chacha20Constants<>(SB), A2; PADDD ·chacha20Constants<>(SB), A3
+	PADDD state1Store, B0; PADDD state1Store, B1; PADDD state1Store, B2; PADDD state1Store, B3
+	PADDD state2Store, C1; PADDD state2Store, C2; PADDD state2Store, C3
+	PADDD ctr1Store, D1; PADDD ctr2Store, D2; PADDD ctr3Store, D3
+
+	// Clamp and store the key
+	PAND ·polyClampMask<>(SB), A0
+	MOVO A0, rStore
+	MOVO B0, sStore
+
+	// Hash AAD
+	MOVQ ad_len+80(FP), itr2
+	CALL polyHashADInternal<>(SB)
+
+	MOVOU (0*16)(inp), A0; MOVOU (1*16)(inp), B0; MOVOU (2*16)(inp), C0; MOVOU (3*16)(inp), D0
+	PXOR  A0, A1; PXOR B0, B1; PXOR C0, C1; PXOR D0, D1
+	MOVOU A1, (0*16)(oup); MOVOU B1, (1*16)(oup); MOVOU C1, (2*16)(oup); MOVOU D1, (3*16)(oup)
+	MOVOU (4*16)(inp), A0; MOVOU (5*16)(inp), B0; MOVOU (6*16)(inp), C0; MOVOU (7*16)(inp), D0
+	PXOR  A0, A2; PXOR B0, B2; PXOR C0, C2; PXOR D0, D2
+	MOVOU A2, (4*16)(oup); MOVOU B2, (5*16)(oup); MOVOU C2, (6*16)(oup); MOVOU D2, (7*16)(oup)
+
+	MOVQ $128, itr1
+	SUBQ $128, inl
+	LEAQ 128(inp), inp
+
+	MOVO A3, A1; MOVO B3, B1; MOVO C3, C1; MOVO D3, D1
+
+	CMPQ inl, $64
+	JBE  sealSSE128SealHash
+
+	MOVOU (0*16)(inp), A0; MOVOU (1*16)(inp), B0; MOVOU (2*16)(inp), C0; MOVOU (3*16)(inp), D0
+	PXOR  A0, A3; PXOR B0, B3; PXOR C0, C3; PXOR D0, D3
+	MOVOU A3, (8*16)(oup); MOVOU B3, (9*16)(oup); MOVOU C3, (10*16)(oup); MOVOU D3, (11*16)(oup)
+
+	ADDQ $64, itr1
+	SUBQ $64, inl
+	LEAQ 64(inp), inp
+
+	MOVQ $2, itr1
+	MOVQ $8, itr2
+
+	CMPQ inl, $64
+	JBE  sealSSETail64
+	CMPQ inl, $128
+	JBE  sealSSETail128
+	CMPQ inl, $192
+	JBE  sealSSETail192
+
+sealSSEMainLoop:
+	// Load state, increment counter blocks
+	MOVO ·chacha20Constants<>(SB), A0; MOVO state1Store, B0; MOVO state2Store, C0; MOVO ctr3Store, D0; PADDL ·sseIncMask<>(SB), D0
+	MOVO A0, A1; MOVO B0, B1; MOVO C0, C1; MOVO D0, D1; PADDL ·sseIncMask<>(SB), D1
+	MOVO A1, A2; MOVO B1, B2; MOVO C1, C2; MOVO D1, D2; PADDL ·sseIncMask<>(SB), D2
+	MOVO A2, A3; MOVO B2, B3; MOVO C2, C3; MOVO D2, D3; PADDL ·sseIncMask<>(SB), D3
+
+	// Store counters
+	MOVO D0, ctr0Store; MOVO D1, ctr1Store; MOVO D2, ctr2Store; MOVO D3, ctr3Store
+
+sealSSEInnerLoop:
+	MOVO          C3, tmpStore
+	chachaQR(A0, B0, C0, D0, C3); chachaQR(A1, B1, C1, D1, C3); chachaQR(A2, B2, C2, D2, C3)
+	MOVO          tmpStore, C3
+	MOVO          C1, tmpStore
+	chachaQR(A3, B3, C3, D3, C1)
+	MOVO          tmpStore, C1
+	polyAdd(0(oup))
+	shiftB0Left;  shiftB1Left; shiftB2Left; shiftB3Left
+	shiftC0Left;  shiftC1Left; shiftC2Left; shiftC3Left
+	shiftD0Left;  shiftD1Left; shiftD2Left; shiftD3Left
+	polyMulStage1
+	polyMulStage2
+	LEAQ          (2*8)(oup), oup
+	MOVO          C3, tmpStore
+	chachaQR(A0, B0, C0, D0, C3); chachaQR(A1, B1, C1, D1, C3); chachaQR(A2, B2, C2, D2, C3)
+	MOVO          tmpStore, C3
+	MOVO          C1, tmpStore
+	polyMulStage3
+	chachaQR(A3, B3, C3, D3, C1)
+	MOVO          tmpStore, C1
+	polyMulReduceStage
+	shiftB0Right; shiftB1Right; shiftB2Right; shiftB3Right
+	shiftC0Right; shiftC1Right; shiftC2Right; shiftC3Right
+	shiftD0Right; shiftD1Right; shiftD2Right; shiftD3Right
+	DECQ          itr2
+	JGE           sealSSEInnerLoop
+	polyAdd(0(oup))
+	polyMul
+	LEAQ          (2*8)(oup), oup
+	DECQ          itr1
+	JG            sealSSEInnerLoop
+
+	// Add in the state
+	PADDD ·chacha20Constants<>(SB), A0; PADDD ·chacha20Constants<>(SB), A1; PADDD ·chacha20Constants<>(SB), A2; PADDD ·chacha20Constants<>(SB), A3
+	PADDD state1Store, B0; PADDD state1Store, B1; PADDD state1Store, B2; PADDD state1Store, B3
+	PADDD state2Store, C0; PADDD state2Store, C1; PADDD state2Store, C2; PADDD state2Store, C3
+	PADDD ctr0Store, D0; PADDD ctr1Store, D1; PADDD ctr2Store, D2; PADDD ctr3Store, D3
+	MOVO  D3, tmpStore
+
+	// Load - xor - store
+	MOVOU (0*16)(inp), D3; PXOR D3, A0
+	MOVOU (1*16)(inp), D3; PXOR D3, B0
+	MOVOU (2*16)(inp), D3; PXOR D3, C0
+	MOVOU (3*16)(inp), D3; PXOR D3, D0
+	MOVOU A0, (0*16)(oup)
+	MOVOU B0, (1*16)(oup)
+	MOVOU C0, (2*16)(oup)
+	MOVOU D0, (3*16)(oup)
+	MOVO  tmpStore, D3
+
+	MOVOU (4*16)(inp), A0; MOVOU (5*16)(inp), B0; MOVOU (6*16)(inp), C0; MOVOU (7*16)(inp), D0
+	PXOR  A0, A1; PXOR B0, B1; PXOR C0, C1; PXOR D0, D1
+	MOVOU A1, (4*16)(oup); MOVOU B1, (5*16)(oup); MOVOU C1, (6*16)(oup); MOVOU D1, (7*16)(oup)
+	MOVOU (8*16)(inp), A0; MOVOU (9*16)(inp), B0; MOVOU (10*16)(inp), C0; MOVOU (11*16)(inp), D0
+	PXOR  A0, A2; PXOR B0, B2; PXOR C0, C2; PXOR D0, D2
+	MOVOU A2, (8*16)(oup); MOVOU B2, (9*16)(oup); MOVOU C2, (10*16)(oup); MOVOU D2, (11*16)(oup)
+	ADDQ  $192, inp
+	MOVQ  $192, itr1
+	SUBQ  $192, inl
+	MOVO  A3, A1
+	MOVO  B3, B1
+	MOVO  C3, C1
+	MOVO  D3, D1
+	CMPQ  inl, $64
+	JBE   sealSSE128SealHash
+	MOVOU (0*16)(inp), A0; MOVOU (1*16)(inp), B0; MOVOU (2*16)(inp), C0; MOVOU (3*16)(inp), D0
+	PXOR  A0, A3; PXOR B0, B3; PXOR C0, C3; PXOR D0, D3
+	MOVOU A3, (12*16)(oup); MOVOU B3, (13*16)(oup); MOVOU C3, (14*16)(oup); MOVOU D3, (15*16)(oup)
+	LEAQ  64(inp), inp
+	SUBQ  $64, inl
+	MOVQ  $6, itr1
+	MOVQ  $4, itr2
+	CMPQ  inl, $192
+	JG    sealSSEMainLoop
+
+	MOVQ  inl, itr1
+	TESTQ inl, inl
+	JE    sealSSE128SealHash
+	MOVQ  $6, itr1
+	CMPQ  inl, $64
+	JBE   sealSSETail64
+	CMPQ  inl, $128
+	JBE   sealSSETail128
+	JMP   sealSSETail192
+
+// ----------------------------------------------------------------------------
+// Special optimization for the last 64 bytes of plaintext
+sealSSETail64:
+	// Need to encrypt up to 64 bytes - prepare single block, hash 192 or 256 bytes
+	MOVO  ·chacha20Constants<>(SB), A1
+	MOVO  state1Store, B1
+	MOVO  state2Store, C1
+	MOVO  ctr3Store, D1
+	PADDL ·sseIncMask<>(SB), D1
+	MOVO  D1, ctr0Store
+
+sealSSETail64LoopA:
+	// Perform ChaCha rounds, while hashing the previously encrypted ciphertext
+	polyAdd(0(oup))
+	polyMul
+	LEAQ 16(oup), oup
+
+sealSSETail64LoopB:
+	chachaQR(A1, B1, C1, D1, T1)
+	shiftB1Left;  shiftC1Left; shiftD1Left
+	chachaQR(A1, B1, C1, D1, T1)
+	shiftB1Right; shiftC1Right; shiftD1Right
+	polyAdd(0(oup))
+	polyMul
+	LEAQ          16(oup), oup
+
+	DECQ itr1
+	JG   sealSSETail64LoopA
+
+	DECQ  itr2
+	JGE   sealSSETail64LoopB
+	PADDL ·chacha20Constants<>(SB), A1
+	PADDL state1Store, B1
+	PADDL state2Store, C1
+	PADDL ctr0Store, D1
+
+	JMP sealSSE128Seal
+
+// ----------------------------------------------------------------------------
+// Special optimization for the last 128 bytes of plaintext
+sealSSETail128:
+	// Need to encrypt up to 128 bytes - prepare two blocks, hash 192 or 256 bytes
+	MOVO ·chacha20Constants<>(SB), A0; MOVO state1Store, B0; MOVO state2Store, C0; MOVO ctr3Store, D0; PADDL ·sseIncMask<>(SB), D0; MOVO D0, ctr0Store
+	MOVO A0, A1; MOVO B0, B1; MOVO C0, C1; MOVO D0, D1; PADDL ·sseIncMask<>(SB), D1; MOVO D1, ctr1Store
+
+sealSSETail128LoopA:
+	// Perform ChaCha rounds, while hashing the previously encrypted ciphertext
+	polyAdd(0(oup))
+	polyMul
+	LEAQ 16(oup), oup
+
+sealSSETail128LoopB:
+	chachaQR(A0, B0, C0, D0, T0); chachaQR(A1, B1, C1, D1, T0)
+	shiftB0Left;  shiftC0Left; shiftD0Left
+	shiftB1Left;  shiftC1Left; shiftD1Left
+	polyAdd(0(oup))
+	polyMul
+	LEAQ          16(oup), oup
+	chachaQR(A0, B0, C0, D0, T0); chachaQR(A1, B1, C1, D1, T0)
+	shiftB0Right; shiftC0Right; shiftD0Right
+	shiftB1Right; shiftC1Right; shiftD1Right
+
+	DECQ itr1
+	JG   sealSSETail128LoopA
+
+	DECQ itr2
+	JGE  sealSSETail128LoopB
+
+	PADDL ·chacha20Constants<>(SB), A0; PADDL ·chacha20Constants<>(SB), A1
+	PADDL state1Store, B0; PADDL state1Store, B1
+	PADDL state2Store, C0; PADDL state2Store, C1
+	PADDL ctr0Store, D0; PADDL ctr1Store, D1
+
+	MOVOU (0*16)(inp), T0; MOVOU (1*16)(inp), T1; MOVOU (2*16)(inp), T2; MOVOU (3*16)(inp), T3
+	PXOR  T0, A0; PXOR T1, B0; PXOR T2, C0; PXOR T3, D0
+	MOVOU A0, (0*16)(oup); MOVOU B0, (1*16)(oup); MOVOU C0, (2*16)(oup); MOVOU D0, (3*16)(oup)
+
+	MOVQ $64, itr1
+	LEAQ 64(inp), inp
+	SUBQ $64, inl
+
+	JMP sealSSE128SealHash
+
+// ----------------------------------------------------------------------------
+// Special optimization for the last 192 bytes of plaintext
+sealSSETail192:
+	// Need to encrypt up to 192 bytes - prepare three blocks, hash 192 or 256 bytes
+	MOVO ·chacha20Constants<>(SB), A0; MOVO state1Store, B0; MOVO state2Store, C0; MOVO ctr3Store, D0; PADDL ·sseIncMask<>(SB), D0; MOVO D0, ctr0Store
+	MOVO A0, A1; MOVO B0, B1; MOVO C0, C1; MOVO D0, D1; PADDL ·sseIncMask<>(SB), D1; MOVO D1, ctr1Store
+	MOVO A1, A2; MOVO B1, B2; MOVO C1, C2; MOVO D1, D2; PADDL ·sseIncMask<>(SB), D2; MOVO D2, ctr2Store
+
+sealSSETail192LoopA:
+	// Perform ChaCha rounds, while hashing the previously encrypted ciphertext
+	polyAdd(0(oup))
+	polyMul
+	LEAQ 16(oup), oup
+
+sealSSETail192LoopB:
+	chachaQR(A0, B0, C0, D0, T0); chachaQR(A1, B1, C1, D1, T0); chachaQR(A2, B2, C2, D2, T0)
+	shiftB0Left; shiftC0Left; shiftD0Left
+	shiftB1Left; shiftC1Left; shiftD1Left
+	shiftB2Left; shiftC2Left; shiftD2Left
+
+	polyAdd(0(oup))
+	polyMul
+	LEAQ 16(oup), oup
+
+	chachaQR(A0, B0, C0, D0, T0); chachaQR(A1, B1, C1, D1, T0); chachaQR(A2, B2, C2, D2, T0)
+	shiftB0Right; shiftC0Right; shiftD0Right
+	shiftB1Right; shiftC1Right; shiftD1Right
+	shiftB2Right; shiftC2Right; shiftD2Right
+
+	DECQ itr1
+	JG   sealSSETail192LoopA
+
+	DECQ itr2
+	JGE  sealSSETail192LoopB
+
+	PADDL ·chacha20Constants<>(SB), A0; PADDL ·chacha20Constants<>(SB), A1; PADDL ·chacha20Constants<>(SB), A2
+	PADDL state1Store, B0; PADDL state1Store, B1; PADDL state1Store, B2
+	PADDL state2Store, C0; PADDL state2Store, C1; PADDL state2Store, C2
+	PADDL ctr0Store, D0; PADDL ctr1Store, D1; PADDL ctr2Store, D2
+
+	MOVOU (0*16)(inp), T0; MOVOU (1*16)(inp), T1; MOVOU (2*16)(inp), T2; MOVOU (3*16)(inp), T3
+	PXOR  T0, A0; PXOR T1, B0; PXOR T2, C0; PXOR T3, D0
+	MOVOU A0, (0*16)(oup); MOVOU B0, (1*16)(oup); MOVOU C0, (2*16)(oup); MOVOU D0, (3*16)(oup)
+	MOVOU (4*16)(inp), T0; MOVOU (5*16)(inp), T1; MOVOU (6*16)(inp), T2; MOVOU (7*16)(inp), T3
+	PXOR  T0, A1; PXOR T1, B1; PXOR T2, C1; PXOR T3, D1
+	MOVOU A1, (4*16)(oup); MOVOU B1, (5*16)(oup); MOVOU C1, (6*16)(oup); MOVOU D1, (7*16)(oup)
+
+	MOVO A2, A1
+	MOVO B2, B1
+	MOVO C2, C1
+	MOVO D2, D1
+	MOVQ $128, itr1
+	LEAQ 128(inp), inp
+	SUBQ $128, inl
+
+	JMP sealSSE128SealHash
+
+// ----------------------------------------------------------------------------
+// Special seal optimization for buffers smaller than 129 bytes
+sealSSE128:
+	// For up to 128 bytes of ciphertext and 64 bytes for the poly key, we require to process three blocks
+	MOVOU ·chacha20Constants<>(SB), A0; MOVOU (1*16)(keyp), B0; MOVOU (2*16)(keyp), C0; MOVOU (3*16)(keyp), D0
+	MOVO  A0, A1; MOVO B0, B1; MOVO C0, C1; MOVO D0, D1; PADDL ·sseIncMask<>(SB), D1
+	MOVO  A1, A2; MOVO B1, B2; MOVO C1, C2; MOVO D1, D2; PADDL ·sseIncMask<>(SB), D2
+	MOVO  B0, T1; MOVO C0, T2; MOVO D1, T3
+	MOVQ  $10, itr2
+
+sealSSE128InnerCipherLoop:
+	chachaQR(A0, B0, C0, D0, T0); chachaQR(A1, B1, C1, D1, T0); chachaQR(A2, B2, C2, D2, T0)
+	shiftB0Left;  shiftB1Left; shiftB2Left
+	shiftC0Left;  shiftC1Left; shiftC2Left
+	shiftD0Left;  shiftD1Left; shiftD2Left
+	chachaQR(A0, B0, C0, D0, T0); chachaQR(A1, B1, C1, D1, T0); chachaQR(A2, B2, C2, D2, T0)
+	shiftB0Right; shiftB1Right; shiftB2Right
+	shiftC0Right; shiftC1Right; shiftC2Right
+	shiftD0Right; shiftD1Right; shiftD2Right
+	DECQ          itr2
+	JNE           sealSSE128InnerCipherLoop
+
+	// A0|B0 hold the Poly1305 32-byte key, C0,D0 can be discarded
+	PADDL ·chacha20Constants<>(SB), A0; PADDL ·chacha20Constants<>(SB), A1; PADDL ·chacha20Constants<>(SB), A2
+	PADDL T1, B0; PADDL T1, B1; PADDL T1, B2
+	PADDL T2, C1; PADDL T2, C2
+	PADDL T3, D1; PADDL ·sseIncMask<>(SB), T3; PADDL T3, D2
+	PAND  ·polyClampMask<>(SB), A0
+	MOVOU A0, rStore
+	MOVOU B0, sStore
+
+	// Hash
+	MOVQ ad_len+80(FP), itr2
+	CALL polyHashADInternal<>(SB)
+	XORQ itr1, itr1
+
+sealSSE128SealHash:
+	// itr1 holds the number of bytes encrypted but not yet hashed
+	CMPQ itr1, $16
+	JB   sealSSE128Seal
+	polyAdd(0(oup))
+	polyMul
+
+	SUBQ $16, itr1
+	ADDQ $16, oup
+
+	JMP sealSSE128SealHash
+
+sealSSE128Seal:
+	CMPQ inl, $16
+	JB   sealSSETail
+	SUBQ $16, inl
+
+	// Load for decryption
+	MOVOU (inp), T0
+	PXOR  T0, A1
+	MOVOU A1, (oup)
+	LEAQ  (1*16)(inp), inp
+	LEAQ  (1*16)(oup), oup
+
+	// Extract for hashing
+	MOVQ   A1, t0
+	PSRLDQ $8, A1
+	MOVQ A1, t1
+	ADDQ   t0, acc0; ADCQ t1, acc1; ADCQ $1, acc2
+	polyMul
+
+	// Shift the stream "left"
+	MOVO B1, A1
+	MOVO C1, B1
+	MOVO D1, C1
+	MOVO A2, D1
+	MOVO B2, A2
+	MOVO C2, B2
+	MOVO D2, C2
+	JMP  sealSSE128Seal
+
+sealSSETail:
+	TESTQ inl, inl
+	JE    sealSSEFinalize
+
+	// We can only load the PT one byte at a time to avoid read after end of buffer
+	MOVQ inl, itr2
+	SHLQ $4, itr2
+	LEAQ ·andMask<>(SB), t0
+	MOVQ inl, itr1
+	LEAQ -1(inp)(inl*1), inp
+	XORQ t2, t2
+	XORQ t3, t3
+	XORQ AX, AX
+
+sealSSETailLoadLoop:
+	SHLQ $8, t2, t3
+	SHLQ $8, t2
+	MOVB (inp), AX
+	XORQ AX, t2
+	LEAQ   -1(inp), inp
+	DECQ   itr1
+	JNE    sealSSETailLoadLoop
+	MOVQ t2, 0+tmpStore
+	MOVQ t3, 8+tmpStore
+	PXOR 0+tmpStore, A1
+	MOVOU  A1, (oup)
+	MOVOU  -16(t0)(itr2*1), T0
+	PAND   T0, A1
+	MOVQ   A1, t0
+	PSRLDQ $8, A1
+	MOVQ   A1, t1
+	ADDQ   t0, acc0; ADCQ t1, acc1; ADCQ $1, acc2
+	polyMul
+
+	ADDQ inl, oup
+
+sealSSEFinalize:
+	// Hash in the buffer lengths
+	ADDQ ad_len+80(FP), acc0
+	ADCQ src_len+56(FP), acc1
+	ADCQ $1, acc2
+	polyMul
+
+	// Final reduce
+	MOVQ    acc0, t0
+	MOVQ    acc1, t1
+	MOVQ    acc2, t2
+	SUBQ    $-5, acc0
+	SBBQ    $-1, acc1
+	SBBQ    $3, acc2
+	CMOVQCS t0, acc0
+	CMOVQCS t1, acc1
+	CMOVQCS t2, acc2
+
+	// Add in the "s" part of the key
+	ADDQ 0+sStore, acc0
+	ADCQ 8+sStore, acc1
+
+	// Finally store the tag at the end of the message
+	MOVQ acc0, (0*8)(oup)
+	MOVQ acc1, (1*8)(oup)
+	RET
+
+// ----------------------------------------------------------------------------
+// ------------------------- AVX2 Code ----------------------------------------
+chacha20Poly1305Seal_AVX2:
+	VZEROUPPER
+	VMOVDQU ·chacha20Constants<>(SB), AA0
+	BYTE    $0xc4; BYTE $0x42; BYTE $0x7d; BYTE $0x5a; BYTE $0x70; BYTE $0x10 // broadcasti128 16(r8), ymm14
+	BYTE    $0xc4; BYTE $0x42; BYTE $0x7d; BYTE $0x5a; BYTE $0x60; BYTE $0x20 // broadcasti128 32(r8), ymm12
+	BYTE    $0xc4; BYTE $0xc2; BYTE $0x7d; BYTE $0x5a; BYTE $0x60; BYTE $0x30 // broadcasti128 48(r8), ymm4
+	VPADDD  ·avx2InitMask<>(SB), DD0, DD0
+
+	// Special optimizations, for very short buffers
+	CMPQ inl, $192
+	JBE  seal192AVX2 // 33% faster
+	CMPQ inl, $320
+	JBE  seal320AVX2 // 17% faster
+
+	// For the general key prepare the key first - as a byproduct we have 64 bytes of cipher stream
+	VMOVDQA AA0, AA1; VMOVDQA AA0, AA2; VMOVDQA AA0, AA3
+	VMOVDQA BB0, BB1; VMOVDQA BB0, BB2; VMOVDQA BB0, BB3; VMOVDQA BB0, state1StoreAVX2
+	VMOVDQA CC0, CC1; VMOVDQA CC0, CC2; VMOVDQA CC0, CC3; VMOVDQA CC0, state2StoreAVX2
+	VPADDD  ·avx2IncMask<>(SB), DD0, DD1; VMOVDQA DD0, ctr0StoreAVX2
+	VPADDD  ·avx2IncMask<>(SB), DD1, DD2; VMOVDQA DD1, ctr1StoreAVX2
+	VPADDD  ·avx2IncMask<>(SB), DD2, DD3; VMOVDQA DD2, ctr2StoreAVX2
+	VMOVDQA DD3, ctr3StoreAVX2
+	MOVQ    $10, itr2
+
+sealAVX2IntroLoop:
+	VMOVDQA CC3, tmpStoreAVX2
+	chachaQR_AVX2(AA0, BB0, CC0, DD0, CC3); chachaQR_AVX2(AA1, BB1, CC1, DD1, CC3); chachaQR_AVX2(AA2, BB2, CC2, DD2, CC3)
+	VMOVDQA tmpStoreAVX2, CC3
+	VMOVDQA CC1, tmpStoreAVX2
+	chachaQR_AVX2(AA3, BB3, CC3, DD3, CC1)
+	VMOVDQA tmpStoreAVX2, CC1
+
+	VPALIGNR $4, BB0, BB0, BB0; VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $12, DD0, DD0, DD0
+	VPALIGNR $4, BB1, BB1, BB1; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $12, DD1, DD1, DD1
+	VPALIGNR $4, BB2, BB2, BB2; VPALIGNR $8, CC2, CC2, CC2; VPALIGNR $12, DD2, DD2, DD2
+	VPALIGNR $4, BB3, BB3, BB3; VPALIGNR $8, CC3, CC3, CC3; VPALIGNR $12, DD3, DD3, DD3
+
+	VMOVDQA CC3, tmpStoreAVX2
+	chachaQR_AVX2(AA0, BB0, CC0, DD0, CC3); chachaQR_AVX2(AA1, BB1, CC1, DD1, CC3); chachaQR_AVX2(AA2, BB2, CC2, DD2, CC3)
+	VMOVDQA tmpStoreAVX2, CC3
+	VMOVDQA CC1, tmpStoreAVX2
+	chachaQR_AVX2(AA3, BB3, CC3, DD3, CC1)
+	VMOVDQA tmpStoreAVX2, CC1
+
+	VPALIGNR $12, BB0, BB0, BB0; VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $4, DD0, DD0, DD0
+	VPALIGNR $12, BB1, BB1, BB1; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $4, DD1, DD1, DD1
+	VPALIGNR $12, BB2, BB2, BB2; VPALIGNR $8, CC2, CC2, CC2; VPALIGNR $4, DD2, DD2, DD2
+	VPALIGNR $12, BB3, BB3, BB3; VPALIGNR $8, CC3, CC3, CC3; VPALIGNR $4, DD3, DD3, DD3
+	DECQ     itr2
+	JNE      sealAVX2IntroLoop
+
+	VPADDD ·chacha20Constants<>(SB), AA0, AA0; VPADDD ·chacha20Constants<>(SB), AA1, AA1; VPADDD ·chacha20Constants<>(SB), AA2, AA2; VPADDD ·chacha20Constants<>(SB), AA3, AA3
+	VPADDD state1StoreAVX2, BB0, BB0; VPADDD state1StoreAVX2, BB1, BB1; VPADDD state1StoreAVX2, BB2, BB2; VPADDD state1StoreAVX2, BB3, BB3
+	VPADDD state2StoreAVX2, CC0, CC0; VPADDD state2StoreAVX2, CC1, CC1; VPADDD state2StoreAVX2, CC2, CC2; VPADDD state2StoreAVX2, CC3, CC3
+	VPADDD ctr0StoreAVX2, DD0, DD0; VPADDD ctr1StoreAVX2, DD1, DD1; VPADDD ctr2StoreAVX2, DD2, DD2; VPADDD ctr3StoreAVX2, DD3, DD3
+
+	VPERM2I128 $0x13, CC0, DD0, CC0 // Stream bytes 96 - 127
+	VPERM2I128 $0x02, AA0, BB0, DD0 // The Poly1305 key
+	VPERM2I128 $0x13, AA0, BB0, AA0 // Stream bytes 64 - 95
+
+	// Clamp and store poly key
+	VPAND   ·polyClampMask<>(SB), DD0, DD0
+	VMOVDQA DD0, rsStoreAVX2
+
+	// Hash AD
+	MOVQ ad_len+80(FP), itr2
+	CALL polyHashADInternal<>(SB)
+
+	// Can store at least 320 bytes
+	VPXOR   (0*32)(inp), AA0, AA0
+	VPXOR   (1*32)(inp), CC0, CC0
+	VMOVDQU AA0, (0*32)(oup)
+	VMOVDQU CC0, (1*32)(oup)
+
+	VPERM2I128 $0x02, AA1, BB1, AA0; VPERM2I128 $0x02, CC1, DD1, BB0; VPERM2I128 $0x13, AA1, BB1, CC0; VPERM2I128 $0x13, CC1, DD1, DD0
+	VPXOR      (2*32)(inp), AA0, AA0; VPXOR (3*32)(inp), BB0, BB0; VPXOR (4*32)(inp), CC0, CC0; VPXOR (5*32)(inp), DD0, DD0
+	VMOVDQU    AA0, (2*32)(oup); VMOVDQU BB0, (3*32)(oup); VMOVDQU CC0, (4*32)(oup); VMOVDQU DD0, (5*32)(oup)
+	VPERM2I128 $0x02, AA2, BB2, AA0; VPERM2I128 $0x02, CC2, DD2, BB0; VPERM2I128 $0x13, AA2, BB2, CC0; VPERM2I128 $0x13, CC2, DD2, DD0
+	VPXOR      (6*32)(inp), AA0, AA0; VPXOR (7*32)(inp), BB0, BB0; VPXOR (8*32)(inp), CC0, CC0; VPXOR (9*32)(inp), DD0, DD0
+	VMOVDQU    AA0, (6*32)(oup); VMOVDQU BB0, (7*32)(oup); VMOVDQU CC0, (8*32)(oup); VMOVDQU DD0, (9*32)(oup)
+
+	MOVQ $320, itr1
+	SUBQ $320, inl
+	LEAQ 320(inp), inp
+
+	VPERM2I128 $0x02, AA3, BB3, AA0; VPERM2I128 $0x02, CC3, DD3, BB0; VPERM2I128 $0x13, AA3, BB3, CC0; VPERM2I128 $0x13, CC3, DD3, DD0
+	CMPQ       inl, $128
+	JBE        sealAVX2SealHash
+
+	VPXOR   (0*32)(inp), AA0, AA0; VPXOR (1*32)(inp), BB0, BB0; VPXOR (2*32)(inp), CC0, CC0; VPXOR (3*32)(inp), DD0, DD0
+	VMOVDQU AA0, (10*32)(oup); VMOVDQU BB0, (11*32)(oup); VMOVDQU CC0, (12*32)(oup); VMOVDQU DD0, (13*32)(oup)
+	SUBQ    $128, inl
+	LEAQ    128(inp), inp
+
+	MOVQ $8, itr1
+	MOVQ $2, itr2
+
+	CMPQ inl, $128
+	JBE  sealAVX2Tail128
+	CMPQ inl, $256
+	JBE  sealAVX2Tail256
+	CMPQ inl, $384
+	JBE  sealAVX2Tail384
+	CMPQ inl, $512
+	JBE  sealAVX2Tail512
+
+	// We have 448 bytes to hash, but main loop hashes 512 bytes at a time - perform some rounds, before the main loop
+	VMOVDQA ·chacha20Constants<>(SB), AA0; VMOVDQA AA0, AA1; VMOVDQA AA0, AA2; VMOVDQA AA0, AA3
+	VMOVDQA state1StoreAVX2, BB0; VMOVDQA BB0, BB1; VMOVDQA BB0, BB2; VMOVDQA BB0, BB3
+	VMOVDQA state2StoreAVX2, CC0; VMOVDQA CC0, CC1; VMOVDQA CC0, CC2; VMOVDQA CC0, CC3
+	VMOVDQA ctr3StoreAVX2, DD0
+	VPADDD  ·avx2IncMask<>(SB), DD0, DD0; VPADDD ·avx2IncMask<>(SB), DD0, DD1; VPADDD ·avx2IncMask<>(SB), DD1, DD2; VPADDD ·avx2IncMask<>(SB), DD2, DD3
+	VMOVDQA DD0, ctr0StoreAVX2; VMOVDQA DD1, ctr1StoreAVX2; VMOVDQA DD2, ctr2StoreAVX2; VMOVDQA DD3, ctr3StoreAVX2
+
+	VMOVDQA CC3, tmpStoreAVX2
+	chachaQR_AVX2(AA0, BB0, CC0, DD0, CC3); chachaQR_AVX2(AA1, BB1, CC1, DD1, CC3); chachaQR_AVX2(AA2, BB2, CC2, DD2, CC3)
+	VMOVDQA tmpStoreAVX2, CC3
+	VMOVDQA CC1, tmpStoreAVX2
+	chachaQR_AVX2(AA3, BB3, CC3, DD3, CC1)
+	VMOVDQA tmpStoreAVX2, CC1
+
+	VPALIGNR $4, BB0, BB0, BB0; VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $12, DD0, DD0, DD0
+	VPALIGNR $4, BB1, BB1, BB1; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $12, DD1, DD1, DD1
+	VPALIGNR $4, BB2, BB2, BB2; VPALIGNR $8, CC2, CC2, CC2; VPALIGNR $12, DD2, DD2, DD2
+	VPALIGNR $4, BB3, BB3, BB3; VPALIGNR $8, CC3, CC3, CC3; VPALIGNR $12, DD3, DD3, DD3
+
+	VMOVDQA CC3, tmpStoreAVX2
+	chachaQR_AVX2(AA0, BB0, CC0, DD0, CC3); chachaQR_AVX2(AA1, BB1, CC1, DD1, CC3); chachaQR_AVX2(AA2, BB2, CC2, DD2, CC3)
+	VMOVDQA tmpStoreAVX2, CC3
+	VMOVDQA CC1, tmpStoreAVX2
+	chachaQR_AVX2(AA3, BB3, CC3, DD3, CC1)
+	VMOVDQA tmpStoreAVX2, CC1
+
+	VPALIGNR $12, BB0, BB0, BB0; VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $4, DD0, DD0, DD0
+	VPALIGNR $12, BB1, BB1, BB1; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $4, DD1, DD1, DD1
+	VPALIGNR $12, BB2, BB2, BB2; VPALIGNR $8, CC2, CC2, CC2; VPALIGNR $4, DD2, DD2, DD2
+	VPALIGNR $12, BB3, BB3, BB3; VPALIGNR $8, CC3, CC3, CC3; VPALIGNR $4, DD3, DD3, DD3
+	VPADDD   BB0, AA0, AA0; VPADDD BB1, AA1, AA1; VPADDD BB2, AA2, AA2; VPADDD BB3, AA3, AA3
+	VPXOR    AA0, DD0, DD0; VPXOR AA1, DD1, DD1; VPXOR AA2, DD2, DD2; VPXOR AA3, DD3, DD3
+	VPSHUFB  ·rol16<>(SB), DD0, DD0; VPSHUFB ·rol16<>(SB), DD1, DD1; VPSHUFB ·rol16<>(SB), DD2, DD2; VPSHUFB ·rol16<>(SB), DD3, DD3
+	VPADDD   DD0, CC0, CC0; VPADDD DD1, CC1, CC1; VPADDD DD2, CC2, CC2; VPADDD DD3, CC3, CC3
+	VPXOR    CC0, BB0, BB0; VPXOR CC1, BB1, BB1; VPXOR CC2, BB2, BB2; VPXOR CC3, BB3, BB3
+	VMOVDQA  CC3, tmpStoreAVX2
+	VPSLLD   $12, BB0, CC3; VPSRLD $20, BB0, BB0; VPXOR CC3, BB0, BB0
+	VPSLLD   $12, BB1, CC3; VPSRLD $20, BB1, BB1; VPXOR CC3, BB1, BB1
+	VPSLLD   $12, BB2, CC3; VPSRLD $20, BB2, BB2; VPXOR CC3, BB2, BB2
+	VPSLLD   $12, BB3, CC3; VPSRLD $20, BB3, BB3; VPXOR CC3, BB3, BB3
+	VMOVDQA  tmpStoreAVX2, CC3
+
+	SUBQ $16, oup                  // Adjust the pointer
+	MOVQ $9, itr1
+	JMP  sealAVX2InternalLoopStart
+
+sealAVX2MainLoop:
+	// Load state, increment counter blocks, store the incremented counters
+	VMOVDQU ·chacha20Constants<>(SB), AA0; VMOVDQA AA0, AA1; VMOVDQA AA0, AA2; VMOVDQA AA0, AA3
+	VMOVDQA state1StoreAVX2, BB0; VMOVDQA BB0, BB1; VMOVDQA BB0, BB2; VMOVDQA BB0, BB3
+	VMOVDQA state2StoreAVX2, CC0; VMOVDQA CC0, CC1; VMOVDQA CC0, CC2; VMOVDQA CC0, CC3
+	VMOVDQA ctr3StoreAVX2, DD0; VPADDD ·avx2IncMask<>(SB), DD0, DD0; VPADDD ·avx2IncMask<>(SB), DD0, DD1; VPADDD ·avx2IncMask<>(SB), DD1, DD2; VPADDD ·avx2IncMask<>(SB), DD2, DD3
+	VMOVDQA DD0, ctr0StoreAVX2; VMOVDQA DD1, ctr1StoreAVX2; VMOVDQA DD2, ctr2StoreAVX2; VMOVDQA DD3, ctr3StoreAVX2
+	MOVQ    $10, itr1
+
+sealAVX2InternalLoop:
+	polyAdd(0*8(oup))
+	VPADDD  BB0, AA0, AA0; VPADDD BB1, AA1, AA1; VPADDD BB2, AA2, AA2; VPADDD BB3, AA3, AA3
+	polyMulStage1_AVX2
+	VPXOR   AA0, DD0, DD0; VPXOR AA1, DD1, DD1; VPXOR AA2, DD2, DD2; VPXOR AA3, DD3, DD3
+	VPSHUFB ·rol16<>(SB), DD0, DD0; VPSHUFB ·rol16<>(SB), DD1, DD1; VPSHUFB ·rol16<>(SB), DD2, DD2; VPSHUFB ·rol16<>(SB), DD3, DD3
+	polyMulStage2_AVX2
+	VPADDD  DD0, CC0, CC0; VPADDD DD1, CC1, CC1; VPADDD DD2, CC2, CC2; VPADDD DD3, CC3, CC3
+	VPXOR   CC0, BB0, BB0; VPXOR CC1, BB1, BB1; VPXOR CC2, BB2, BB2; VPXOR CC3, BB3, BB3
+	polyMulStage3_AVX2
+	VMOVDQA CC3, tmpStoreAVX2
+	VPSLLD  $12, BB0, CC3; VPSRLD $20, BB0, BB0; VPXOR CC3, BB0, BB0
+	VPSLLD  $12, BB1, CC3; VPSRLD $20, BB1, BB1; VPXOR CC3, BB1, BB1
+	VPSLLD  $12, BB2, CC3; VPSRLD $20, BB2, BB2; VPXOR CC3, BB2, BB2
+	VPSLLD  $12, BB3, CC3; VPSRLD $20, BB3, BB3; VPXOR CC3, BB3, BB3
+	VMOVDQA tmpStoreAVX2, CC3
+	polyMulReduceStage
+
+sealAVX2InternalLoopStart:
+	VPADDD   BB0, AA0, AA0; VPADDD BB1, AA1, AA1; VPADDD BB2, AA2, AA2; VPADDD BB3, AA3, AA3
+	VPXOR    AA0, DD0, DD0; VPXOR AA1, DD1, DD1; VPXOR AA2, DD2, DD2; VPXOR AA3, DD3, DD3
+	VPSHUFB  ·rol8<>(SB), DD0, DD0; VPSHUFB ·rol8<>(SB), DD1, DD1; VPSHUFB ·rol8<>(SB), DD2, DD2; VPSHUFB ·rol8<>(SB), DD3, DD3
+	polyAdd(2*8(oup))
+	VPADDD   DD0, CC0, CC0; VPADDD DD1, CC1, CC1; VPADDD DD2, CC2, CC2; VPADDD DD3, CC3, CC3
+	polyMulStage1_AVX2
+	VPXOR    CC0, BB0, BB0; VPXOR CC1, BB1, BB1; VPXOR CC2, BB2, BB2; VPXOR CC3, BB3, BB3
+	VMOVDQA  CC3, tmpStoreAVX2
+	VPSLLD   $7, BB0, CC3; VPSRLD $25, BB0, BB0; VPXOR CC3, BB0, BB0
+	VPSLLD   $7, BB1, CC3; VPSRLD $25, BB1, BB1; VPXOR CC3, BB1, BB1
+	VPSLLD   $7, BB2, CC3; VPSRLD $25, BB2, BB2; VPXOR CC3, BB2, BB2
+	VPSLLD   $7, BB3, CC3; VPSRLD $25, BB3, BB3; VPXOR CC3, BB3, BB3
+	VMOVDQA  tmpStoreAVX2, CC3
+	polyMulStage2_AVX2
+	VPALIGNR $4, BB0, BB0, BB0; VPALIGNR $4, BB1, BB1, BB1; VPALIGNR $4, BB2, BB2, BB2; VPALIGNR $4, BB3, BB3, BB3
+	VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $8, CC2, CC2, CC2; VPALIGNR $8, CC3, CC3, CC3
+	VPALIGNR $12, DD0, DD0, DD0; VPALIGNR $12, DD1, DD1, DD1; VPALIGNR $12, DD2, DD2, DD2; VPALIGNR $12, DD3, DD3, DD3
+	VPADDD   BB0, AA0, AA0; VPADDD BB1, AA1, AA1; VPADDD BB2, AA2, AA2; VPADDD BB3, AA3, AA3
+	polyMulStage3_AVX2
+	VPXOR    AA0, DD0, DD0; VPXOR AA1, DD1, DD1; VPXOR AA2, DD2, DD2; VPXOR AA3, DD3, DD3
+	VPSHUFB  ·rol16<>(SB), DD0, DD0; VPSHUFB ·rol16<>(SB), DD1, DD1; VPSHUFB ·rol16<>(SB), DD2, DD2; VPSHUFB ·rol16<>(SB), DD3, DD3
+	polyMulReduceStage
+	VPADDD   DD0, CC0, CC0; VPADDD DD1, CC1, CC1; VPADDD DD2, CC2, CC2; VPADDD DD3, CC3, CC3
+	VPXOR    CC0, BB0, BB0; VPXOR CC1, BB1, BB1; VPXOR CC2, BB2, BB2; VPXOR CC3, BB3, BB3
+	polyAdd(4*8(oup))
+	LEAQ     (6*8)(oup), oup
+	VMOVDQA  CC3, tmpStoreAVX2
+	VPSLLD   $12, BB0, CC3; VPSRLD $20, BB0, BB0; VPXOR CC3, BB0, BB0
+	VPSLLD   $12, BB1, CC3; VPSRLD $20, BB1, BB1; VPXOR CC3, BB1, BB1
+	VPSLLD   $12, BB2, CC3; VPSRLD $20, BB2, BB2; VPXOR CC3, BB2, BB2
+	VPSLLD   $12, BB3, CC3; VPSRLD $20, BB3, BB3; VPXOR CC3, BB3, BB3
+	VMOVDQA  tmpStoreAVX2, CC3
+	polyMulStage1_AVX2
+	VPADDD   BB0, AA0, AA0; VPADDD BB1, AA1, AA1; VPADDD BB2, AA2, AA2; VPADDD BB3, AA3, AA3
+	VPXOR    AA0, DD0, DD0; VPXOR AA1, DD1, DD1; VPXOR AA2, DD2, DD2; VPXOR AA3, DD3, DD3
+	polyMulStage2_AVX2
+	VPSHUFB  ·rol8<>(SB), DD0, DD0; VPSHUFB ·rol8<>(SB), DD1, DD1; VPSHUFB ·rol8<>(SB), DD2, DD2; VPSHUFB ·rol8<>(SB), DD3, DD3
+	VPADDD   DD0, CC0, CC0; VPADDD DD1, CC1, CC1; VPADDD DD2, CC2, CC2; VPADDD DD3, CC3, CC3
+	polyMulStage3_AVX2
+	VPXOR    CC0, BB0, BB0; VPXOR CC1, BB1, BB1; VPXOR CC2, BB2, BB2; VPXOR CC3, BB3, BB3
+	VMOVDQA  CC3, tmpStoreAVX2
+	VPSLLD   $7, BB0, CC3; VPSRLD $25, BB0, BB0; VPXOR CC3, BB0, BB0
+	VPSLLD   $7, BB1, CC3; VPSRLD $25, BB1, BB1; VPXOR CC3, BB1, BB1
+	VPSLLD   $7, BB2, CC3; VPSRLD $25, BB2, BB2; VPXOR CC3, BB2, BB2
+	VPSLLD   $7, BB3, CC3; VPSRLD $25, BB3, BB3; VPXOR CC3, BB3, BB3
+	VMOVDQA  tmpStoreAVX2, CC3
+	polyMulReduceStage
+	VPALIGNR $12, BB0, BB0, BB0; VPALIGNR $12, BB1, BB1, BB1; VPALIGNR $12, BB2, BB2, BB2; VPALIGNR $12, BB3, BB3, BB3
+	VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $8, CC2, CC2, CC2; VPALIGNR $8, CC3, CC3, CC3
+	VPALIGNR $4, DD0, DD0, DD0; VPALIGNR $4, DD1, DD1, DD1; VPALIGNR $4, DD2, DD2, DD2; VPALIGNR $4, DD3, DD3, DD3
+	DECQ     itr1
+	JNE      sealAVX2InternalLoop
+
+	VPADDD  ·chacha20Constants<>(SB), AA0, AA0; VPADDD ·chacha20Constants<>(SB), AA1, AA1; VPADDD ·chacha20Constants<>(SB), AA2, AA2; VPADDD ·chacha20Constants<>(SB), AA3, AA3
+	VPADDD  state1StoreAVX2, BB0, BB0; VPADDD state1StoreAVX2, BB1, BB1; VPADDD state1StoreAVX2, BB2, BB2; VPADDD state1StoreAVX2, BB3, BB3
+	VPADDD  state2StoreAVX2, CC0, CC0; VPADDD state2StoreAVX2, CC1, CC1; VPADDD state2StoreAVX2, CC2, CC2; VPADDD state2StoreAVX2, CC3, CC3
+	VPADDD  ctr0StoreAVX2, DD0, DD0; VPADDD ctr1StoreAVX2, DD1, DD1; VPADDD ctr2StoreAVX2, DD2, DD2; VPADDD ctr3StoreAVX2, DD3, DD3
+	VMOVDQA CC3, tmpStoreAVX2
+
+	// We only hashed 480 of the 512 bytes available - hash the remaining 32 here
+	polyAdd(0*8(oup))
+	polyMulAVX2
+	LEAQ       (4*8)(oup), oup
+	VPERM2I128 $0x02, AA0, BB0, CC3; VPERM2I128 $0x13, AA0, BB0, BB0; VPERM2I128 $0x02, CC0, DD0, AA0; VPERM2I128 $0x13, CC0, DD0, CC0
+	VPXOR      (0*32)(inp), CC3, CC3; VPXOR (1*32)(inp), AA0, AA0; VPXOR (2*32)(inp), BB0, BB0; VPXOR (3*32)(inp), CC0, CC0
+	VMOVDQU    CC3, (0*32)(oup); VMOVDQU AA0, (1*32)(oup); VMOVDQU BB0, (2*32)(oup); VMOVDQU CC0, (3*32)(oup)
+	VPERM2I128 $0x02, AA1, BB1, AA0; VPERM2I128 $0x02, CC1, DD1, BB0; VPERM2I128 $0x13, AA1, BB1, CC0; VPERM2I128 $0x13, CC1, DD1, DD0
+	VPXOR      (4*32)(inp), AA0, AA0; VPXOR (5*32)(inp), BB0, BB0; VPXOR (6*32)(inp), CC0, CC0; VPXOR (7*32)(inp), DD0, DD0
+	VMOVDQU    AA0, (4*32)(oup); VMOVDQU BB0, (5*32)(oup); VMOVDQU CC0, (6*32)(oup); VMOVDQU DD0, (7*32)(oup)
+
+	// and here
+	polyAdd(-2*8(oup))
+	polyMulAVX2
+	VPERM2I128 $0x02, AA2, BB2, AA0; VPERM2I128 $0x02, CC2, DD2, BB0; VPERM2I128 $0x13, AA2, BB2, CC0; VPERM2I128 $0x13, CC2, DD2, DD0
+	VPXOR      (8*32)(inp), AA0, AA0; VPXOR (9*32)(inp), BB0, BB0; VPXOR (10*32)(inp), CC0, CC0; VPXOR (11*32)(inp), DD0, DD0
+	VMOVDQU    AA0, (8*32)(oup); VMOVDQU BB0, (9*32)(oup); VMOVDQU CC0, (10*32)(oup); VMOVDQU DD0, (11*32)(oup)
+	VPERM2I128 $0x02, AA3, BB3, AA0; VPERM2I128 $0x02, tmpStoreAVX2, DD3, BB0; VPERM2I128 $0x13, AA3, BB3, CC0; VPERM2I128 $0x13, tmpStoreAVX2, DD3, DD0
+	VPXOR      (12*32)(inp), AA0, AA0; VPXOR (13*32)(inp), BB0, BB0; VPXOR (14*32)(inp), CC0, CC0; VPXOR (15*32)(inp), DD0, DD0
+	VMOVDQU    AA0, (12*32)(oup); VMOVDQU BB0, (13*32)(oup); VMOVDQU CC0, (14*32)(oup); VMOVDQU DD0, (15*32)(oup)
+	LEAQ       (32*16)(inp), inp
+	SUBQ       $(32*16), inl
+	CMPQ       inl, $512
+	JG         sealAVX2MainLoop
+
+	// Tail can only hash 480 bytes
+	polyAdd(0*8(oup))
+	polyMulAVX2
+	polyAdd(2*8(oup))
+	polyMulAVX2
+	LEAQ 32(oup), oup
+
+	MOVQ $10, itr1
+	MOVQ $0, itr2
+	CMPQ inl, $128
+	JBE  sealAVX2Tail128
+	CMPQ inl, $256
+	JBE  sealAVX2Tail256
+	CMPQ inl, $384
+	JBE  sealAVX2Tail384
+	JMP  sealAVX2Tail512
+
+// ----------------------------------------------------------------------------
+// Special optimization for buffers smaller than 193 bytes
+seal192AVX2:
+	// For up to 192 bytes of ciphertext and 64 bytes for the poly key, we process four blocks
+	VMOVDQA AA0, AA1
+	VMOVDQA BB0, BB1
+	VMOVDQA CC0, CC1
+	VPADDD  ·avx2IncMask<>(SB), DD0, DD1
+	VMOVDQA AA0, AA2
+	VMOVDQA BB0, BB2
+	VMOVDQA CC0, CC2
+	VMOVDQA DD0, DD2
+	VMOVDQA DD1, TT3
+	MOVQ    $10, itr2
+
+sealAVX2192InnerCipherLoop:
+	chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0); chachaQR_AVX2(AA1, BB1, CC1, DD1, TT0)
+	VPALIGNR   $4, BB0, BB0, BB0; VPALIGNR $4, BB1, BB1, BB1
+	VPALIGNR   $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1
+	VPALIGNR   $12, DD0, DD0, DD0; VPALIGNR $12, DD1, DD1, DD1
+	chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0); chachaQR_AVX2(AA1, BB1, CC1, DD1, TT0)
+	VPALIGNR   $12, BB0, BB0, BB0; VPALIGNR $12, BB1, BB1, BB1
+	VPALIGNR   $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1
+	VPALIGNR   $4, DD0, DD0, DD0; VPALIGNR $4, DD1, DD1, DD1
+	DECQ       itr2
+	JNE        sealAVX2192InnerCipherLoop
+	VPADDD     AA2, AA0, AA0; VPADDD AA2, AA1, AA1
+	VPADDD     BB2, BB0, BB0; VPADDD BB2, BB1, BB1
+	VPADDD     CC2, CC0, CC0; VPADDD CC2, CC1, CC1
+	VPADDD     DD2, DD0, DD0; VPADDD TT3, DD1, DD1
+	VPERM2I128 $0x02, AA0, BB0, TT0
+
+	// Clamp and store poly key
+	VPAND   ·polyClampMask<>(SB), TT0, TT0
+	VMOVDQA TT0, rsStoreAVX2
+
+	// Stream for up to 192 bytes
+	VPERM2I128 $0x13, AA0, BB0, AA0
+	VPERM2I128 $0x13, CC0, DD0, BB0
+	VPERM2I128 $0x02, AA1, BB1, CC0
+	VPERM2I128 $0x02, CC1, DD1, DD0
+	VPERM2I128 $0x13, AA1, BB1, AA1
+	VPERM2I128 $0x13, CC1, DD1, BB1
+
+sealAVX2ShortSeal:
+	// Hash aad
+	MOVQ ad_len+80(FP), itr2
+	CALL polyHashADInternal<>(SB)
+	XORQ itr1, itr1
+
+sealAVX2SealHash:
+	// itr1 holds the number of bytes encrypted but not yet hashed
+	CMPQ itr1, $16
+	JB   sealAVX2ShortSealLoop
+	polyAdd(0(oup))
+	polyMul
+	SUBQ $16, itr1
+	ADDQ $16, oup
+	JMP  sealAVX2SealHash
+
+sealAVX2ShortSealLoop:
+	CMPQ inl, $32
+	JB   sealAVX2ShortTail32
+	SUBQ $32, inl
+
+	// Load for encryption
+	VPXOR   (inp), AA0, AA0
+	VMOVDQU AA0, (oup)
+	LEAQ    (1*32)(inp), inp
+
+	// Now can hash
+	polyAdd(0*8(oup))
+	polyMulAVX2
+	polyAdd(2*8(oup))
+	polyMulAVX2
+	LEAQ (1*32)(oup), oup
+
+	// Shift stream left
+	VMOVDQA BB0, AA0
+	VMOVDQA CC0, BB0
+	VMOVDQA DD0, CC0
+	VMOVDQA AA1, DD0
+	VMOVDQA BB1, AA1
+	VMOVDQA CC1, BB1
+	VMOVDQA DD1, CC1
+	VMOVDQA AA2, DD1
+	VMOVDQA BB2, AA2
+	JMP     sealAVX2ShortSealLoop
+
+sealAVX2ShortTail32:
+	CMPQ    inl, $16
+	VMOVDQA A0, A1
+	JB      sealAVX2ShortDone
+
+	SUBQ $16, inl
+
+	// Load for encryption
+	VPXOR   (inp), A0, T0
+	VMOVDQU T0, (oup)
+	LEAQ    (1*16)(inp), inp
+
+	// Hash
+	polyAdd(0*8(oup))
+	polyMulAVX2
+	LEAQ       (1*16)(oup), oup
+	VPERM2I128 $0x11, AA0, AA0, AA0
+	VMOVDQA    A0, A1
+
+sealAVX2ShortDone:
+	VZEROUPPER
+	JMP sealSSETail
+
+// ----------------------------------------------------------------------------
+// Special optimization for buffers smaller than 321 bytes
+seal320AVX2:
+	// For up to 320 bytes of ciphertext and 64 bytes for the poly key, we process six blocks
+	VMOVDQA AA0, AA1; VMOVDQA BB0, BB1; VMOVDQA CC0, CC1; VPADDD ·avx2IncMask<>(SB), DD0, DD1
+	VMOVDQA AA0, AA2; VMOVDQA BB0, BB2; VMOVDQA CC0, CC2; VPADDD ·avx2IncMask<>(SB), DD1, DD2
+	VMOVDQA BB0, TT1; VMOVDQA CC0, TT2; VMOVDQA DD0, TT3
+	MOVQ    $10, itr2
+
+sealAVX2320InnerCipherLoop:
+	chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0); chachaQR_AVX2(AA1, BB1, CC1, DD1, TT0); chachaQR_AVX2(AA2, BB2, CC2, DD2, TT0)
+	VPALIGNR $4, BB0, BB0, BB0; VPALIGNR $4, BB1, BB1, BB1; VPALIGNR $4, BB2, BB2, BB2
+	VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $8, CC2, CC2, CC2
+	VPALIGNR $12, DD0, DD0, DD0; VPALIGNR $12, DD1, DD1, DD1; VPALIGNR $12, DD2, DD2, DD2
+	chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0); chachaQR_AVX2(AA1, BB1, CC1, DD1, TT0); chachaQR_AVX2(AA2, BB2, CC2, DD2, TT0)
+	VPALIGNR $12, BB0, BB0, BB0; VPALIGNR $12, BB1, BB1, BB1; VPALIGNR $12, BB2, BB2, BB2
+	VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $8, CC2, CC2, CC2
+	VPALIGNR $4, DD0, DD0, DD0; VPALIGNR $4, DD1, DD1, DD1; VPALIGNR $4, DD2, DD2, DD2
+	DECQ     itr2
+	JNE      sealAVX2320InnerCipherLoop
+
+	VMOVDQA ·chacha20Constants<>(SB), TT0
+	VPADDD  TT0, AA0, AA0; VPADDD TT0, AA1, AA1; VPADDD TT0, AA2, AA2
+	VPADDD  TT1, BB0, BB0; VPADDD TT1, BB1, BB1; VPADDD TT1, BB2, BB2
+	VPADDD  TT2, CC0, CC0; VPADDD TT2, CC1, CC1; VPADDD TT2, CC2, CC2
+	VMOVDQA ·avx2IncMask<>(SB), TT0
+	VPADDD  TT3, DD0, DD0; VPADDD TT0, TT3, TT3
+	VPADDD  TT3, DD1, DD1; VPADDD TT0, TT3, TT3
+	VPADDD  TT3, DD2, DD2
+
+	// Clamp and store poly key
+	VPERM2I128 $0x02, AA0, BB0, TT0
+	VPAND      ·polyClampMask<>(SB), TT0, TT0
+	VMOVDQA    TT0, rsStoreAVX2
+
+	// Stream for up to 320 bytes
+	VPERM2I128 $0x13, AA0, BB0, AA0
+	VPERM2I128 $0x13, CC0, DD0, BB0
+	VPERM2I128 $0x02, AA1, BB1, CC0
+	VPERM2I128 $0x02, CC1, DD1, DD0
+	VPERM2I128 $0x13, AA1, BB1, AA1
+	VPERM2I128 $0x13, CC1, DD1, BB1
+	VPERM2I128 $0x02, AA2, BB2, CC1
+	VPERM2I128 $0x02, CC2, DD2, DD1
+	VPERM2I128 $0x13, AA2, BB2, AA2
+	VPERM2I128 $0x13, CC2, DD2, BB2
+	JMP        sealAVX2ShortSeal
+
+// ----------------------------------------------------------------------------
+// Special optimization for the last 128 bytes of ciphertext
+sealAVX2Tail128:
+	// Need to decrypt up to 128 bytes - prepare two blocks
+	// If we got here after the main loop - there are 512 encrypted bytes waiting to be hashed
+	// If we got here before the main loop - there are 448 encrpyred bytes waiting to be hashed
+	VMOVDQA ·chacha20Constants<>(SB), AA0
+	VMOVDQA state1StoreAVX2, BB0
+	VMOVDQA state2StoreAVX2, CC0
+	VMOVDQA ctr3StoreAVX2, DD0
+	VPADDD  ·avx2IncMask<>(SB), DD0, DD0
+	VMOVDQA DD0, DD1
+
+sealAVX2Tail128LoopA:
+	polyAdd(0(oup))
+	polyMul
+	LEAQ 16(oup), oup
+
+sealAVX2Tail128LoopB:
+	chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0)
+	polyAdd(0(oup))
+	polyMul
+	VPALIGNR $4, BB0, BB0, BB0
+	VPALIGNR $8, CC0, CC0, CC0
+	VPALIGNR $12, DD0, DD0, DD0
+	chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0)
+	polyAdd(16(oup))
+	polyMul
+	LEAQ     32(oup), oup
+	VPALIGNR $12, BB0, BB0, BB0
+	VPALIGNR $8, CC0, CC0, CC0
+	VPALIGNR $4, DD0, DD0, DD0
+	DECQ     itr1
+	JG       sealAVX2Tail128LoopA
+	DECQ     itr2
+	JGE      sealAVX2Tail128LoopB
+
+	VPADDD ·chacha20Constants<>(SB), AA0, AA1
+	VPADDD state1StoreAVX2, BB0, BB1
+	VPADDD state2StoreAVX2, CC0, CC1
+	VPADDD DD1, DD0, DD1
+
+	VPERM2I128 $0x02, AA1, BB1, AA0
+	VPERM2I128 $0x02, CC1, DD1, BB0
+	VPERM2I128 $0x13, AA1, BB1, CC0
+	VPERM2I128 $0x13, CC1, DD1, DD0
+	JMP        sealAVX2ShortSealLoop
+
+// ----------------------------------------------------------------------------
+// Special optimization for the last 256 bytes of ciphertext
+sealAVX2Tail256:
+	// Need to decrypt up to 256 bytes - prepare two blocks
+	// If we got here after the main loop - there are 512 encrypted bytes waiting to be hashed
+	// If we got here before the main loop - there are 448 encrpyred bytes waiting to be hashed
+	VMOVDQA ·chacha20Constants<>(SB), AA0; VMOVDQA ·chacha20Constants<>(SB), AA1
+	VMOVDQA state1StoreAVX2, BB0; VMOVDQA state1StoreAVX2, BB1
+	VMOVDQA state2StoreAVX2, CC0; VMOVDQA state2StoreAVX2, CC1
+	VMOVDQA ctr3StoreAVX2, DD0
+	VPADDD  ·avx2IncMask<>(SB), DD0, DD0
+	VPADDD  ·avx2IncMask<>(SB), DD0, DD1
+	VMOVDQA DD0, TT1
+	VMOVDQA DD1, TT2
+
+sealAVX2Tail256LoopA:
+	polyAdd(0(oup))
+	polyMul
+	LEAQ 16(oup), oup
+
+sealAVX2Tail256LoopB:
+	chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0); chachaQR_AVX2(AA1, BB1, CC1, DD1, TT0)
+	polyAdd(0(oup))
+	polyMul
+	VPALIGNR $4, BB0, BB0, BB0; VPALIGNR $4, BB1, BB1, BB1
+	VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1
+	VPALIGNR $12, DD0, DD0, DD0; VPALIGNR $12, DD1, DD1, DD1
+	chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0); chachaQR_AVX2(AA1, BB1, CC1, DD1, TT0)
+	polyAdd(16(oup))
+	polyMul
+	LEAQ     32(oup), oup
+	VPALIGNR $12, BB0, BB0, BB0; VPALIGNR $12, BB1, BB1, BB1
+	VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1
+	VPALIGNR $4, DD0, DD0, DD0; VPALIGNR $4, DD1, DD1, DD1
+	DECQ     itr1
+	JG       sealAVX2Tail256LoopA
+	DECQ     itr2
+	JGE      sealAVX2Tail256LoopB
+
+	VPADDD     ·chacha20Constants<>(SB), AA0, AA0; VPADDD ·chacha20Constants<>(SB), AA1, AA1
+	VPADDD     state1StoreAVX2, BB0, BB0; VPADDD state1StoreAVX2, BB1, BB1
+	VPADDD     state2StoreAVX2, CC0, CC0; VPADDD state2StoreAVX2, CC1, CC1
+	VPADDD     TT1, DD0, DD0; VPADDD TT2, DD1, DD1
+	VPERM2I128 $0x02, AA0, BB0, TT0
+	VPERM2I128 $0x02, CC0, DD0, TT1
+	VPERM2I128 $0x13, AA0, BB0, TT2
+	VPERM2I128 $0x13, CC0, DD0, TT3
+	VPXOR      (0*32)(inp), TT0, TT0; VPXOR (1*32)(inp), TT1, TT1; VPXOR (2*32)(inp), TT2, TT2; VPXOR (3*32)(inp), TT3, TT3
+	VMOVDQU    TT0, (0*32)(oup); VMOVDQU TT1, (1*32)(oup); VMOVDQU TT2, (2*32)(oup); VMOVDQU TT3, (3*32)(oup)
+	MOVQ       $128, itr1
+	LEAQ       128(inp), inp
+	SUBQ       $128, inl
+	VPERM2I128 $0x02, AA1, BB1, AA0
+	VPERM2I128 $0x02, CC1, DD1, BB0
+	VPERM2I128 $0x13, AA1, BB1, CC0
+	VPERM2I128 $0x13, CC1, DD1, DD0
+
+	JMP sealAVX2SealHash
+
+// ----------------------------------------------------------------------------
+// Special optimization for the last 384 bytes of ciphertext
+sealAVX2Tail384:
+	// Need to decrypt up to 384 bytes - prepare two blocks
+	// If we got here after the main loop - there are 512 encrypted bytes waiting to be hashed
+	// If we got here before the main loop - there are 448 encrpyred bytes waiting to be hashed
+	VMOVDQA ·chacha20Constants<>(SB), AA0; VMOVDQA AA0, AA1; VMOVDQA AA0, AA2
+	VMOVDQA state1StoreAVX2, BB0; VMOVDQA BB0, BB1; VMOVDQA BB0, BB2
+	VMOVDQA state2StoreAVX2, CC0; VMOVDQA CC0, CC1; VMOVDQA CC0, CC2
+	VMOVDQA ctr3StoreAVX2, DD0
+	VPADDD  ·avx2IncMask<>(SB), DD0, DD0; VPADDD ·avx2IncMask<>(SB), DD0, DD1; VPADDD ·avx2IncMask<>(SB), DD1, DD2
+	VMOVDQA DD0, TT1; VMOVDQA DD1, TT2; VMOVDQA DD2, TT3
+
+sealAVX2Tail384LoopA:
+	polyAdd(0(oup))
+	polyMul
+	LEAQ 16(oup), oup
+
+sealAVX2Tail384LoopB:
+	chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0); chachaQR_AVX2(AA1, BB1, CC1, DD1, TT0); chachaQR_AVX2(AA2, BB2, CC2, DD2, TT0)
+	polyAdd(0(oup))
+	polyMul
+	VPALIGNR $4, BB0, BB0, BB0; VPALIGNR $4, BB1, BB1, BB1; VPALIGNR $4, BB2, BB2, BB2
+	VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $8, CC2, CC2, CC2
+	VPALIGNR $12, DD0, DD0, DD0; VPALIGNR $12, DD1, DD1, DD1; VPALIGNR $12, DD2, DD2, DD2
+	chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0); chachaQR_AVX2(AA1, BB1, CC1, DD1, TT0); chachaQR_AVX2(AA2, BB2, CC2, DD2, TT0)
+	polyAdd(16(oup))
+	polyMul
+	LEAQ     32(oup), oup
+	VPALIGNR $12, BB0, BB0, BB0; VPALIGNR $12, BB1, BB1, BB1; VPALIGNR $12, BB2, BB2, BB2
+	VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $8, CC2, CC2, CC2
+	VPALIGNR $4, DD0, DD0, DD0; VPALIGNR $4, DD1, DD1, DD1; VPALIGNR $4, DD2, DD2, DD2
+	DECQ     itr1
+	JG       sealAVX2Tail384LoopA
+	DECQ     itr2
+	JGE      sealAVX2Tail384LoopB
+
+	VPADDD     ·chacha20Constants<>(SB), AA0, AA0; VPADDD ·chacha20Constants<>(SB), AA1, AA1; VPADDD ·chacha20Constants<>(SB), AA2, AA2
+	VPADDD     state1StoreAVX2, BB0, BB0; VPADDD state1StoreAVX2, BB1, BB1; VPADDD state1StoreAVX2, BB2, BB2
+	VPADDD     state2StoreAVX2, CC0, CC0; VPADDD state2StoreAVX2, CC1, CC1; VPADDD state2StoreAVX2, CC2, CC2
+	VPADDD     TT1, DD0, DD0; VPADDD TT2, DD1, DD1; VPADDD TT3, DD2, DD2
+	VPERM2I128 $0x02, AA0, BB0, TT0
+	VPERM2I128 $0x02, CC0, DD0, TT1
+	VPERM2I128 $0x13, AA0, BB0, TT2
+	VPERM2I128 $0x13, CC0, DD0, TT3
+	VPXOR      (0*32)(inp), TT0, TT0; VPXOR (1*32)(inp), TT1, TT1; VPXOR (2*32)(inp), TT2, TT2; VPXOR (3*32)(inp), TT3, TT3
+	VMOVDQU    TT0, (0*32)(oup); VMOVDQU TT1, (1*32)(oup); VMOVDQU TT2, (2*32)(oup); VMOVDQU TT3, (3*32)(oup)
+	VPERM2I128 $0x02, AA1, BB1, TT0
+	VPERM2I128 $0x02, CC1, DD1, TT1
+	VPERM2I128 $0x13, AA1, BB1, TT2
+	VPERM2I128 $0x13, CC1, DD1, TT3
+	VPXOR      (4*32)(inp), TT0, TT0; VPXOR (5*32)(inp), TT1, TT1; VPXOR (6*32)(inp), TT2, TT2; VPXOR (7*32)(inp), TT3, TT3
+	VMOVDQU    TT0, (4*32)(oup); VMOVDQU TT1, (5*32)(oup); VMOVDQU TT2, (6*32)(oup); VMOVDQU TT3, (7*32)(oup)
+	MOVQ       $256, itr1
+	LEAQ       256(inp), inp
+	SUBQ       $256, inl
+	VPERM2I128 $0x02, AA2, BB2, AA0
+	VPERM2I128 $0x02, CC2, DD2, BB0
+	VPERM2I128 $0x13, AA2, BB2, CC0
+	VPERM2I128 $0x13, CC2, DD2, DD0
+
+	JMP sealAVX2SealHash
+
+// ----------------------------------------------------------------------------
+// Special optimization for the last 512 bytes of ciphertext
+sealAVX2Tail512:
+	// Need to decrypt up to 512 bytes - prepare two blocks
+	// If we got here after the main loop - there are 512 encrypted bytes waiting to be hashed
+	// If we got here before the main loop - there are 448 encrpyred bytes waiting to be hashed
+	VMOVDQA ·chacha20Constants<>(SB), AA0; VMOVDQA AA0, AA1; VMOVDQA AA0, AA2; VMOVDQA AA0, AA3
+	VMOVDQA state1StoreAVX2, BB0; VMOVDQA BB0, BB1; VMOVDQA BB0, BB2; VMOVDQA BB0, BB3
+	VMOVDQA state2StoreAVX2, CC0; VMOVDQA CC0, CC1; VMOVDQA CC0, CC2; VMOVDQA CC0, CC3
+	VMOVDQA ctr3StoreAVX2, DD0
+	VPADDD  ·avx2IncMask<>(SB), DD0, DD0; VPADDD ·avx2IncMask<>(SB), DD0, DD1; VPADDD ·avx2IncMask<>(SB), DD1, DD2; VPADDD ·avx2IncMask<>(SB), DD2, DD3
+	VMOVDQA DD0, ctr0StoreAVX2; VMOVDQA DD1, ctr1StoreAVX2; VMOVDQA DD2, ctr2StoreAVX2; VMOVDQA DD3, ctr3StoreAVX2
+
+sealAVX2Tail512LoopA:
+	polyAdd(0(oup))
+	polyMul
+	LEAQ 16(oup), oup
+
+sealAVX2Tail512LoopB:
+	VPADDD   BB0, AA0, AA0; VPADDD BB1, AA1, AA1; VPADDD BB2, AA2, AA2; VPADDD BB3, AA3, AA3
+	VPXOR    AA0, DD0, DD0; VPXOR AA1, DD1, DD1; VPXOR AA2, DD2, DD2; VPXOR AA3, DD3, DD3
+	VPSHUFB  ·rol16<>(SB), DD0, DD0; VPSHUFB ·rol16<>(SB), DD1, DD1; VPSHUFB ·rol16<>(SB), DD2, DD2; VPSHUFB ·rol16<>(SB), DD3, DD3
+	VPADDD   DD0, CC0, CC0; VPADDD DD1, CC1, CC1; VPADDD DD2, CC2, CC2; VPADDD DD3, CC3, CC3
+	VPXOR    CC0, BB0, BB0; VPXOR CC1, BB1, BB1; VPXOR CC2, BB2, BB2; VPXOR CC3, BB3, BB3
+	VMOVDQA  CC3, tmpStoreAVX2
+	VPSLLD   $12, BB0, CC3; VPSRLD $20, BB0, BB0; VPXOR CC3, BB0, BB0
+	VPSLLD   $12, BB1, CC3; VPSRLD $20, BB1, BB1; VPXOR CC3, BB1, BB1
+	VPSLLD   $12, BB2, CC3; VPSRLD $20, BB2, BB2; VPXOR CC3, BB2, BB2
+	VPSLLD   $12, BB3, CC3; VPSRLD $20, BB3, BB3; VPXOR CC3, BB3, BB3
+	VMOVDQA  tmpStoreAVX2, CC3
+	polyAdd(0*8(oup))
+	polyMulAVX2
+	VPADDD   BB0, AA0, AA0; VPADDD BB1, AA1, AA1; VPADDD BB2, AA2, AA2; VPADDD BB3, AA3, AA3
+	VPXOR    AA0, DD0, DD0; VPXOR AA1, DD1, DD1; VPXOR AA2, DD2, DD2; VPXOR AA3, DD3, DD3
+	VPSHUFB  ·rol8<>(SB), DD0, DD0; VPSHUFB ·rol8<>(SB), DD1, DD1; VPSHUFB ·rol8<>(SB), DD2, DD2; VPSHUFB ·rol8<>(SB), DD3, DD3
+	VPADDD   DD0, CC0, CC0; VPADDD DD1, CC1, CC1; VPADDD DD2, CC2, CC2; VPADDD DD3, CC3, CC3
+	VPXOR    CC0, BB0, BB0; VPXOR CC1, BB1, BB1; VPXOR CC2, BB2, BB2; VPXOR CC3, BB3, BB3
+	VMOVDQA  CC3, tmpStoreAVX2
+	VPSLLD   $7, BB0, CC3; VPSRLD $25, BB0, BB0; VPXOR CC3, BB0, BB0
+	VPSLLD   $7, BB1, CC3; VPSRLD $25, BB1, BB1; VPXOR CC3, BB1, BB1
+	VPSLLD   $7, BB2, CC3; VPSRLD $25, BB2, BB2; VPXOR CC3, BB2, BB2
+	VPSLLD   $7, BB3, CC3; VPSRLD $25, BB3, BB3; VPXOR CC3, BB3, BB3
+	VMOVDQA  tmpStoreAVX2, CC3
+	VPALIGNR $4, BB0, BB0, BB0; VPALIGNR $4, BB1, BB1, BB1; VPALIGNR $4, BB2, BB2, BB2; VPALIGNR $4, BB3, BB3, BB3
+	VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $8, CC2, CC2, CC2; VPALIGNR $8, CC3, CC3, CC3
+	VPALIGNR $12, DD0, DD0, DD0; VPALIGNR $12, DD1, DD1, DD1; VPALIGNR $12, DD2, DD2, DD2; VPALIGNR $12, DD3, DD3, DD3
+	VPADDD   BB0, AA0, AA0; VPADDD BB1, AA1, AA1; VPADDD BB2, AA2, AA2; VPADDD BB3, AA3, AA3
+	VPXOR    AA0, DD0, DD0; VPXOR AA1, DD1, DD1; VPXOR AA2, DD2, DD2; VPXOR AA3, DD3, DD3
+	VPSHUFB  ·rol16<>(SB), DD0, DD0; VPSHUFB ·rol16<>(SB), DD1, DD1; VPSHUFB ·rol16<>(SB), DD2, DD2; VPSHUFB ·rol16<>(SB), DD3, DD3
+	VPADDD   DD0, CC0, CC0; VPADDD DD1, CC1, CC1; VPADDD DD2, CC2, CC2; VPADDD DD3, CC3, CC3
+	VPXOR    CC0, BB0, BB0; VPXOR CC1, BB1, BB1; VPXOR CC2, BB2, BB2; VPXOR CC3, BB3, BB3
+	polyAdd(2*8(oup))
+	polyMulAVX2
+	LEAQ     (4*8)(oup), oup
+	VMOVDQA  CC3, tmpStoreAVX2
+	VPSLLD   $12, BB0, CC3; VPSRLD $20, BB0, BB0; VPXOR CC3, BB0, BB0
+	VPSLLD   $12, BB1, CC3; VPSRLD $20, BB1, BB1; VPXOR CC3, BB1, BB1
+	VPSLLD   $12, BB2, CC3; VPSRLD $20, BB2, BB2; VPXOR CC3, BB2, BB2
+	VPSLLD   $12, BB3, CC3; VPSRLD $20, BB3, BB3; VPXOR CC3, BB3, BB3
+	VMOVDQA  tmpStoreAVX2, CC3
+	VPADDD   BB0, AA0, AA0; VPADDD BB1, AA1, AA1; VPADDD BB2, AA2, AA2; VPADDD BB3, AA3, AA3
+	VPXOR    AA0, DD0, DD0; VPXOR AA1, DD1, DD1; VPXOR AA2, DD2, DD2; VPXOR AA3, DD3, DD3
+	VPSHUFB  ·rol8<>(SB), DD0, DD0; VPSHUFB ·rol8<>(SB), DD1, DD1; VPSHUFB ·rol8<>(SB), DD2, DD2; VPSHUFB ·rol8<>(SB), DD3, DD3
+	VPADDD   DD0, CC0, CC0; VPADDD DD1, CC1, CC1; VPADDD DD2, CC2, CC2; VPADDD DD3, CC3, CC3
+	VPXOR    CC0, BB0, BB0; VPXOR CC1, BB1, BB1; VPXOR CC2, BB2, BB2; VPXOR CC3, BB3, BB3
+	VMOVDQA  CC3, tmpStoreAVX2
+	VPSLLD   $7, BB0, CC3; VPSRLD $25, BB0, BB0; VPXOR CC3, BB0, BB0
+	VPSLLD   $7, BB1, CC3; VPSRLD $25, BB1, BB1; VPXOR CC3, BB1, BB1
+	VPSLLD   $7, BB2, CC3; VPSRLD $25, BB2, BB2; VPXOR CC3, BB2, BB2
+	VPSLLD   $7, BB3, CC3; VPSRLD $25, BB3, BB3; VPXOR CC3, BB3, BB3
+	VMOVDQA  tmpStoreAVX2, CC3
+	VPALIGNR $12, BB0, BB0, BB0; VPALIGNR $12, BB1, BB1, BB1; VPALIGNR $12, BB2, BB2, BB2; VPALIGNR $12, BB3, BB3, BB3
+	VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $8, CC2, CC2, CC2; VPALIGNR $8, CC3, CC3, CC3
+	VPALIGNR $4, DD0, DD0, DD0; VPALIGNR $4, DD1, DD1, DD1; VPALIGNR $4, DD2, DD2, DD2; VPALIGNR $4, DD3, DD3, DD3
+
+	DECQ itr1
+	JG   sealAVX2Tail512LoopA
+	DECQ itr2
+	JGE  sealAVX2Tail512LoopB
+
+	VPADDD     ·chacha20Constants<>(SB), AA0, AA0; VPADDD ·chacha20Constants<>(SB), AA1, AA1; VPADDD ·chacha20Constants<>(SB), AA2, AA2; VPADDD ·chacha20Constants<>(SB), AA3, AA3
+	VPADDD     state1StoreAVX2, BB0, BB0; VPADDD state1StoreAVX2, BB1, BB1; VPADDD state1StoreAVX2, BB2, BB2; VPADDD state1StoreAVX2, BB3, BB3
+	VPADDD     state2StoreAVX2, CC0, CC0; VPADDD state2StoreAVX2, CC1, CC1; VPADDD state2StoreAVX2, CC2, CC2; VPADDD state2StoreAVX2, CC3, CC3
+	VPADDD     ctr0StoreAVX2, DD0, DD0; VPADDD ctr1StoreAVX2, DD1, DD1; VPADDD ctr2StoreAVX2, DD2, DD2; VPADDD ctr3StoreAVX2, DD3, DD3
+	VMOVDQA    CC3, tmpStoreAVX2
+	VPERM2I128 $0x02, AA0, BB0, CC3
+	VPXOR      (0*32)(inp), CC3, CC3
+	VMOVDQU    CC3, (0*32)(oup)
+	VPERM2I128 $0x02, CC0, DD0, CC3
+	VPXOR      (1*32)(inp), CC3, CC3
+	VMOVDQU    CC3, (1*32)(oup)
+	VPERM2I128 $0x13, AA0, BB0, CC3
+	VPXOR      (2*32)(inp), CC3, CC3
+	VMOVDQU    CC3, (2*32)(oup)
+	VPERM2I128 $0x13, CC0, DD0, CC3
+	VPXOR      (3*32)(inp), CC3, CC3
+	VMOVDQU    CC3, (3*32)(oup)
+
+	VPERM2I128 $0x02, AA1, BB1, AA0
+	VPERM2I128 $0x02, CC1, DD1, BB0
+	VPERM2I128 $0x13, AA1, BB1, CC0
+	VPERM2I128 $0x13, CC1, DD1, DD0
+	VPXOR      (4*32)(inp), AA0, AA0; VPXOR (5*32)(inp), BB0, BB0; VPXOR (6*32)(inp), CC0, CC0; VPXOR (7*32)(inp), DD0, DD0
+	VMOVDQU    AA0, (4*32)(oup); VMOVDQU BB0, (5*32)(oup); VMOVDQU CC0, (6*32)(oup); VMOVDQU DD0, (7*32)(oup)
+
+	VPERM2I128 $0x02, AA2, BB2, AA0
+	VPERM2I128 $0x02, CC2, DD2, BB0
+	VPERM2I128 $0x13, AA2, BB2, CC0
+	VPERM2I128 $0x13, CC2, DD2, DD0
+	VPXOR      (8*32)(inp), AA0, AA0; VPXOR (9*32)(inp), BB0, BB0; VPXOR (10*32)(inp), CC0, CC0; VPXOR (11*32)(inp), DD0, DD0
+	VMOVDQU    AA0, (8*32)(oup); VMOVDQU BB0, (9*32)(oup); VMOVDQU CC0, (10*32)(oup); VMOVDQU DD0, (11*32)(oup)
+
+	MOVQ       $384, itr1
+	LEAQ       384(inp), inp
+	SUBQ       $384, inl
+	VPERM2I128 $0x02, AA3, BB3, AA0
+	VPERM2I128 $0x02, tmpStoreAVX2, DD3, BB0
+	VPERM2I128 $0x13, AA3, BB3, CC0
+	VPERM2I128 $0x13, tmpStoreAVX2, DD3, DD0
+
+	JMP sealAVX2SealHash
diff --git a/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_generic.go b/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_generic.go
new file mode 100644
index 0000000000..96b2fd898b
--- /dev/null
+++ b/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_generic.go
@@ -0,0 +1,81 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package chacha20poly1305
+
+import (
+	"encoding/binary"
+
+	"golang.org/x/crypto/chacha20"
+	"golang.org/x/crypto/internal/poly1305"
+	"golang.org/x/crypto/internal/subtle"
+)
+
+func writeWithPadding(p *poly1305.MAC, b []byte) {
+	p.Write(b)
+	if rem := len(b) % 16; rem != 0 {
+		var buf [16]byte
+		padLen := 16 - rem
+		p.Write(buf[:padLen])
+	}
+}
+
+func writeUint64(p *poly1305.MAC, n int) {
+	var buf [8]byte
+	binary.LittleEndian.PutUint64(buf[:], uint64(n))
+	p.Write(buf[:])
+}
+
+func (c *chacha20poly1305) sealGeneric(dst, nonce, plaintext, additionalData []byte) []byte {
+	ret, out := sliceForAppend(dst, len(plaintext)+poly1305.TagSize)
+	ciphertext, tag := out[:len(plaintext)], out[len(plaintext):]
+	if subtle.InexactOverlap(out, plaintext) {
+		panic("chacha20poly1305: invalid buffer overlap")
+	}
+
+	var polyKey [32]byte
+	s, _ := chacha20.NewUnauthenticatedCipher(c.key[:], nonce)
+	s.XORKeyStream(polyKey[:], polyKey[:])
+	s.SetCounter(1) // set the counter to 1, skipping 32 bytes
+	s.XORKeyStream(ciphertext, plaintext)
+
+	p := poly1305.New(&polyKey)
+	writeWithPadding(p, additionalData)
+	writeWithPadding(p, ciphertext)
+	writeUint64(p, len(additionalData))
+	writeUint64(p, len(plaintext))
+	p.Sum(tag[:0])
+
+	return ret
+}
+
+func (c *chacha20poly1305) openGeneric(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) {
+	tag := ciphertext[len(ciphertext)-16:]
+	ciphertext = ciphertext[:len(ciphertext)-16]
+
+	var polyKey [32]byte
+	s, _ := chacha20.NewUnauthenticatedCipher(c.key[:], nonce)
+	s.XORKeyStream(polyKey[:], polyKey[:])
+	s.SetCounter(1) // set the counter to 1, skipping 32 bytes
+
+	p := poly1305.New(&polyKey)
+	writeWithPadding(p, additionalData)
+	writeWithPadding(p, ciphertext)
+	writeUint64(p, len(additionalData))
+	writeUint64(p, len(ciphertext))
+
+	ret, out := sliceForAppend(dst, len(ciphertext))
+	if subtle.InexactOverlap(out, ciphertext) {
+		panic("chacha20poly1305: invalid buffer overlap")
+	}
+	if !p.Verify(tag) {
+		for i := range out {
+			out[i] = 0
+		}
+		return nil, errOpen
+	}
+
+	s.XORKeyStream(out, ciphertext)
+	return ret, nil
+}
diff --git a/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_noasm.go b/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_noasm.go
new file mode 100644
index 0000000000..f832b33d45
--- /dev/null
+++ b/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_noasm.go
@@ -0,0 +1,16 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !amd64 || !gc || purego
+// +build !amd64 !gc purego
+
+package chacha20poly1305
+
+func (c *chacha20poly1305) seal(dst, nonce, plaintext, additionalData []byte) []byte {
+	return c.sealGeneric(dst, nonce, plaintext, additionalData)
+}
+
+func (c *chacha20poly1305) open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) {
+	return c.openGeneric(dst, nonce, ciphertext, additionalData)
+}
diff --git a/vendor/golang.org/x/crypto/chacha20poly1305/xchacha20poly1305.go b/vendor/golang.org/x/crypto/chacha20poly1305/xchacha20poly1305.go
new file mode 100644
index 0000000000..1cebfe946f
--- /dev/null
+++ b/vendor/golang.org/x/crypto/chacha20poly1305/xchacha20poly1305.go
@@ -0,0 +1,86 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package chacha20poly1305
+
+import (
+	"crypto/cipher"
+	"errors"
+
+	"golang.org/x/crypto/chacha20"
+)
+
+type xchacha20poly1305 struct {
+	key [KeySize]byte
+}
+
+// NewX returns a XChaCha20-Poly1305 AEAD that uses the given 256-bit key.
+//
+// XChaCha20-Poly1305 is a ChaCha20-Poly1305 variant that takes a longer nonce,
+// suitable to be generated randomly without risk of collisions. It should be
+// preferred when nonce uniqueness cannot be trivially ensured, or whenever
+// nonces are randomly generated.
+func NewX(key []byte) (cipher.AEAD, error) {
+	if len(key) != KeySize {
+		return nil, errors.New("chacha20poly1305: bad key length")
+	}
+	ret := new(xchacha20poly1305)
+	copy(ret.key[:], key)
+	return ret, nil
+}
+
+func (*xchacha20poly1305) NonceSize() int {
+	return NonceSizeX
+}
+
+func (*xchacha20poly1305) Overhead() int {
+	return Overhead
+}
+
+func (x *xchacha20poly1305) Seal(dst, nonce, plaintext, additionalData []byte) []byte {
+	if len(nonce) != NonceSizeX {
+		panic("chacha20poly1305: bad nonce length passed to Seal")
+	}
+
+	// XChaCha20-Poly1305 technically supports a 64-bit counter, so there is no
+	// size limit. However, since we reuse the ChaCha20-Poly1305 implementation,
+	// the second half of the counter is not available. This is unlikely to be
+	// an issue because the cipher.AEAD API requires the entire message to be in
+	// memory, and the counter overflows at 256 GB.
+	if uint64(len(plaintext)) > (1<<38)-64 {
+		panic("chacha20poly1305: plaintext too large")
+	}
+
+	c := new(chacha20poly1305)
+	hKey, _ := chacha20.HChaCha20(x.key[:], nonce[0:16])
+	copy(c.key[:], hKey)
+
+	// The first 4 bytes of the final nonce are unused counter space.
+	cNonce := make([]byte, NonceSize)
+	copy(cNonce[4:12], nonce[16:24])
+
+	return c.seal(dst, cNonce[:], plaintext, additionalData)
+}
+
+func (x *xchacha20poly1305) Open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) {
+	if len(nonce) != NonceSizeX {
+		panic("chacha20poly1305: bad nonce length passed to Open")
+	}
+	if len(ciphertext) < 16 {
+		return nil, errOpen
+	}
+	if uint64(len(ciphertext)) > (1<<38)-48 {
+		panic("chacha20poly1305: ciphertext too large")
+	}
+
+	c := new(chacha20poly1305)
+	hKey, _ := chacha20.HChaCha20(x.key[:], nonce[0:16])
+	copy(c.key[:], hKey)
+
+	// The first 4 bytes of the final nonce are unused counter space.
+	cNonce := make([]byte, NonceSize)
+	copy(cNonce[4:12], nonce[16:24])
+
+	return c.open(dst, cNonce[:], ciphertext, additionalData)
+}
diff --git a/vendor/golang.org/x/crypto/codereview.cfg b/vendor/golang.org/x/crypto/codereview.cfg
new file mode 100644
index 0000000000..3f8b14b64e
--- /dev/null
+++ b/vendor/golang.org/x/crypto/codereview.cfg
@@ -0,0 +1 @@
+issuerepo: golang/go
diff --git a/vendor/golang.org/x/crypto/cryptobyte/asn1.go b/vendor/golang.org/x/crypto/cryptobyte/asn1.go
index d3596ee66f..3a1674a1e5 100644
--- a/vendor/golang.org/x/crypto/cryptobyte/asn1.go
+++ b/vendor/golang.org/x/crypto/cryptobyte/asn1.go
@@ -117,6 +117,19 @@ func (b *Builder) AddASN1GeneralizedTime(t time.Time) {
 	})
 }
 
+// AddASN1UTCTime appends a DER-encoded ASN.1 UTCTime.
+func (b *Builder) AddASN1UTCTime(t time.Time) {
+	b.AddASN1(asn1.UTCTime, func(c *Builder) {
+		// As utilized by the X.509 profile, UTCTime can only
+		// represent the years 1950 through 2049.
+		if t.Year() < 1950 || t.Year() >= 2050 {
+			b.err = fmt.Errorf("cryptobyte: cannot represent %v as a UTCTime", t)
+			return
+		}
+		c.AddBytes([]byte(t.Format(defaultUTCTimeFormatStr)))
+	})
+}
+
 // AddASN1BitString appends a DER-encoded ASN.1 BIT STRING. This does not
 // support BIT STRINGs that are not a whole number of bytes.
 func (b *Builder) AddASN1BitString(data []byte) {
@@ -394,7 +407,12 @@ func (s *String) ReadASN1Enum(out *int) bool {
 func (s *String) readBase128Int(out *int) bool {
 	ret := 0
 	for i := 0; len(*s) > 0; i++ {
-		if i == 4 {
+		if i == 5 {
+			return false
+		}
+		// Avoid overflowing int on a 32-bit platform.
+		// We don't want different behavior based on the architecture.
+		if ret >= 1<<(31-7) {
 			return false
 		}
 		ret <<= 7
@@ -466,6 +484,45 @@ func (s *String) ReadASN1GeneralizedTime(out *time.Time) bool {
 	return true
 }
 
+const defaultUTCTimeFormatStr = "060102150405Z0700"
+
+// ReadASN1UTCTime decodes an ASN.1 UTCTime into out and advances.
+// It reports whether the read was successful.
+func (s *String) ReadASN1UTCTime(out *time.Time) bool {
+	var bytes String
+	if !s.ReadASN1(&bytes, asn1.UTCTime) {
+		return false
+	}
+	t := string(bytes)
+
+	formatStr := defaultUTCTimeFormatStr
+	var err error
+	res, err := time.Parse(formatStr, t)
+	if err != nil {
+		// Fallback to minute precision if we can't parse second
+		// precision. If we are following X.509 or X.690 we shouldn't
+		// support this, but we do.
+		formatStr = "0601021504Z0700"
+		res, err = time.Parse(formatStr, t)
+	}
+	if err != nil {
+		return false
+	}
+
+	if serialized := res.Format(formatStr); serialized != t {
+		return false
+	}
+
+	if res.Year() >= 2050 {
+		// UTCTime interprets the low order digits 50-99 as 1950-99.
+		// This only applies to its use in the X.509 profile.
+		// See https://tools.ietf.org/html/rfc5280#section-4.1.2.5.1
+		res = res.AddDate(-100, 0, 0)
+	}
+	*out = res
+	return true
+}
+
 // ReadASN1BitString decodes an ASN.1 BIT STRING into out and advances.
 // It reports whether the read was successful.
 func (s *String) ReadASN1BitString(out *encoding_asn1.BitString) bool {
diff --git a/vendor/golang.org/x/crypto/curve25519/curve25519.go b/vendor/golang.org/x/crypto/curve25519/curve25519.go
index 4b9a655d1b..cda3fdd354 100644
--- a/vendor/golang.org/x/crypto/curve25519/curve25519.go
+++ b/vendor/golang.org/x/crypto/curve25519/curve25519.go
@@ -10,6 +10,8 @@ package curve25519 // import "golang.org/x/crypto/curve25519"
 import (
 	"crypto/subtle"
 	"fmt"
+
+	"golang.org/x/crypto/curve25519/internal/field"
 )
 
 // ScalarMult sets dst to the product scalar * point.
@@ -18,7 +20,55 @@ import (
 // zeroes, irrespective of the scalar. Instead, use the X25519 function, which
 // will return an error.
 func ScalarMult(dst, scalar, point *[32]byte) {
-	scalarMult(dst, scalar, point)
+	var e [32]byte
+
+	copy(e[:], scalar[:])
+	e[0] &= 248
+	e[31] &= 127
+	e[31] |= 64
+
+	var x1, x2, z2, x3, z3, tmp0, tmp1 field.Element
+	x1.SetBytes(point[:])
+	x2.One()
+	x3.Set(&x1)
+	z3.One()
+
+	swap := 0
+	for pos := 254; pos >= 0; pos-- {
+		b := e[pos/8] >> uint(pos&7)
+		b &= 1
+		swap ^= int(b)
+		x2.Swap(&x3, swap)
+		z2.Swap(&z3, swap)
+		swap = int(b)
+
+		tmp0.Subtract(&x3, &z3)
+		tmp1.Subtract(&x2, &z2)
+		x2.Add(&x2, &z2)
+		z2.Add(&x3, &z3)
+		z3.Multiply(&tmp0, &x2)
+		z2.Multiply(&z2, &tmp1)
+		tmp0.Square(&tmp1)
+		tmp1.Square(&x2)
+		x3.Add(&z3, &z2)
+		z2.Subtract(&z3, &z2)
+		x2.Multiply(&tmp1, &tmp0)
+		tmp1.Subtract(&tmp1, &tmp0)
+		z2.Square(&z2)
+
+		z3.Mult32(&tmp1, 121666)
+		x3.Square(&x3)
+		tmp0.Add(&tmp0, &z3)
+		z3.Multiply(&x1, &z2)
+		z2.Multiply(&tmp1, &tmp0)
+	}
+
+	x2.Swap(&x3, swap)
+	z2.Swap(&z3, swap)
+
+	z2.Invert(&z2)
+	x2.Multiply(&x2, &z2)
+	copy(dst[:], x2.Bytes())
 }
 
 // ScalarBaseMult sets dst to the product scalar * base where base is the
diff --git a/vendor/golang.org/x/crypto/curve25519/curve25519_amd64.go b/vendor/golang.org/x/crypto/curve25519/curve25519_amd64.go
deleted file mode 100644
index 5120b779b9..0000000000
--- a/vendor/golang.org/x/crypto/curve25519/curve25519_amd64.go
+++ /dev/null
@@ -1,240 +0,0 @@
-// 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,!purego
-
-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 */
-}
diff --git a/vendor/golang.org/x/crypto/curve25519/curve25519_amd64.s b/vendor/golang.org/x/crypto/curve25519/curve25519_amd64.s
deleted file mode 100644
index 0250c88859..0000000000
--- a/vendor/golang.org/x/crypto/curve25519/curve25519_amd64.s
+++ /dev/null
@@ -1,1793 +0,0 @@
-// 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: https://bench.cr.yp.to/supercop.html
-
-// +build amd64,!gccgo,!appengine,!purego
-
-#define REDMASK51     0x0007FFFFFFFFFFFF
-
-// These constants cannot be encoded in non-MOVQ immediates.
-// We access them directly from memory instead.
-
-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
-
-// func freeze(inout *[5]uint64)
-TEXT ·freeze(SB),7,$0-8
-	MOVQ inout+0(FP), DI
-
-	MOVQ 0(DI),SI
-	MOVQ 8(DI),DX
-	MOVQ 16(DI),CX
-	MOVQ 24(DI),R8
-	MOVQ 32(DI),R9
-	MOVQ $REDMASK51,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)
-	RET
-
-// func ladderstep(inout *[5][5]uint64)
-TEXT ·ladderstep(SB),0,$296-8
-	MOVQ inout+0(FP),DI
-
-	MOVQ 40(DI),SI
-	MOVQ 48(DI),DX
-	MOVQ 56(DI),CX
-	MOVQ 64(DI),R8
-	MOVQ 72(DI),R9
-	MOVQ SI,AX
-	MOVQ DX,R10
-	MOVQ CX,R11
-	MOVQ R8,R12
-	MOVQ R9,R13
-	ADDQ ·_2P0(SB),AX
-	ADDQ ·_2P1234(SB),R10
-	ADDQ ·_2P1234(SB),R11
-	ADDQ ·_2P1234(SB),R12
-	ADDQ ·_2P1234(SB),R13
-	ADDQ 80(DI),SI
-	ADDQ 88(DI),DX
-	ADDQ 96(DI),CX
-	ADDQ 104(DI),R8
-	ADDQ 112(DI),R9
-	SUBQ 80(DI),AX
-	SUBQ 88(DI),R10
-	SUBQ 96(DI),R11
-	SUBQ 104(DI),R12
-	SUBQ 112(DI),R13
-	MOVQ SI,0(SP)
-	MOVQ DX,8(SP)
-	MOVQ CX,16(SP)
-	MOVQ R8,24(SP)
-	MOVQ R9,32(SP)
-	MOVQ AX,40(SP)
-	MOVQ R10,48(SP)
-	MOVQ R11,56(SP)
-	MOVQ R12,64(SP)
-	MOVQ R13,72(SP)
-	MOVQ 40(SP),AX
-	MULQ 40(SP)
-	MOVQ AX,SI
-	MOVQ DX,CX
-	MOVQ 40(SP),AX
-	SHLQ $1,AX
-	MULQ 48(SP)
-	MOVQ AX,R8
-	MOVQ DX,R9
-	MOVQ 40(SP),AX
-	SHLQ $1,AX
-	MULQ 56(SP)
-	MOVQ AX,R10
-	MOVQ DX,R11
-	MOVQ 40(SP),AX
-	SHLQ $1,AX
-	MULQ 64(SP)
-	MOVQ AX,R12
-	MOVQ DX,R13
-	MOVQ 40(SP),AX
-	SHLQ $1,AX
-	MULQ 72(SP)
-	MOVQ AX,R14
-	MOVQ DX,R15
-	MOVQ 48(SP),AX
-	MULQ 48(SP)
-	ADDQ AX,R10
-	ADCQ DX,R11
-	MOVQ 48(SP),AX
-	SHLQ $1,AX
-	MULQ 56(SP)
-	ADDQ AX,R12
-	ADCQ DX,R13
-	MOVQ 48(SP),AX
-	SHLQ $1,AX
-	MULQ 64(SP)
-	ADDQ AX,R14
-	ADCQ DX,R15
-	MOVQ 48(SP),DX
-	IMUL3Q $38,DX,AX
-	MULQ 72(SP)
-	ADDQ AX,SI
-	ADCQ DX,CX
-	MOVQ 56(SP),AX
-	MULQ 56(SP)
-	ADDQ AX,R14
-	ADCQ DX,R15
-	MOVQ 56(SP),DX
-	IMUL3Q $38,DX,AX
-	MULQ 64(SP)
-	ADDQ AX,SI
-	ADCQ DX,CX
-	MOVQ 56(SP),DX
-	IMUL3Q $38,DX,AX
-	MULQ 72(SP)
-	ADDQ AX,R8
-	ADCQ DX,R9
-	MOVQ 64(SP),DX
-	IMUL3Q $19,DX,AX
-	MULQ 64(SP)
-	ADDQ AX,R8
-	ADCQ DX,R9
-	MOVQ 64(SP),DX
-	IMUL3Q $38,DX,AX
-	MULQ 72(SP)
-	ADDQ AX,R10
-	ADCQ DX,R11
-	MOVQ 72(SP),DX
-	IMUL3Q $19,DX,AX
-	MULQ 72(SP)
-	ADDQ AX,R12
-	ADCQ DX,R13
-	MOVQ $REDMASK51,DX
-	SHLQ $13,SI,CX
-	ANDQ DX,SI
-	SHLQ $13,R8,R9
-	ANDQ DX,R8
-	ADDQ CX,R8
-	SHLQ $13,R10,R11
-	ANDQ DX,R10
-	ADDQ R9,R10
-	SHLQ $13,R12,R13
-	ANDQ DX,R12
-	ADDQ R11,R12
-	SHLQ $13,R14,R15
-	ANDQ DX,R14
-	ADDQ R13,R14
-	IMUL3Q $19,R15,CX
-	ADDQ CX,SI
-	MOVQ SI,CX
-	SHRQ $51,CX
-	ADDQ R8,CX
-	ANDQ DX,SI
-	MOVQ CX,R8
-	SHRQ $51,CX
-	ADDQ R10,CX
-	ANDQ DX,R8
-	MOVQ CX,R9
-	SHRQ $51,CX
-	ADDQ R12,CX
-	ANDQ DX,R9
-	MOVQ CX,AX
-	SHRQ $51,CX
-	ADDQ R14,CX
-	ANDQ DX,AX
-	MOVQ CX,R10
-	SHRQ $51,CX
-	IMUL3Q $19,CX,CX
-	ADDQ CX,SI
-	ANDQ DX,R10
-	MOVQ SI,80(SP)
-	MOVQ R8,88(SP)
-	MOVQ R9,96(SP)
-	MOVQ AX,104(SP)
-	MOVQ R10,112(SP)
-	MOVQ 0(SP),AX
-	MULQ 0(SP)
-	MOVQ AX,SI
-	MOVQ DX,CX
-	MOVQ 0(SP),AX
-	SHLQ $1,AX
-	MULQ 8(SP)
-	MOVQ AX,R8
-	MOVQ DX,R9
-	MOVQ 0(SP),AX
-	SHLQ $1,AX
-	MULQ 16(SP)
-	MOVQ AX,R10
-	MOVQ DX,R11
-	MOVQ 0(SP),AX
-	SHLQ $1,AX
-	MULQ 24(SP)
-	MOVQ AX,R12
-	MOVQ DX,R13
-	MOVQ 0(SP),AX
-	SHLQ $1,AX
-	MULQ 32(SP)
-	MOVQ AX,R14
-	MOVQ DX,R15
-	MOVQ 8(SP),AX
-	MULQ 8(SP)
-	ADDQ AX,R10
-	ADCQ DX,R11
-	MOVQ 8(SP),AX
-	SHLQ $1,AX
-	MULQ 16(SP)
-	ADDQ AX,R12
-	ADCQ DX,R13
-	MOVQ 8(SP),AX
-	SHLQ $1,AX
-	MULQ 24(SP)
-	ADDQ AX,R14
-	ADCQ DX,R15
-	MOVQ 8(SP),DX
-	IMUL3Q $38,DX,AX
-	MULQ 32(SP)
-	ADDQ AX,SI
-	ADCQ DX,CX
-	MOVQ 16(SP),AX
-	MULQ 16(SP)
-	ADDQ AX,R14
-	ADCQ DX,R15
-	MOVQ 16(SP),DX
-	IMUL3Q $38,DX,AX
-	MULQ 24(SP)
-	ADDQ AX,SI
-	ADCQ DX,CX
-	MOVQ 16(SP),DX
-	IMUL3Q $38,DX,AX
-	MULQ 32(SP)
-	ADDQ AX,R8
-	ADCQ DX,R9
-	MOVQ 24(SP),DX
-	IMUL3Q $19,DX,AX
-	MULQ 24(SP)
-	ADDQ AX,R8
-	ADCQ DX,R9
-	MOVQ 24(SP),DX
-	IMUL3Q $38,DX,AX
-	MULQ 32(SP)
-	ADDQ AX,R10
-	ADCQ DX,R11
-	MOVQ 32(SP),DX
-	IMUL3Q $19,DX,AX
-	MULQ 32(SP)
-	ADDQ AX,R12
-	ADCQ DX,R13
-	MOVQ $REDMASK51,DX
-	SHLQ $13,SI,CX
-	ANDQ DX,SI
-	SHLQ $13,R8,R9
-	ANDQ DX,R8
-	ADDQ CX,R8
-	SHLQ $13,R10,R11
-	ANDQ DX,R10
-	ADDQ R9,R10
-	SHLQ $13,R12,R13
-	ANDQ DX,R12
-	ADDQ R11,R12
-	SHLQ $13,R14,R15
-	ANDQ DX,R14
-	ADDQ R13,R14
-	IMUL3Q $19,R15,CX
-	ADDQ CX,SI
-	MOVQ SI,CX
-	SHRQ $51,CX
-	ADDQ R8,CX
-	ANDQ DX,SI
-	MOVQ CX,R8
-	SHRQ $51,CX
-	ADDQ R10,CX
-	ANDQ DX,R8
-	MOVQ CX,R9
-	SHRQ $51,CX
-	ADDQ R12,CX
-	ANDQ DX,R9
-	MOVQ CX,AX
-	SHRQ $51,CX
-	ADDQ R14,CX
-	ANDQ DX,AX
-	MOVQ CX,R10
-	SHRQ $51,CX
-	IMUL3Q $19,CX,CX
-	ADDQ CX,SI
-	ANDQ DX,R10
-	MOVQ SI,120(SP)
-	MOVQ R8,128(SP)
-	MOVQ R9,136(SP)
-	MOVQ AX,144(SP)
-	MOVQ R10,152(SP)
-	MOVQ SI,SI
-	MOVQ R8,DX
-	MOVQ R9,CX
-	MOVQ AX,R8
-	MOVQ R10,R9
-	ADDQ ·_2P0(SB),SI
-	ADDQ ·_2P1234(SB),DX
-	ADDQ ·_2P1234(SB),CX
-	ADDQ ·_2P1234(SB),R8
-	ADDQ ·_2P1234(SB),R9
-	SUBQ 80(SP),SI
-	SUBQ 88(SP),DX
-	SUBQ 96(SP),CX
-	SUBQ 104(SP),R8
-	SUBQ 112(SP),R9
-	MOVQ SI,160(SP)
-	MOVQ DX,168(SP)
-	MOVQ CX,176(SP)
-	MOVQ R8,184(SP)
-	MOVQ R9,192(SP)
-	MOVQ 120(DI),SI
-	MOVQ 128(DI),DX
-	MOVQ 136(DI),CX
-	MOVQ 144(DI),R8
-	MOVQ 152(DI),R9
-	MOVQ SI,AX
-	MOVQ DX,R10
-	MOVQ CX,R11
-	MOVQ R8,R12
-	MOVQ R9,R13
-	ADDQ ·_2P0(SB),AX
-	ADDQ ·_2P1234(SB),R10
-	ADDQ ·_2P1234(SB),R11
-	ADDQ ·_2P1234(SB),R12
-	ADDQ ·_2P1234(SB),R13
-	ADDQ 160(DI),SI
-	ADDQ 168(DI),DX
-	ADDQ 176(DI),CX
-	ADDQ 184(DI),R8
-	ADDQ 192(DI),R9
-	SUBQ 160(DI),AX
-	SUBQ 168(DI),R10
-	SUBQ 176(DI),R11
-	SUBQ 184(DI),R12
-	SUBQ 192(DI),R13
-	MOVQ SI,200(SP)
-	MOVQ DX,208(SP)
-	MOVQ CX,216(SP)
-	MOVQ R8,224(SP)
-	MOVQ R9,232(SP)
-	MOVQ AX,240(SP)
-	MOVQ R10,248(SP)
-	MOVQ R11,256(SP)
-	MOVQ R12,264(SP)
-	MOVQ R13,272(SP)
-	MOVQ 224(SP),SI
-	IMUL3Q $19,SI,AX
-	MOVQ AX,280(SP)
-	MULQ 56(SP)
-	MOVQ AX,SI
-	MOVQ DX,CX
-	MOVQ 232(SP),DX
-	IMUL3Q $19,DX,AX
-	MOVQ AX,288(SP)
-	MULQ 48(SP)
-	ADDQ AX,SI
-	ADCQ DX,CX
-	MOVQ 200(SP),AX
-	MULQ 40(SP)
-	ADDQ AX,SI
-	ADCQ DX,CX
-	MOVQ 200(SP),AX
-	MULQ 48(SP)
-	MOVQ AX,R8
-	MOVQ DX,R9
-	MOVQ 200(SP),AX
-	MULQ 56(SP)
-	MOVQ AX,R10
-	MOVQ DX,R11
-	MOVQ 200(SP),AX
-	MULQ 64(SP)
-	MOVQ AX,R12
-	MOVQ DX,R13
-	MOVQ 200(SP),AX
-	MULQ 72(SP)
-	MOVQ AX,R14
-	MOVQ DX,R15
-	MOVQ 208(SP),AX
-	MULQ 40(SP)
-	ADDQ AX,R8
-	ADCQ DX,R9
-	MOVQ 208(SP),AX
-	MULQ 48(SP)
-	ADDQ AX,R10
-	ADCQ DX,R11
-	MOVQ 208(SP),AX
-	MULQ 56(SP)
-	ADDQ AX,R12
-	ADCQ DX,R13
-	MOVQ 208(SP),AX
-	MULQ 64(SP)
-	ADDQ AX,R14
-	ADCQ DX,R15
-	MOVQ 208(SP),DX
-	IMUL3Q $19,DX,AX
-	MULQ 72(SP)
-	ADDQ AX,SI
-	ADCQ DX,CX
-	MOVQ 216(SP),AX
-	MULQ 40(SP)
-	ADDQ AX,R10
-	ADCQ DX,R11
-	MOVQ 216(SP),AX
-	MULQ 48(SP)
-	ADDQ AX,R12
-	ADCQ DX,R13
-	MOVQ 216(SP),AX
-	MULQ 56(SP)
-	ADDQ AX,R14
-	ADCQ DX,R15
-	MOVQ 216(SP),DX
-	IMUL3Q $19,DX,AX
-	MULQ 64(SP)
-	ADDQ AX,SI
-	ADCQ DX,CX
-	MOVQ 216(SP),DX
-	IMUL3Q $19,DX,AX
-	MULQ 72(SP)
-	ADDQ AX,R8
-	ADCQ DX,R9
-	MOVQ 224(SP),AX
-	MULQ 40(SP)
-	ADDQ AX,R12
-	ADCQ DX,R13
-	MOVQ 224(SP),AX
-	MULQ 48(SP)
-	ADDQ AX,R14
-	ADCQ DX,R15
-	MOVQ 280(SP),AX
-	MULQ 64(SP)
-	ADDQ AX,R8
-	ADCQ DX,R9
-	MOVQ 280(SP),AX
-	MULQ 72(SP)
-	ADDQ AX,R10
-	ADCQ DX,R11
-	MOVQ 232(SP),AX
-	MULQ 40(SP)
-	ADDQ AX,R14
-	ADCQ DX,R15
-	MOVQ 288(SP),AX
-	MULQ 56(SP)
-	ADDQ AX,R8
-	ADCQ DX,R9
-	MOVQ 288(SP),AX
-	MULQ 64(SP)
-	ADDQ AX,R10
-	ADCQ DX,R11
-	MOVQ 288(SP),AX
-	MULQ 72(SP)
-	ADDQ AX,R12
-	ADCQ DX,R13
-	MOVQ $REDMASK51,DX
-	SHLQ $13,SI,CX
-	ANDQ DX,SI
-	SHLQ $13,R8,R9
-	ANDQ DX,R8
-	ADDQ CX,R8
-	SHLQ $13,R10,R11
-	ANDQ DX,R10
-	ADDQ R9,R10
-	SHLQ $13,R12,R13
-	ANDQ DX,R12
-	ADDQ R11,R12
-	SHLQ $13,R14,R15
-	ANDQ DX,R14
-	ADDQ R13,R14
-	IMUL3Q $19,R15,CX
-	ADDQ CX,SI
-	MOVQ SI,CX
-	SHRQ $51,CX
-	ADDQ R8,CX
-	MOVQ CX,R8
-	SHRQ $51,CX
-	ANDQ DX,SI
-	ADDQ R10,CX
-	MOVQ CX,R9
-	SHRQ $51,CX
-	ANDQ DX,R8
-	ADDQ R12,CX
-	MOVQ CX,AX
-	SHRQ $51,CX
-	ANDQ DX,R9
-	ADDQ R14,CX
-	MOVQ CX,R10
-	SHRQ $51,CX
-	ANDQ DX,AX
-	IMUL3Q $19,CX,CX
-	ADDQ CX,SI
-	ANDQ DX,R10
-	MOVQ SI,40(SP)
-	MOVQ R8,48(SP)
-	MOVQ R9,56(SP)
-	MOVQ AX,64(SP)
-	MOVQ R10,72(SP)
-	MOVQ 264(SP),SI
-	IMUL3Q $19,SI,AX
-	MOVQ AX,200(SP)
-	MULQ 16(SP)
-	MOVQ AX,SI
-	MOVQ DX,CX
-	MOVQ 272(SP),DX
-	IMUL3Q $19,DX,AX
-	MOVQ AX,208(SP)
-	MULQ 8(SP)
-	ADDQ AX,SI
-	ADCQ DX,CX
-	MOVQ 240(SP),AX
-	MULQ 0(SP)
-	ADDQ AX,SI
-	ADCQ DX,CX
-	MOVQ 240(SP),AX
-	MULQ 8(SP)
-	MOVQ AX,R8
-	MOVQ DX,R9
-	MOVQ 240(SP),AX
-	MULQ 16(SP)
-	MOVQ AX,R10
-	MOVQ DX,R11
-	MOVQ 240(SP),AX
-	MULQ 24(SP)
-	MOVQ AX,R12
-	MOVQ DX,R13
-	MOVQ 240(SP),AX
-	MULQ 32(SP)
-	MOVQ AX,R14
-	MOVQ DX,R15
-	MOVQ 248(SP),AX
-	MULQ 0(SP)
-	ADDQ AX,R8
-	ADCQ DX,R9
-	MOVQ 248(SP),AX
-	MULQ 8(SP)
-	ADDQ AX,R10
-	ADCQ DX,R11
-	MOVQ 248(SP),AX
-	MULQ 16(SP)
-	ADDQ AX,R12
-	ADCQ DX,R13
-	MOVQ 248(SP),AX
-	MULQ 24(SP)
-	ADDQ AX,R14
-	ADCQ DX,R15
-	MOVQ 248(SP),DX
-	IMUL3Q $19,DX,AX
-	MULQ 32(SP)
-	ADDQ AX,SI
-	ADCQ DX,CX
-	MOVQ 256(SP),AX
-	MULQ 0(SP)
-	ADDQ AX,R10
-	ADCQ DX,R11
-	MOVQ 256(SP),AX
-	MULQ 8(SP)
-	ADDQ AX,R12
-	ADCQ DX,R13
-	MOVQ 256(SP),AX
-	MULQ 16(SP)
-	ADDQ AX,R14
-	ADCQ DX,R15
-	MOVQ 256(SP),DX
-	IMUL3Q $19,DX,AX
-	MULQ 24(SP)
-	ADDQ AX,SI
-	ADCQ DX,CX
-	MOVQ 256(SP),DX
-	IMUL3Q $19,DX,AX
-	MULQ 32(SP)
-	ADDQ AX,R8
-	ADCQ DX,R9
-	MOVQ 264(SP),AX
-	MULQ 0(SP)
-	ADDQ AX,R12
-	ADCQ DX,R13
-	MOVQ 264(SP),AX
-	MULQ 8(SP)
-	ADDQ AX,R14
-	ADCQ DX,R15
-	MOVQ 200(SP),AX
-	MULQ 24(SP)
-	ADDQ AX,R8
-	ADCQ DX,R9
-	MOVQ 200(SP),AX
-	MULQ 32(SP)
-	ADDQ AX,R10
-	ADCQ DX,R11
-	MOVQ 272(SP),AX
-	MULQ 0(SP)
-	ADDQ AX,R14
-	ADCQ DX,R15
-	MOVQ 208(SP),AX
-	MULQ 16(SP)
-	ADDQ AX,R8
-	ADCQ DX,R9
-	MOVQ 208(SP),AX
-	MULQ 24(SP)
-	ADDQ AX,R10
-	ADCQ DX,R11
-	MOVQ 208(SP),AX
-	MULQ 32(SP)
-	ADDQ AX,R12
-	ADCQ DX,R13
-	MOVQ $REDMASK51,DX
-	SHLQ $13,SI,CX
-	ANDQ DX,SI
-	SHLQ $13,R8,R9
-	ANDQ DX,R8
-	ADDQ CX,R8
-	SHLQ $13,R10,R11
-	ANDQ DX,R10
-	ADDQ R9,R10
-	SHLQ $13,R12,R13
-	ANDQ DX,R12
-	ADDQ R11,R12
-	SHLQ $13,R14,R15
-	ANDQ DX,R14
-	ADDQ R13,R14
-	IMUL3Q $19,R15,CX
-	ADDQ CX,SI
-	MOVQ SI,CX
-	SHRQ $51,CX
-	ADDQ R8,CX
-	MOVQ CX,R8
-	SHRQ $51,CX
-	ANDQ DX,SI
-	ADDQ R10,CX
-	MOVQ CX,R9
-	SHRQ $51,CX
-	ANDQ DX,R8
-	ADDQ R12,CX
-	MOVQ CX,AX
-	SHRQ $51,CX
-	ANDQ DX,R9
-	ADDQ R14,CX
-	MOVQ CX,R10
-	SHRQ $51,CX
-	ANDQ DX,AX
-	IMUL3Q $19,CX,CX
-	ADDQ CX,SI
-	ANDQ DX,R10
-	MOVQ SI,DX
-	MOVQ R8,CX
-	MOVQ R9,R11
-	MOVQ AX,R12
-	MOVQ R10,R13
-	ADDQ ·_2P0(SB),DX
-	ADDQ ·_2P1234(SB),CX
-	ADDQ ·_2P1234(SB),R11
-	ADDQ ·_2P1234(SB),R12
-	ADDQ ·_2P1234(SB),R13
-	ADDQ 40(SP),SI
-	ADDQ 48(SP),R8
-	ADDQ 56(SP),R9
-	ADDQ 64(SP),AX
-	ADDQ 72(SP),R10
-	SUBQ 40(SP),DX
-	SUBQ 48(SP),CX
-	SUBQ 56(SP),R11
-	SUBQ 64(SP),R12
-	SUBQ 72(SP),R13
-	MOVQ SI,120(DI)
-	MOVQ R8,128(DI)
-	MOVQ R9,136(DI)
-	MOVQ AX,144(DI)
-	MOVQ R10,152(DI)
-	MOVQ DX,160(DI)
-	MOVQ CX,168(DI)
-	MOVQ R11,176(DI)
-	MOVQ R12,184(DI)
-	MOVQ R13,192(DI)
-	MOVQ 120(DI),AX
-	MULQ 120(DI)
-	MOVQ AX,SI
-	MOVQ DX,CX
-	MOVQ 120(DI),AX
-	SHLQ $1,AX
-	MULQ 128(DI)
-	MOVQ AX,R8
-	MOVQ DX,R9
-	MOVQ 120(DI),AX
-	SHLQ $1,AX
-	MULQ 136(DI)
-	MOVQ AX,R10
-	MOVQ DX,R11
-	MOVQ 120(DI),AX
-	SHLQ $1,AX
-	MULQ 144(DI)
-	MOVQ AX,R12
-	MOVQ DX,R13
-	MOVQ 120(DI),AX
-	SHLQ $1,AX
-	MULQ 152(DI)
-	MOVQ AX,R14
-	MOVQ DX,R15
-	MOVQ 128(DI),AX
-	MULQ 128(DI)
-	ADDQ AX,R10
-	ADCQ DX,R11
-	MOVQ 128(DI),AX
-	SHLQ $1,AX
-	MULQ 136(DI)
-	ADDQ AX,R12
-	ADCQ DX,R13
-	MOVQ 128(DI),AX
-	SHLQ $1,AX
-	MULQ 144(DI)
-	ADDQ AX,R14
-	ADCQ DX,R15
-	MOVQ 128(DI),DX
-	IMUL3Q $38,DX,AX
-	MULQ 152(DI)
-	ADDQ AX,SI
-	ADCQ DX,CX
-	MOVQ 136(DI),AX
-	MULQ 136(DI)
-	ADDQ AX,R14
-	ADCQ DX,R15
-	MOVQ 136(DI),DX
-	IMUL3Q $38,DX,AX
-	MULQ 144(DI)
-	ADDQ AX,SI
-	ADCQ DX,CX
-	MOVQ 136(DI),DX
-	IMUL3Q $38,DX,AX
-	MULQ 152(DI)
-	ADDQ AX,R8
-	ADCQ DX,R9
-	MOVQ 144(DI),DX
-	IMUL3Q $19,DX,AX
-	MULQ 144(DI)
-	ADDQ AX,R8
-	ADCQ DX,R9
-	MOVQ 144(DI),DX
-	IMUL3Q $38,DX,AX
-	MULQ 152(DI)
-	ADDQ AX,R10
-	ADCQ DX,R11
-	MOVQ 152(DI),DX
-	IMUL3Q $19,DX,AX
-	MULQ 152(DI)
-	ADDQ AX,R12
-	ADCQ DX,R13
-	MOVQ $REDMASK51,DX
-	SHLQ $13,SI,CX
-	ANDQ DX,SI
-	SHLQ $13,R8,R9
-	ANDQ DX,R8
-	ADDQ CX,R8
-	SHLQ $13,R10,R11
-	ANDQ DX,R10
-	ADDQ R9,R10
-	SHLQ $13,R12,R13
-	ANDQ DX,R12
-	ADDQ R11,R12
-	SHLQ $13,R14,R15
-	ANDQ DX,R14
-	ADDQ R13,R14
-	IMUL3Q $19,R15,CX
-	ADDQ CX,SI
-	MOVQ SI,CX
-	SHRQ $51,CX
-	ADDQ R8,CX
-	ANDQ DX,SI
-	MOVQ CX,R8
-	SHRQ $51,CX
-	ADDQ R10,CX
-	ANDQ DX,R8
-	MOVQ CX,R9
-	SHRQ $51,CX
-	ADDQ R12,CX
-	ANDQ DX,R9
-	MOVQ CX,AX
-	SHRQ $51,CX
-	ADDQ R14,CX
-	ANDQ DX,AX
-	MOVQ CX,R10
-	SHRQ $51,CX
-	IMUL3Q $19,CX,CX
-	ADDQ CX,SI
-	ANDQ DX,R10
-	MOVQ SI,120(DI)
-	MOVQ R8,128(DI)
-	MOVQ R9,136(DI)
-	MOVQ AX,144(DI)
-	MOVQ R10,152(DI)
-	MOVQ 160(DI),AX
-	MULQ 160(DI)
-	MOVQ AX,SI
-	MOVQ DX,CX
-	MOVQ 160(DI),AX
-	SHLQ $1,AX
-	MULQ 168(DI)
-	MOVQ AX,R8
-	MOVQ DX,R9
-	MOVQ 160(DI),AX
-	SHLQ $1,AX
-	MULQ 176(DI)
-	MOVQ AX,R10
-	MOVQ DX,R11
-	MOVQ 160(DI),AX
-	SHLQ $1,AX
-	MULQ 184(DI)
-	MOVQ AX,R12
-	MOVQ DX,R13
-	MOVQ 160(DI),AX
-	SHLQ $1,AX
-	MULQ 192(DI)
-	MOVQ AX,R14
-	MOVQ DX,R15
-	MOVQ 168(DI),AX
-	MULQ 168(DI)
-	ADDQ AX,R10
-	ADCQ DX,R11
-	MOVQ 168(DI),AX
-	SHLQ $1,AX
-	MULQ 176(DI)
-	ADDQ AX,R12
-	ADCQ DX,R13
-	MOVQ 168(DI),AX
-	SHLQ $1,AX
-	MULQ 184(DI)
-	ADDQ AX,R14
-	ADCQ DX,R15
-	MOVQ 168(DI),DX
-	IMUL3Q $38,DX,AX
-	MULQ 192(DI)
-	ADDQ AX,SI
-	ADCQ DX,CX
-	MOVQ 176(DI),AX
-	MULQ 176(DI)
-	ADDQ AX,R14
-	ADCQ DX,R15
-	MOVQ 176(DI),DX
-	IMUL3Q $38,DX,AX
-	MULQ 184(DI)
-	ADDQ AX,SI
-	ADCQ DX,CX
-	MOVQ 176(DI),DX
-	IMUL3Q $38,DX,AX
-	MULQ 192(DI)
-	ADDQ AX,R8
-	ADCQ DX,R9
-	MOVQ 184(DI),DX
-	IMUL3Q $19,DX,AX
-	MULQ 184(DI)
-	ADDQ AX,R8
-	ADCQ DX,R9
-	MOVQ 184(DI),DX
-	IMUL3Q $38,DX,AX
-	MULQ 192(DI)
-	ADDQ AX,R10
-	ADCQ DX,R11
-	MOVQ 192(DI),DX
-	IMUL3Q $19,DX,AX
-	MULQ 192(DI)
-	ADDQ AX,R12
-	ADCQ DX,R13
-	MOVQ $REDMASK51,DX
-	SHLQ $13,SI,CX
-	ANDQ DX,SI
-	SHLQ $13,R8,R9
-	ANDQ DX,R8
-	ADDQ CX,R8
-	SHLQ $13,R10,R11
-	ANDQ DX,R10
-	ADDQ R9,R10
-	SHLQ $13,R12,R13
-	ANDQ DX,R12
-	ADDQ R11,R12
-	SHLQ $13,R14,R15
-	ANDQ DX,R14
-	ADDQ R13,R14
-	IMUL3Q $19,R15,CX
-	ADDQ CX,SI
-	MOVQ SI,CX
-	SHRQ $51,CX
-	ADDQ R8,CX
-	ANDQ DX,SI
-	MOVQ CX,R8
-	SHRQ $51,CX
-	ADDQ R10,CX
-	ANDQ DX,R8
-	MOVQ CX,R9
-	SHRQ $51,CX
-	ADDQ R12,CX
-	ANDQ DX,R9
-	MOVQ CX,AX
-	SHRQ $51,CX
-	ADDQ R14,CX
-	ANDQ DX,AX
-	MOVQ CX,R10
-	SHRQ $51,CX
-	IMUL3Q $19,CX,CX
-	ADDQ CX,SI
-	ANDQ DX,R10
-	MOVQ SI,160(DI)
-	MOVQ R8,168(DI)
-	MOVQ R9,176(DI)
-	MOVQ AX,184(DI)
-	MOVQ R10,192(DI)
-	MOVQ 184(DI),SI
-	IMUL3Q $19,SI,AX
-	MOVQ AX,0(SP)
-	MULQ 16(DI)
-	MOVQ AX,SI
-	MOVQ DX,CX
-	MOVQ 192(DI),DX
-	IMUL3Q $19,DX,AX
-	MOVQ AX,8(SP)
-	MULQ 8(DI)
-	ADDQ AX,SI
-	ADCQ DX,CX
-	MOVQ 160(DI),AX
-	MULQ 0(DI)
-	ADDQ AX,SI
-	ADCQ DX,CX
-	MOVQ 160(DI),AX
-	MULQ 8(DI)
-	MOVQ AX,R8
-	MOVQ DX,R9
-	MOVQ 160(DI),AX
-	MULQ 16(DI)
-	MOVQ AX,R10
-	MOVQ DX,R11
-	MOVQ 160(DI),AX
-	MULQ 24(DI)
-	MOVQ AX,R12
-	MOVQ DX,R13
-	MOVQ 160(DI),AX
-	MULQ 32(DI)
-	MOVQ AX,R14
-	MOVQ DX,R15
-	MOVQ 168(DI),AX
-	MULQ 0(DI)
-	ADDQ AX,R8
-	ADCQ DX,R9
-	MOVQ 168(DI),AX
-	MULQ 8(DI)
-	ADDQ AX,R10
-	ADCQ DX,R11
-	MOVQ 168(DI),AX
-	MULQ 16(DI)
-	ADDQ AX,R12
-	ADCQ DX,R13
-	MOVQ 168(DI),AX
-	MULQ 24(DI)
-	ADDQ AX,R14
-	ADCQ DX,R15
-	MOVQ 168(DI),DX
-	IMUL3Q $19,DX,AX
-	MULQ 32(DI)
-	ADDQ AX,SI
-	ADCQ DX,CX
-	MOVQ 176(DI),AX
-	MULQ 0(DI)
-	ADDQ AX,R10
-	ADCQ DX,R11
-	MOVQ 176(DI),AX
-	MULQ 8(DI)
-	ADDQ AX,R12
-	ADCQ DX,R13
-	MOVQ 176(DI),AX
-	MULQ 16(DI)
-	ADDQ AX,R14
-	ADCQ DX,R15
-	MOVQ 176(DI),DX
-	IMUL3Q $19,DX,AX
-	MULQ 24(DI)
-	ADDQ AX,SI
-	ADCQ DX,CX
-	MOVQ 176(DI),DX
-	IMUL3Q $19,DX,AX
-	MULQ 32(DI)
-	ADDQ AX,R8
-	ADCQ DX,R9
-	MOVQ 184(DI),AX
-	MULQ 0(DI)
-	ADDQ AX,R12
-	ADCQ DX,R13
-	MOVQ 184(DI),AX
-	MULQ 8(DI)
-	ADDQ AX,R14
-	ADCQ DX,R15
-	MOVQ 0(SP),AX
-	MULQ 24(DI)
-	ADDQ AX,R8
-	ADCQ DX,R9
-	MOVQ 0(SP),AX
-	MULQ 32(DI)
-	ADDQ AX,R10
-	ADCQ DX,R11
-	MOVQ 192(DI),AX
-	MULQ 0(DI)
-	ADDQ AX,R14
-	ADCQ DX,R15
-	MOVQ 8(SP),AX
-	MULQ 16(DI)
-	ADDQ AX,R8
-	ADCQ DX,R9
-	MOVQ 8(SP),AX
-	MULQ 24(DI)
-	ADDQ AX,R10
-	ADCQ DX,R11
-	MOVQ 8(SP),AX
-	MULQ 32(DI)
-	ADDQ AX,R12
-	ADCQ DX,R13
-	MOVQ $REDMASK51,DX
-	SHLQ $13,SI,CX
-	ANDQ DX,SI
-	SHLQ $13,R8,R9
-	ANDQ DX,R8
-	ADDQ CX,R8
-	SHLQ $13,R10,R11
-	ANDQ DX,R10
-	ADDQ R9,R10
-	SHLQ $13,R12,R13
-	ANDQ DX,R12
-	ADDQ R11,R12
-	SHLQ $13,R14,R15
-	ANDQ DX,R14
-	ADDQ R13,R14
-	IMUL3Q $19,R15,CX
-	ADDQ CX,SI
-	MOVQ SI,CX
-	SHRQ $51,CX
-	ADDQ R8,CX
-	MOVQ CX,R8
-	SHRQ $51,CX
-	ANDQ DX,SI
-	ADDQ R10,CX
-	MOVQ CX,R9
-	SHRQ $51,CX
-	ANDQ DX,R8
-	ADDQ R12,CX
-	MOVQ CX,AX
-	SHRQ $51,CX
-	ANDQ DX,R9
-	ADDQ R14,CX
-	MOVQ CX,R10
-	SHRQ $51,CX
-	ANDQ DX,AX
-	IMUL3Q $19,CX,CX
-	ADDQ CX,SI
-	ANDQ DX,R10
-	MOVQ SI,160(DI)
-	MOVQ R8,168(DI)
-	MOVQ R9,176(DI)
-	MOVQ AX,184(DI)
-	MOVQ R10,192(DI)
-	MOVQ 144(SP),SI
-	IMUL3Q $19,SI,AX
-	MOVQ AX,0(SP)
-	MULQ 96(SP)
-	MOVQ AX,SI
-	MOVQ DX,CX
-	MOVQ 152(SP),DX
-	IMUL3Q $19,DX,AX
-	MOVQ AX,8(SP)
-	MULQ 88(SP)
-	ADDQ AX,SI
-	ADCQ DX,CX
-	MOVQ 120(SP),AX
-	MULQ 80(SP)
-	ADDQ AX,SI
-	ADCQ DX,CX
-	MOVQ 120(SP),AX
-	MULQ 88(SP)
-	MOVQ AX,R8
-	MOVQ DX,R9
-	MOVQ 120(SP),AX
-	MULQ 96(SP)
-	MOVQ AX,R10
-	MOVQ DX,R11
-	MOVQ 120(SP),AX
-	MULQ 104(SP)
-	MOVQ AX,R12
-	MOVQ DX,R13
-	MOVQ 120(SP),AX
-	MULQ 112(SP)
-	MOVQ AX,R14
-	MOVQ DX,R15
-	MOVQ 128(SP),AX
-	MULQ 80(SP)
-	ADDQ AX,R8
-	ADCQ DX,R9
-	MOVQ 128(SP),AX
-	MULQ 88(SP)
-	ADDQ AX,R10
-	ADCQ DX,R11
-	MOVQ 128(SP),AX
-	MULQ 96(SP)
-	ADDQ AX,R12
-	ADCQ DX,R13
-	MOVQ 128(SP),AX
-	MULQ 104(SP)
-	ADDQ AX,R14
-	ADCQ DX,R15
-	MOVQ 128(SP),DX
-	IMUL3Q $19,DX,AX
-	MULQ 112(SP)
-	ADDQ AX,SI
-	ADCQ DX,CX
-	MOVQ 136(SP),AX
-	MULQ 80(SP)
-	ADDQ AX,R10
-	ADCQ DX,R11
-	MOVQ 136(SP),AX
-	MULQ 88(SP)
-	ADDQ AX,R12
-	ADCQ DX,R13
-	MOVQ 136(SP),AX
-	MULQ 96(SP)
-	ADDQ AX,R14
-	ADCQ DX,R15
-	MOVQ 136(SP),DX
-	IMUL3Q $19,DX,AX
-	MULQ 104(SP)
-	ADDQ AX,SI
-	ADCQ DX,CX
-	MOVQ 136(SP),DX
-	IMUL3Q $19,DX,AX
-	MULQ 112(SP)
-	ADDQ AX,R8
-	ADCQ DX,R9
-	MOVQ 144(SP),AX
-	MULQ 80(SP)
-	ADDQ AX,R12
-	ADCQ DX,R13
-	MOVQ 144(SP),AX
-	MULQ 88(SP)
-	ADDQ AX,R14
-	ADCQ DX,R15
-	MOVQ 0(SP),AX
-	MULQ 104(SP)
-	ADDQ AX,R8
-	ADCQ DX,R9
-	MOVQ 0(SP),AX
-	MULQ 112(SP)
-	ADDQ AX,R10
-	ADCQ DX,R11
-	MOVQ 152(SP),AX
-	MULQ 80(SP)
-	ADDQ AX,R14
-	ADCQ DX,R15
-	MOVQ 8(SP),AX
-	MULQ 96(SP)
-	ADDQ AX,R8
-	ADCQ DX,R9
-	MOVQ 8(SP),AX
-	MULQ 104(SP)
-	ADDQ AX,R10
-	ADCQ DX,R11
-	MOVQ 8(SP),AX
-	MULQ 112(SP)
-	ADDQ AX,R12
-	ADCQ DX,R13
-	MOVQ $REDMASK51,DX
-	SHLQ $13,SI,CX
-	ANDQ DX,SI
-	SHLQ $13,R8,R9
-	ANDQ DX,R8
-	ADDQ CX,R8
-	SHLQ $13,R10,R11
-	ANDQ DX,R10
-	ADDQ R9,R10
-	SHLQ $13,R12,R13
-	ANDQ DX,R12
-	ADDQ R11,R12
-	SHLQ $13,R14,R15
-	ANDQ DX,R14
-	ADDQ R13,R14
-	IMUL3Q $19,R15,CX
-	ADDQ CX,SI
-	MOVQ SI,CX
-	SHRQ $51,CX
-	ADDQ R8,CX
-	MOVQ CX,R8
-	SHRQ $51,CX
-	ANDQ DX,SI
-	ADDQ R10,CX
-	MOVQ CX,R9
-	SHRQ $51,CX
-	ANDQ DX,R8
-	ADDQ R12,CX
-	MOVQ CX,AX
-	SHRQ $51,CX
-	ANDQ DX,R9
-	ADDQ R14,CX
-	MOVQ CX,R10
-	SHRQ $51,CX
-	ANDQ DX,AX
-	IMUL3Q $19,CX,CX
-	ADDQ CX,SI
-	ANDQ DX,R10
-	MOVQ SI,40(DI)
-	MOVQ R8,48(DI)
-	MOVQ R9,56(DI)
-	MOVQ AX,64(DI)
-	MOVQ R10,72(DI)
-	MOVQ 160(SP),AX
-	MULQ ·_121666_213(SB)
-	SHRQ $13,AX
-	MOVQ AX,SI
-	MOVQ DX,CX
-	MOVQ 168(SP),AX
-	MULQ ·_121666_213(SB)
-	SHRQ $13,AX
-	ADDQ AX,CX
-	MOVQ DX,R8
-	MOVQ 176(SP),AX
-	MULQ ·_121666_213(SB)
-	SHRQ $13,AX
-	ADDQ AX,R8
-	MOVQ DX,R9
-	MOVQ 184(SP),AX
-	MULQ ·_121666_213(SB)
-	SHRQ $13,AX
-	ADDQ AX,R9
-	MOVQ DX,R10
-	MOVQ 192(SP),AX
-	MULQ ·_121666_213(SB)
-	SHRQ $13,AX
-	ADDQ AX,R10
-	IMUL3Q $19,DX,DX
-	ADDQ DX,SI
-	ADDQ 80(SP),SI
-	ADDQ 88(SP),CX
-	ADDQ 96(SP),R8
-	ADDQ 104(SP),R9
-	ADDQ 112(SP),R10
-	MOVQ SI,80(DI)
-	MOVQ CX,88(DI)
-	MOVQ R8,96(DI)
-	MOVQ R9,104(DI)
-	MOVQ R10,112(DI)
-	MOVQ 104(DI),SI
-	IMUL3Q $19,SI,AX
-	MOVQ AX,0(SP)
-	MULQ 176(SP)
-	MOVQ AX,SI
-	MOVQ DX,CX
-	MOVQ 112(DI),DX
-	IMUL3Q $19,DX,AX
-	MOVQ AX,8(SP)
-	MULQ 168(SP)
-	ADDQ AX,SI
-	ADCQ DX,CX
-	MOVQ 80(DI),AX
-	MULQ 160(SP)
-	ADDQ AX,SI
-	ADCQ DX,CX
-	MOVQ 80(DI),AX
-	MULQ 168(SP)
-	MOVQ AX,R8
-	MOVQ DX,R9
-	MOVQ 80(DI),AX
-	MULQ 176(SP)
-	MOVQ AX,R10
-	MOVQ DX,R11
-	MOVQ 80(DI),AX
-	MULQ 184(SP)
-	MOVQ AX,R12
-	MOVQ DX,R13
-	MOVQ 80(DI),AX
-	MULQ 192(SP)
-	MOVQ AX,R14
-	MOVQ DX,R15
-	MOVQ 88(DI),AX
-	MULQ 160(SP)
-	ADDQ AX,R8
-	ADCQ DX,R9
-	MOVQ 88(DI),AX
-	MULQ 168(SP)
-	ADDQ AX,R10
-	ADCQ DX,R11
-	MOVQ 88(DI),AX
-	MULQ 176(SP)
-	ADDQ AX,R12
-	ADCQ DX,R13
-	MOVQ 88(DI),AX
-	MULQ 184(SP)
-	ADDQ AX,R14
-	ADCQ DX,R15
-	MOVQ 88(DI),DX
-	IMUL3Q $19,DX,AX
-	MULQ 192(SP)
-	ADDQ AX,SI
-	ADCQ DX,CX
-	MOVQ 96(DI),AX
-	MULQ 160(SP)
-	ADDQ AX,R10
-	ADCQ DX,R11
-	MOVQ 96(DI),AX
-	MULQ 168(SP)
-	ADDQ AX,R12
-	ADCQ DX,R13
-	MOVQ 96(DI),AX
-	MULQ 176(SP)
-	ADDQ AX,R14
-	ADCQ DX,R15
-	MOVQ 96(DI),DX
-	IMUL3Q $19,DX,AX
-	MULQ 184(SP)
-	ADDQ AX,SI
-	ADCQ DX,CX
-	MOVQ 96(DI),DX
-	IMUL3Q $19,DX,AX
-	MULQ 192(SP)
-	ADDQ AX,R8
-	ADCQ DX,R9
-	MOVQ 104(DI),AX
-	MULQ 160(SP)
-	ADDQ AX,R12
-	ADCQ DX,R13
-	MOVQ 104(DI),AX
-	MULQ 168(SP)
-	ADDQ AX,R14
-	ADCQ DX,R15
-	MOVQ 0(SP),AX
-	MULQ 184(SP)
-	ADDQ AX,R8
-	ADCQ DX,R9
-	MOVQ 0(SP),AX
-	MULQ 192(SP)
-	ADDQ AX,R10
-	ADCQ DX,R11
-	MOVQ 112(DI),AX
-	MULQ 160(SP)
-	ADDQ AX,R14
-	ADCQ DX,R15
-	MOVQ 8(SP),AX
-	MULQ 176(SP)
-	ADDQ AX,R8
-	ADCQ DX,R9
-	MOVQ 8(SP),AX
-	MULQ 184(SP)
-	ADDQ AX,R10
-	ADCQ DX,R11
-	MOVQ 8(SP),AX
-	MULQ 192(SP)
-	ADDQ AX,R12
-	ADCQ DX,R13
-	MOVQ $REDMASK51,DX
-	SHLQ $13,SI,CX
-	ANDQ DX,SI
-	SHLQ $13,R8,R9
-	ANDQ DX,R8
-	ADDQ CX,R8
-	SHLQ $13,R10,R11
-	ANDQ DX,R10
-	ADDQ R9,R10
-	SHLQ $13,R12,R13
-	ANDQ DX,R12
-	ADDQ R11,R12
-	SHLQ $13,R14,R15
-	ANDQ DX,R14
-	ADDQ R13,R14
-	IMUL3Q $19,R15,CX
-	ADDQ CX,SI
-	MOVQ SI,CX
-	SHRQ $51,CX
-	ADDQ R8,CX
-	MOVQ CX,R8
-	SHRQ $51,CX
-	ANDQ DX,SI
-	ADDQ R10,CX
-	MOVQ CX,R9
-	SHRQ $51,CX
-	ANDQ DX,R8
-	ADDQ R12,CX
-	MOVQ CX,AX
-	SHRQ $51,CX
-	ANDQ DX,R9
-	ADDQ R14,CX
-	MOVQ CX,R10
-	SHRQ $51,CX
-	ANDQ DX,AX
-	IMUL3Q $19,CX,CX
-	ADDQ CX,SI
-	ANDQ DX,R10
-	MOVQ SI,80(DI)
-	MOVQ R8,88(DI)
-	MOVQ R9,96(DI)
-	MOVQ AX,104(DI)
-	MOVQ R10,112(DI)
-	RET
-
-// func cswap(inout *[4][5]uint64, v uint64)
-TEXT ·cswap(SB),7,$0
-	MOVQ inout+0(FP),DI
-	MOVQ v+8(FP),SI
-
-	SUBQ $1, SI
-	NOTQ SI
-	MOVQ SI, X15
-	PSHUFD $0x44, X15, X15
-
-	MOVOU 0(DI), X0
-	MOVOU 16(DI), X2
-	MOVOU 32(DI), X4
-	MOVOU 48(DI), X6
-	MOVOU 64(DI), X8
-	MOVOU 80(DI), X1
-	MOVOU 96(DI), X3
-	MOVOU 112(DI), X5
-	MOVOU 128(DI), X7
-	MOVOU 144(DI), X9
-
-	MOVO X1, X10
-	MOVO X3, X11
-	MOVO X5, X12
-	MOVO X7, X13
-	MOVO X9, X14
-
-	PXOR X0, X10
-	PXOR X2, X11
-	PXOR X4, X12
-	PXOR X6, X13
-	PXOR X8, X14
-	PAND X15, X10
-	PAND X15, X11
-	PAND X15, X12
-	PAND X15, X13
-	PAND X15, X14
-	PXOR X10, X0
-	PXOR X10, X1
-	PXOR X11, X2
-	PXOR X11, X3
-	PXOR X12, X4
-	PXOR X12, X5
-	PXOR X13, X6
-	PXOR X13, X7
-	PXOR X14, X8
-	PXOR X14, X9
-
-	MOVOU X0, 0(DI)
-	MOVOU X2, 16(DI)
-	MOVOU X4, 32(DI)
-	MOVOU X6, 48(DI)
-	MOVOU X8, 64(DI)
-	MOVOU X1, 80(DI)
-	MOVOU X3, 96(DI)
-	MOVOU X5, 112(DI)
-	MOVOU X7, 128(DI)
-	MOVOU X9, 144(DI)
-	RET
-
-// func mul(dest, a, b *[5]uint64)
-TEXT ·mul(SB),0,$16-24
-	MOVQ dest+0(FP), DI
-	MOVQ a+8(FP), SI
-	MOVQ b+16(FP), DX
-
-	MOVQ DX,CX
-	MOVQ 24(SI),DX
-	IMUL3Q $19,DX,AX
-	MOVQ AX,0(SP)
-	MULQ 16(CX)
-	MOVQ AX,R8
-	MOVQ DX,R9
-	MOVQ 32(SI),DX
-	IMUL3Q $19,DX,AX
-	MOVQ AX,8(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 0(SP),AX
-	MULQ 24(CX)
-	ADDQ AX,R10
-	ADCQ DX,R11
-	MOVQ 0(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 8(SP),AX
-	MULQ 16(CX)
-	ADDQ AX,R10
-	ADCQ DX,R11
-	MOVQ 8(SP),AX
-	MULQ 24(CX)
-	ADDQ AX,R12
-	ADCQ DX,R13
-	MOVQ 8(SP),AX
-	MULQ 32(CX)
-	ADDQ AX,R14
-	ADCQ DX,R15
-	MOVQ $REDMASK51,SI
-	SHLQ $13,R8,R9
-	ANDQ SI,R8
-	SHLQ $13,R10,R11
-	ANDQ SI,R10
-	ADDQ R9,R10
-	SHLQ $13,R12,R13
-	ANDQ SI,R12
-	ADDQ R11,R12
-	SHLQ $13,R14,R15
-	ANDQ SI,R14
-	ADDQ R13,R14
-	SHLQ $13,BX,BP
-	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)
-	RET
-
-// func square(out, in *[5]uint64)
-TEXT ·square(SB),7,$0-16
-	MOVQ out+0(FP), DI
-	MOVQ in+8(FP), SI
-
-	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,SI
-	SHLQ $13,CX,R8
-	ANDQ SI,CX
-	SHLQ $13,R9,R10
-	ANDQ SI,R9
-	ADDQ R8,R9
-	SHLQ $13,R11,R12
-	ANDQ SI,R11
-	ADDQ R10,R11
-	SHLQ $13,R13,R14
-	ANDQ SI,R13
-	ADDQ R12,R13
-	SHLQ $13,R15,BX
-	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)
-	RET
diff --git a/vendor/golang.org/x/crypto/curve25519/curve25519_generic.go b/vendor/golang.org/x/crypto/curve25519/curve25519_generic.go
deleted file mode 100644
index c43b13fc83..0000000000
--- a/vendor/golang.org/x/crypto/curve25519/curve25519_generic.go
+++ /dev/null
@@ -1,828 +0,0 @@
-// 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.
-
-package curve25519
-
-import "encoding/binary"
-
-// 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) {
-	b = -b
-	for i := range f {
-		t := b & (f[i] ^ g[i])
-		f[i] ^= t
-		g[i] ^= t
-	}
-}
-
-// 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 {
-	return int64(binary.LittleEndian.Uint32(in))
-}
-
-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:]) & 0x7fffff) << 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 scalarMultGeneric(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)
-}
diff --git a/vendor/golang.org/x/crypto/curve25519/curve25519_noasm.go b/vendor/golang.org/x/crypto/curve25519/curve25519_noasm.go
deleted file mode 100644
index 047d49afc2..0000000000
--- a/vendor/golang.org/x/crypto/curve25519/curve25519_noasm.go
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2019 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 purego
-
-package curve25519
-
-func scalarMult(out, in, base *[32]byte) {
-	scalarMultGeneric(out, in, base)
-}
diff --git a/vendor/golang.org/x/crypto/curve25519/internal/field/README b/vendor/golang.org/x/crypto/curve25519/internal/field/README
new file mode 100644
index 0000000000..e25bca7dc8
--- /dev/null
+++ b/vendor/golang.org/x/crypto/curve25519/internal/field/README
@@ -0,0 +1,7 @@
+This package is kept in sync with crypto/ed25519/internal/edwards25519/field in
+the standard library.
+
+If there are any changes in the standard library that need to be synced to this
+package, run sync.sh. It will not overwrite any local changes made since the
+previous sync, so it's ok to land changes in this package first, and then sync
+to the standard library later.
diff --git a/vendor/golang.org/x/crypto/curve25519/internal/field/_asm/fe_amd64_asm.go b/vendor/golang.org/x/crypto/curve25519/internal/field/_asm/fe_amd64_asm.go
new file mode 100644
index 0000000000..1f3652987e
--- /dev/null
+++ b/vendor/golang.org/x/crypto/curve25519/internal/field/_asm/fe_amd64_asm.go
@@ -0,0 +1,298 @@
+// Copyright (c) 2021 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 main
+
+import (
+	"fmt"
+
+	. "github.com/mmcloughlin/avo/build"
+	. "github.com/mmcloughlin/avo/gotypes"
+	. "github.com/mmcloughlin/avo/operand"
+	. "github.com/mmcloughlin/avo/reg"
+
+	// Ensure "go mod tidy" doesn't remove the golang.org/x/crypto module
+	// dependency, which is necessary to access the field.Element type.
+	_ "golang.org/x/crypto/curve25519"
+)
+
+//go:generate go run . -out ../fe_amd64.s -stubs ../fe_amd64.go -pkg field
+
+func main() {
+	Package("golang.org/x/crypto/curve25519/internal/field")
+	ConstraintExpr("amd64,gc,!purego")
+	feMul()
+	feSquare()
+	Generate()
+}
+
+type namedComponent struct {
+	Component
+	name string
+}
+
+func (c namedComponent) String() string { return c.name }
+
+type uint128 struct {
+	name   string
+	hi, lo GPVirtual
+}
+
+func (c uint128) String() string { return c.name }
+
+func feSquare() {
+	TEXT("feSquare", NOSPLIT, "func(out, a *Element)")
+	Doc("feSquare sets out = a * a. It works like feSquareGeneric.")
+	Pragma("noescape")
+
+	a := Dereference(Param("a"))
+	l0 := namedComponent{a.Field("l0"), "l0"}
+	l1 := namedComponent{a.Field("l1"), "l1"}
+	l2 := namedComponent{a.Field("l2"), "l2"}
+	l3 := namedComponent{a.Field("l3"), "l3"}
+	l4 := namedComponent{a.Field("l4"), "l4"}
+
+	// r0 = l0×l0 + 19×2×(l1×l4 + l2×l3)
+	r0 := uint128{"r0", GP64(), GP64()}
+	mul64(r0, 1, l0, l0)
+	addMul64(r0, 38, l1, l4)
+	addMul64(r0, 38, l2, l3)
+
+	// r1 = 2×l0×l1 + 19×2×l2×l4 + 19×l3×l3
+	r1 := uint128{"r1", GP64(), GP64()}
+	mul64(r1, 2, l0, l1)
+	addMul64(r1, 38, l2, l4)
+	addMul64(r1, 19, l3, l3)
+
+	// r2 = = 2×l0×l2 + l1×l1 + 19×2×l3×l4
+	r2 := uint128{"r2", GP64(), GP64()}
+	mul64(r2, 2, l0, l2)
+	addMul64(r2, 1, l1, l1)
+	addMul64(r2, 38, l3, l4)
+
+	// r3 = = 2×l0×l3 + 2×l1×l2 + 19×l4×l4
+	r3 := uint128{"r3", GP64(), GP64()}
+	mul64(r3, 2, l0, l3)
+	addMul64(r3, 2, l1, l2)
+	addMul64(r3, 19, l4, l4)
+
+	// r4 = = 2×l0×l4 + 2×l1×l3 + l2×l2
+	r4 := uint128{"r4", GP64(), GP64()}
+	mul64(r4, 2, l0, l4)
+	addMul64(r4, 2, l1, l3)
+	addMul64(r4, 1, l2, l2)
+
+	Comment("First reduction chain")
+	maskLow51Bits := GP64()
+	MOVQ(Imm((1<<51)-1), maskLow51Bits)
+	c0, r0lo := shiftRightBy51(&r0)
+	c1, r1lo := shiftRightBy51(&r1)
+	c2, r2lo := shiftRightBy51(&r2)
+	c3, r3lo := shiftRightBy51(&r3)
+	c4, r4lo := shiftRightBy51(&r4)
+	maskAndAdd(r0lo, maskLow51Bits, c4, 19)
+	maskAndAdd(r1lo, maskLow51Bits, c0, 1)
+	maskAndAdd(r2lo, maskLow51Bits, c1, 1)
+	maskAndAdd(r3lo, maskLow51Bits, c2, 1)
+	maskAndAdd(r4lo, maskLow51Bits, c3, 1)
+
+	Comment("Second reduction chain (carryPropagate)")
+	// c0 = r0 >> 51
+	MOVQ(r0lo, c0)
+	SHRQ(Imm(51), c0)
+	// c1 = r1 >> 51
+	MOVQ(r1lo, c1)
+	SHRQ(Imm(51), c1)
+	// c2 = r2 >> 51
+	MOVQ(r2lo, c2)
+	SHRQ(Imm(51), c2)
+	// c3 = r3 >> 51
+	MOVQ(r3lo, c3)
+	SHRQ(Imm(51), c3)
+	// c4 = r4 >> 51
+	MOVQ(r4lo, c4)
+	SHRQ(Imm(51), c4)
+	maskAndAdd(r0lo, maskLow51Bits, c4, 19)
+	maskAndAdd(r1lo, maskLow51Bits, c0, 1)
+	maskAndAdd(r2lo, maskLow51Bits, c1, 1)
+	maskAndAdd(r3lo, maskLow51Bits, c2, 1)
+	maskAndAdd(r4lo, maskLow51Bits, c3, 1)
+
+	Comment("Store output")
+	out := Dereference(Param("out"))
+	Store(r0lo, out.Field("l0"))
+	Store(r1lo, out.Field("l1"))
+	Store(r2lo, out.Field("l2"))
+	Store(r3lo, out.Field("l3"))
+	Store(r4lo, out.Field("l4"))
+
+	RET()
+}
+
+func feMul() {
+	TEXT("feMul", NOSPLIT, "func(out, a, b *Element)")
+	Doc("feMul sets out = a * b. It works like feMulGeneric.")
+	Pragma("noescape")
+
+	a := Dereference(Param("a"))
+	a0 := namedComponent{a.Field("l0"), "a0"}
+	a1 := namedComponent{a.Field("l1"), "a1"}
+	a2 := namedComponent{a.Field("l2"), "a2"}
+	a3 := namedComponent{a.Field("l3"), "a3"}
+	a4 := namedComponent{a.Field("l4"), "a4"}
+
+	b := Dereference(Param("b"))
+	b0 := namedComponent{b.Field("l0"), "b0"}
+	b1 := namedComponent{b.Field("l1"), "b1"}
+	b2 := namedComponent{b.Field("l2"), "b2"}
+	b3 := namedComponent{b.Field("l3"), "b3"}
+	b4 := namedComponent{b.Field("l4"), "b4"}
+
+	// r0 = a0×b0 + 19×(a1×b4 + a2×b3 + a3×b2 + a4×b1)
+	r0 := uint128{"r0", GP64(), GP64()}
+	mul64(r0, 1, a0, b0)
+	addMul64(r0, 19, a1, b4)
+	addMul64(r0, 19, a2, b3)
+	addMul64(r0, 19, a3, b2)
+	addMul64(r0, 19, a4, b1)
+
+	// r1 = a0×b1 + a1×b0 + 19×(a2×b4 + a3×b3 + a4×b2)
+	r1 := uint128{"r1", GP64(), GP64()}
+	mul64(r1, 1, a0, b1)
+	addMul64(r1, 1, a1, b0)
+	addMul64(r1, 19, a2, b4)
+	addMul64(r1, 19, a3, b3)
+	addMul64(r1, 19, a4, b2)
+
+	// r2 = a0×b2 + a1×b1 + a2×b0 + 19×(a3×b4 + a4×b3)
+	r2 := uint128{"r2", GP64(), GP64()}
+	mul64(r2, 1, a0, b2)
+	addMul64(r2, 1, a1, b1)
+	addMul64(r2, 1, a2, b0)
+	addMul64(r2, 19, a3, b4)
+	addMul64(r2, 19, a4, b3)
+
+	// r3 = a0×b3 + a1×b2 + a2×b1 + a3×b0 + 19×a4×b4
+	r3 := uint128{"r3", GP64(), GP64()}
+	mul64(r3, 1, a0, b3)
+	addMul64(r3, 1, a1, b2)
+	addMul64(r3, 1, a2, b1)
+	addMul64(r3, 1, a3, b0)
+	addMul64(r3, 19, a4, b4)
+
+	// r4 = a0×b4 + a1×b3 + a2×b2 + a3×b1 + a4×b0
+	r4 := uint128{"r4", GP64(), GP64()}
+	mul64(r4, 1, a0, b4)
+	addMul64(r4, 1, a1, b3)
+	addMul64(r4, 1, a2, b2)
+	addMul64(r4, 1, a3, b1)
+	addMul64(r4, 1, a4, b0)
+
+	Comment("First reduction chain")
+	maskLow51Bits := GP64()
+	MOVQ(Imm((1<<51)-1), maskLow51Bits)
+	c0, r0lo := shiftRightBy51(&r0)
+	c1, r1lo := shiftRightBy51(&r1)
+	c2, r2lo := shiftRightBy51(&r2)
+	c3, r3lo := shiftRightBy51(&r3)
+	c4, r4lo := shiftRightBy51(&r4)
+	maskAndAdd(r0lo, maskLow51Bits, c4, 19)
+	maskAndAdd(r1lo, maskLow51Bits, c0, 1)
+	maskAndAdd(r2lo, maskLow51Bits, c1, 1)
+	maskAndAdd(r3lo, maskLow51Bits, c2, 1)
+	maskAndAdd(r4lo, maskLow51Bits, c3, 1)
+
+	Comment("Second reduction chain (carryPropagate)")
+	// c0 = r0 >> 51
+	MOVQ(r0lo, c0)
+	SHRQ(Imm(51), c0)
+	// c1 = r1 >> 51
+	MOVQ(r1lo, c1)
+	SHRQ(Imm(51), c1)
+	// c2 = r2 >> 51
+	MOVQ(r2lo, c2)
+	SHRQ(Imm(51), c2)
+	// c3 = r3 >> 51
+	MOVQ(r3lo, c3)
+	SHRQ(Imm(51), c3)
+	// c4 = r4 >> 51
+	MOVQ(r4lo, c4)
+	SHRQ(Imm(51), c4)
+	maskAndAdd(r0lo, maskLow51Bits, c4, 19)
+	maskAndAdd(r1lo, maskLow51Bits, c0, 1)
+	maskAndAdd(r2lo, maskLow51Bits, c1, 1)
+	maskAndAdd(r3lo, maskLow51Bits, c2, 1)
+	maskAndAdd(r4lo, maskLow51Bits, c3, 1)
+
+	Comment("Store output")
+	out := Dereference(Param("out"))
+	Store(r0lo, out.Field("l0"))
+	Store(r1lo, out.Field("l1"))
+	Store(r2lo, out.Field("l2"))
+	Store(r3lo, out.Field("l3"))
+	Store(r4lo, out.Field("l4"))
+
+	RET()
+}
+
+// mul64 sets r to i * aX * bX.
+func mul64(r uint128, i int, aX, bX namedComponent) {
+	switch i {
+	case 1:
+		Comment(fmt.Sprintf("%s = %s×%s", r, aX, bX))
+		Load(aX, RAX)
+	case 2:
+		Comment(fmt.Sprintf("%s = 2×%s×%s", r, aX, bX))
+		Load(aX, RAX)
+		SHLQ(Imm(1), RAX)
+	default:
+		panic("unsupported i value")
+	}
+	MULQ(mustAddr(bX)) // RDX, RAX = RAX * bX
+	MOVQ(RAX, r.lo)
+	MOVQ(RDX, r.hi)
+}
+
+// addMul64 sets r to r + i * aX * bX.
+func addMul64(r uint128, i uint64, aX, bX namedComponent) {
+	switch i {
+	case 1:
+		Comment(fmt.Sprintf("%s += %s×%s", r, aX, bX))
+		Load(aX, RAX)
+	default:
+		Comment(fmt.Sprintf("%s += %d×%s×%s", r, i, aX, bX))
+		IMUL3Q(Imm(i), Load(aX, GP64()), RAX)
+	}
+	MULQ(mustAddr(bX)) // RDX, RAX = RAX * bX
+	ADDQ(RAX, r.lo)
+	ADCQ(RDX, r.hi)
+}
+
+// shiftRightBy51 returns r >> 51 and r.lo.
+//
+// After this function is called, the uint128 may not be used anymore.
+func shiftRightBy51(r *uint128) (out, lo GPVirtual) {
+	out = r.hi
+	lo = r.lo
+	SHLQ(Imm(64-51), r.lo, r.hi)
+	r.lo, r.hi = nil, nil // make sure the uint128 is unusable
+	return
+}
+
+// maskAndAdd sets r = r&mask + c*i.
+func maskAndAdd(r, mask, c GPVirtual, i uint64) {
+	ANDQ(mask, r)
+	if i != 1 {
+		IMUL3Q(Imm(i), c, c)
+	}
+	ADDQ(c, r)
+}
+
+func mustAddr(c Component) Op {
+	b, err := c.Resolve()
+	if err != nil {
+		panic(err)
+	}
+	return b.Addr
+}
diff --git a/vendor/golang.org/x/crypto/curve25519/internal/field/_asm/go.mod b/vendor/golang.org/x/crypto/curve25519/internal/field/_asm/go.mod
new file mode 100644
index 0000000000..fbc78be881
--- /dev/null
+++ b/vendor/golang.org/x/crypto/curve25519/internal/field/_asm/go.mod
@@ -0,0 +1,10 @@
+module asm
+
+go 1.16
+
+require (
+	github.com/mmcloughlin/avo v0.2.0
+	golang.org/x/crypto v0.0.0
+)
+
+replace golang.org/x/crypto v0.0.0 => ../../../..
diff --git a/vendor/golang.org/x/crypto/curve25519/internal/field/_asm/go.sum b/vendor/golang.org/x/crypto/curve25519/internal/field/_asm/go.sum
new file mode 100644
index 0000000000..e2361f6ab4
--- /dev/null
+++ b/vendor/golang.org/x/crypto/curve25519/internal/field/_asm/go.sum
@@ -0,0 +1,34 @@
+github.com/mmcloughlin/avo v0.2.0 h1:6vhoSaKtxb6f4RiH+LK2qL6GSMpFzhEwJYTTSZNy09w=
+github.com/mmcloughlin/avo v0.2.0/go.mod h1:5tidO2Z9Z7N6X7UMcGg+1KTj51O8OxYDCMHxCZTVpEA=
+github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+golang.org/x/arch v0.0.0-20210405154355-08b684f594a5/go.mod h1:flIaEI6LNU6xOCD5PaJvn9wGP0agmIOqjrtsKGRguv4=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=
+golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
+golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57 h1:F5Gozwx4I1xtr/sr/8CFbb57iKi3297KFs0QDbGN60A=
+golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.1.0 h1:po9/4sTYwZU9lPhi1tOrb4hCv3qrhiQ77LZfGa2OjwY=
+golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
+golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
diff --git a/vendor/golang.org/x/crypto/curve25519/internal/field/fe.go b/vendor/golang.org/x/crypto/curve25519/internal/field/fe.go
new file mode 100644
index 0000000000..ca841ad99e
--- /dev/null
+++ b/vendor/golang.org/x/crypto/curve25519/internal/field/fe.go
@@ -0,0 +1,416 @@
+// Copyright (c) 2017 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 field implements fast arithmetic modulo 2^255-19.
+package field
+
+import (
+	"crypto/subtle"
+	"encoding/binary"
+	"math/bits"
+)
+
+// Element represents an element of the field GF(2^255-19). Note that this
+// is not a cryptographically secure group, and should only be used to interact
+// with edwards25519.Point coordinates.
+//
+// This type works similarly to math/big.Int, and all arguments and receivers
+// are allowed to alias.
+//
+// The zero value is a valid zero element.
+type Element struct {
+	// An element t represents the integer
+	//     t.l0 + t.l1*2^51 + t.l2*2^102 + t.l3*2^153 + t.l4*2^204
+	//
+	// Between operations, all limbs are expected to be lower than 2^52.
+	l0 uint64
+	l1 uint64
+	l2 uint64
+	l3 uint64
+	l4 uint64
+}
+
+const maskLow51Bits uint64 = (1 << 51) - 1
+
+var feZero = &Element{0, 0, 0, 0, 0}
+
+// Zero sets v = 0, and returns v.
+func (v *Element) Zero() *Element {
+	*v = *feZero
+	return v
+}
+
+var feOne = &Element{1, 0, 0, 0, 0}
+
+// One sets v = 1, and returns v.
+func (v *Element) One() *Element {
+	*v = *feOne
+	return v
+}
+
+// reduce reduces v modulo 2^255 - 19 and returns it.
+func (v *Element) reduce() *Element {
+	v.carryPropagate()
+
+	// After the light reduction we now have a field element representation
+	// v < 2^255 + 2^13 * 19, but need v < 2^255 - 19.
+
+	// If v >= 2^255 - 19, then v + 19 >= 2^255, which would overflow 2^255 - 1,
+	// generating a carry. That is, c will be 0 if v < 2^255 - 19, and 1 otherwise.
+	c := (v.l0 + 19) >> 51
+	c = (v.l1 + c) >> 51
+	c = (v.l2 + c) >> 51
+	c = (v.l3 + c) >> 51
+	c = (v.l4 + c) >> 51
+
+	// If v < 2^255 - 19 and c = 0, this will be a no-op. Otherwise, it's
+	// effectively applying the reduction identity to the carry.
+	v.l0 += 19 * c
+
+	v.l1 += v.l0 >> 51
+	v.l0 = v.l0 & maskLow51Bits
+	v.l2 += v.l1 >> 51
+	v.l1 = v.l1 & maskLow51Bits
+	v.l3 += v.l2 >> 51
+	v.l2 = v.l2 & maskLow51Bits
+	v.l4 += v.l3 >> 51
+	v.l3 = v.l3 & maskLow51Bits
+	// no additional carry
+	v.l4 = v.l4 & maskLow51Bits
+
+	return v
+}
+
+// Add sets v = a + b, and returns v.
+func (v *Element) Add(a, b *Element) *Element {
+	v.l0 = a.l0 + b.l0
+	v.l1 = a.l1 + b.l1
+	v.l2 = a.l2 + b.l2
+	v.l3 = a.l3 + b.l3
+	v.l4 = a.l4 + b.l4
+	// Using the generic implementation here is actually faster than the
+	// assembly. Probably because the body of this function is so simple that
+	// the compiler can figure out better optimizations by inlining the carry
+	// propagation. TODO
+	return v.carryPropagateGeneric()
+}
+
+// Subtract sets v = a - b, and returns v.
+func (v *Element) Subtract(a, b *Element) *Element {
+	// We first add 2 * p, to guarantee the subtraction won't underflow, and
+	// then subtract b (which can be up to 2^255 + 2^13 * 19).
+	v.l0 = (a.l0 + 0xFFFFFFFFFFFDA) - b.l0
+	v.l1 = (a.l1 + 0xFFFFFFFFFFFFE) - b.l1
+	v.l2 = (a.l2 + 0xFFFFFFFFFFFFE) - b.l2
+	v.l3 = (a.l3 + 0xFFFFFFFFFFFFE) - b.l3
+	v.l4 = (a.l4 + 0xFFFFFFFFFFFFE) - b.l4
+	return v.carryPropagate()
+}
+
+// Negate sets v = -a, and returns v.
+func (v *Element) Negate(a *Element) *Element {
+	return v.Subtract(feZero, a)
+}
+
+// Invert sets v = 1/z mod p, and returns v.
+//
+// If z == 0, Invert returns v = 0.
+func (v *Element) Invert(z *Element) *Element {
+	// Inversion is implemented as exponentiation with exponent p − 2. It uses the
+	// same sequence of 255 squarings and 11 multiplications as [Curve25519].
+	var z2, z9, z11, z2_5_0, z2_10_0, z2_20_0, z2_50_0, z2_100_0, t Element
+
+	z2.Square(z)             // 2
+	t.Square(&z2)            // 4
+	t.Square(&t)             // 8
+	z9.Multiply(&t, z)       // 9
+	z11.Multiply(&z9, &z2)   // 11
+	t.Square(&z11)           // 22
+	z2_5_0.Multiply(&t, &z9) // 31 = 2^5 - 2^0
+
+	t.Square(&z2_5_0) // 2^6 - 2^1
+	for i := 0; i < 4; i++ {
+		t.Square(&t) // 2^10 - 2^5
+	}
+	z2_10_0.Multiply(&t, &z2_5_0) // 2^10 - 2^0
+
+	t.Square(&z2_10_0) // 2^11 - 2^1
+	for i := 0; i < 9; i++ {
+		t.Square(&t) // 2^20 - 2^10
+	}
+	z2_20_0.Multiply(&t, &z2_10_0) // 2^20 - 2^0
+
+	t.Square(&z2_20_0) // 2^21 - 2^1
+	for i := 0; i < 19; i++ {
+		t.Square(&t) // 2^40 - 2^20
+	}
+	t.Multiply(&t, &z2_20_0) // 2^40 - 2^0
+
+	t.Square(&t) // 2^41 - 2^1
+	for i := 0; i < 9; i++ {
+		t.Square(&t) // 2^50 - 2^10
+	}
+	z2_50_0.Multiply(&t, &z2_10_0) // 2^50 - 2^0
+
+	t.Square(&z2_50_0) // 2^51 - 2^1
+	for i := 0; i < 49; i++ {
+		t.Square(&t) // 2^100 - 2^50
+	}
+	z2_100_0.Multiply(&t, &z2_50_0) // 2^100 - 2^0
+
+	t.Square(&z2_100_0) // 2^101 - 2^1
+	for i := 0; i < 99; i++ {
+		t.Square(&t) // 2^200 - 2^100
+	}
+	t.Multiply(&t, &z2_100_0) // 2^200 - 2^0
+
+	t.Square(&t) // 2^201 - 2^1
+	for i := 0; i < 49; i++ {
+		t.Square(&t) // 2^250 - 2^50
+	}
+	t.Multiply(&t, &z2_50_0) // 2^250 - 2^0
+
+	t.Square(&t) // 2^251 - 2^1
+	t.Square(&t) // 2^252 - 2^2
+	t.Square(&t) // 2^253 - 2^3
+	t.Square(&t) // 2^254 - 2^4
+	t.Square(&t) // 2^255 - 2^5
+
+	return v.Multiply(&t, &z11) // 2^255 - 21
+}
+
+// Set sets v = a, and returns v.
+func (v *Element) Set(a *Element) *Element {
+	*v = *a
+	return v
+}
+
+// SetBytes sets v to x, which must be a 32-byte little-endian encoding.
+//
+// Consistent with RFC 7748, the most significant bit (the high bit of the
+// last byte) is ignored, and non-canonical values (2^255-19 through 2^255-1)
+// are accepted. Note that this is laxer than specified by RFC 8032.
+func (v *Element) SetBytes(x []byte) *Element {
+	if len(x) != 32 {
+		panic("edwards25519: invalid field element input size")
+	}
+
+	// Bits 0:51 (bytes 0:8, bits 0:64, shift 0, mask 51).
+	v.l0 = binary.LittleEndian.Uint64(x[0:8])
+	v.l0 &= maskLow51Bits
+	// Bits 51:102 (bytes 6:14, bits 48:112, shift 3, mask 51).
+	v.l1 = binary.LittleEndian.Uint64(x[6:14]) >> 3
+	v.l1 &= maskLow51Bits
+	// Bits 102:153 (bytes 12:20, bits 96:160, shift 6, mask 51).
+	v.l2 = binary.LittleEndian.Uint64(x[12:20]) >> 6
+	v.l2 &= maskLow51Bits
+	// Bits 153:204 (bytes 19:27, bits 152:216, shift 1, mask 51).
+	v.l3 = binary.LittleEndian.Uint64(x[19:27]) >> 1
+	v.l3 &= maskLow51Bits
+	// Bits 204:251 (bytes 24:32, bits 192:256, shift 12, mask 51).
+	// Note: not bytes 25:33, shift 4, to avoid overread.
+	v.l4 = binary.LittleEndian.Uint64(x[24:32]) >> 12
+	v.l4 &= maskLow51Bits
+
+	return v
+}
+
+// Bytes returns the canonical 32-byte little-endian encoding of v.
+func (v *Element) Bytes() []byte {
+	// This function is outlined to make the allocations inline in the caller
+	// rather than happen on the heap.
+	var out [32]byte
+	return v.bytes(&out)
+}
+
+func (v *Element) bytes(out *[32]byte) []byte {
+	t := *v
+	t.reduce()
+
+	var buf [8]byte
+	for i, l := range [5]uint64{t.l0, t.l1, t.l2, t.l3, t.l4} {
+		bitsOffset := i * 51
+		binary.LittleEndian.PutUint64(buf[:], l<<uint(bitsOffset%8))
+		for i, bb := range buf {
+			off := bitsOffset/8 + i
+			if off >= len(out) {
+				break
+			}
+			out[off] |= bb
+		}
+	}
+
+	return out[:]
+}
+
+// Equal returns 1 if v and u are equal, and 0 otherwise.
+func (v *Element) Equal(u *Element) int {
+	sa, sv := u.Bytes(), v.Bytes()
+	return subtle.ConstantTimeCompare(sa, sv)
+}
+
+// mask64Bits returns 0xffffffff if cond is 1, and 0 otherwise.
+func mask64Bits(cond int) uint64 { return ^(uint64(cond) - 1) }
+
+// Select sets v to a if cond == 1, and to b if cond == 0.
+func (v *Element) Select(a, b *Element, cond int) *Element {
+	m := mask64Bits(cond)
+	v.l0 = (m & a.l0) | (^m & b.l0)
+	v.l1 = (m & a.l1) | (^m & b.l1)
+	v.l2 = (m & a.l2) | (^m & b.l2)
+	v.l3 = (m & a.l3) | (^m & b.l3)
+	v.l4 = (m & a.l4) | (^m & b.l4)
+	return v
+}
+
+// Swap swaps v and u if cond == 1 or leaves them unchanged if cond == 0, and returns v.
+func (v *Element) Swap(u *Element, cond int) {
+	m := mask64Bits(cond)
+	t := m & (v.l0 ^ u.l0)
+	v.l0 ^= t
+	u.l0 ^= t
+	t = m & (v.l1 ^ u.l1)
+	v.l1 ^= t
+	u.l1 ^= t
+	t = m & (v.l2 ^ u.l2)
+	v.l2 ^= t
+	u.l2 ^= t
+	t = m & (v.l3 ^ u.l3)
+	v.l3 ^= t
+	u.l3 ^= t
+	t = m & (v.l4 ^ u.l4)
+	v.l4 ^= t
+	u.l4 ^= t
+}
+
+// IsNegative returns 1 if v is negative, and 0 otherwise.
+func (v *Element) IsNegative() int {
+	return int(v.Bytes()[0] & 1)
+}
+
+// Absolute sets v to |u|, and returns v.
+func (v *Element) Absolute(u *Element) *Element {
+	return v.Select(new(Element).Negate(u), u, u.IsNegative())
+}
+
+// Multiply sets v = x * y, and returns v.
+func (v *Element) Multiply(x, y *Element) *Element {
+	feMul(v, x, y)
+	return v
+}
+
+// Square sets v = x * x, and returns v.
+func (v *Element) Square(x *Element) *Element {
+	feSquare(v, x)
+	return v
+}
+
+// Mult32 sets v = x * y, and returns v.
+func (v *Element) Mult32(x *Element, y uint32) *Element {
+	x0lo, x0hi := mul51(x.l0, y)
+	x1lo, x1hi := mul51(x.l1, y)
+	x2lo, x2hi := mul51(x.l2, y)
+	x3lo, x3hi := mul51(x.l3, y)
+	x4lo, x4hi := mul51(x.l4, y)
+	v.l0 = x0lo + 19*x4hi // carried over per the reduction identity
+	v.l1 = x1lo + x0hi
+	v.l2 = x2lo + x1hi
+	v.l3 = x3lo + x2hi
+	v.l4 = x4lo + x3hi
+	// The hi portions are going to be only 32 bits, plus any previous excess,
+	// so we can skip the carry propagation.
+	return v
+}
+
+// mul51 returns lo + hi * 2⁵¹ = a * b.
+func mul51(a uint64, b uint32) (lo uint64, hi uint64) {
+	mh, ml := bits.Mul64(a, uint64(b))
+	lo = ml & maskLow51Bits
+	hi = (mh << 13) | (ml >> 51)
+	return
+}
+
+// Pow22523 set v = x^((p-5)/8), and returns v. (p-5)/8 is 2^252-3.
+func (v *Element) Pow22523(x *Element) *Element {
+	var t0, t1, t2 Element
+
+	t0.Square(x)             // x^2
+	t1.Square(&t0)           // x^4
+	t1.Square(&t1)           // x^8
+	t1.Multiply(x, &t1)      // x^9
+	t0.Multiply(&t0, &t1)    // x^11
+	t0.Square(&t0)           // x^22
+	t0.Multiply(&t1, &t0)    // x^31
+	t1.Square(&t0)           // x^62
+	for i := 1; i < 5; i++ { // x^992
+		t1.Square(&t1)
+	}
+	t0.Multiply(&t1, &t0)     // x^1023 -> 1023 = 2^10 - 1
+	t1.Square(&t0)            // 2^11 - 2
+	for i := 1; i < 10; i++ { // 2^20 - 2^10
+		t1.Square(&t1)
+	}
+	t1.Multiply(&t1, &t0)     // 2^20 - 1
+	t2.Square(&t1)            // 2^21 - 2
+	for i := 1; i < 20; i++ { // 2^40 - 2^20
+		t2.Square(&t2)
+	}
+	t1.Multiply(&t2, &t1)     // 2^40 - 1
+	t1.Square(&t1)            // 2^41 - 2
+	for i := 1; i < 10; i++ { // 2^50 - 2^10
+		t1.Square(&t1)
+	}
+	t0.Multiply(&t1, &t0)     // 2^50 - 1
+	t1.Square(&t0)            // 2^51 - 2
+	for i := 1; i < 50; i++ { // 2^100 - 2^50
+		t1.Square(&t1)
+	}
+	t1.Multiply(&t1, &t0)      // 2^100 - 1
+	t2.Square(&t1)             // 2^101 - 2
+	for i := 1; i < 100; i++ { // 2^200 - 2^100
+		t2.Square(&t2)
+	}
+	t1.Multiply(&t2, &t1)     // 2^200 - 1
+	t1.Square(&t1)            // 2^201 - 2
+	for i := 1; i < 50; i++ { // 2^250 - 2^50
+		t1.Square(&t1)
+	}
+	t0.Multiply(&t1, &t0)     // 2^250 - 1
+	t0.Square(&t0)            // 2^251 - 2
+	t0.Square(&t0)            // 2^252 - 4
+	return v.Multiply(&t0, x) // 2^252 - 3 -> x^(2^252-3)
+}
+
+// sqrtM1 is 2^((p-1)/4), which squared is equal to -1 by Euler's Criterion.
+var sqrtM1 = &Element{1718705420411056, 234908883556509,
+	2233514472574048, 2117202627021982, 765476049583133}
+
+// SqrtRatio sets r to the non-negative square root of the ratio of u and v.
+//
+// If u/v is square, SqrtRatio returns r and 1. If u/v is not square, SqrtRatio
+// sets r according to Section 4.3 of draft-irtf-cfrg-ristretto255-decaf448-00,
+// and returns r and 0.
+func (r *Element) SqrtRatio(u, v *Element) (rr *Element, wasSquare int) {
+	var a, b Element
+
+	// r = (u * v3) * (u * v7)^((p-5)/8)
+	v2 := a.Square(v)
+	uv3 := b.Multiply(u, b.Multiply(v2, v))
+	uv7 := a.Multiply(uv3, a.Square(v2))
+	r.Multiply(uv3, r.Pow22523(uv7))
+
+	check := a.Multiply(v, a.Square(r)) // check = v * r^2
+
+	uNeg := b.Negate(u)
+	correctSignSqrt := check.Equal(u)
+	flippedSignSqrt := check.Equal(uNeg)
+	flippedSignSqrtI := check.Equal(uNeg.Multiply(uNeg, sqrtM1))
+
+	rPrime := b.Multiply(r, sqrtM1) // r_prime = SQRT_M1 * r
+	// r = CT_SELECT(r_prime IF flipped_sign_sqrt | flipped_sign_sqrt_i ELSE r)
+	r.Select(rPrime, r, flippedSignSqrt|flippedSignSqrtI)
+
+	r.Absolute(r) // Choose the nonnegative square root.
+	return r, correctSignSqrt | flippedSignSqrt
+}
diff --git a/vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64.go b/vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64.go
new file mode 100644
index 0000000000..44dc8e8caf
--- /dev/null
+++ b/vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64.go
@@ -0,0 +1,13 @@
+// Code generated by command: go run fe_amd64_asm.go -out ../fe_amd64.s -stubs ../fe_amd64.go -pkg field. DO NOT EDIT.
+
+// +build amd64,gc,!purego
+
+package field
+
+// feMul sets out = a * b. It works like feMulGeneric.
+//go:noescape
+func feMul(out *Element, a *Element, b *Element)
+
+// feSquare sets out = a * a. It works like feSquareGeneric.
+//go:noescape
+func feSquare(out *Element, a *Element)
diff --git a/vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64.s b/vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64.s
new file mode 100644
index 0000000000..293f013c94
--- /dev/null
+++ b/vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64.s
@@ -0,0 +1,379 @@
+// Code generated by command: go run fe_amd64_asm.go -out ../fe_amd64.s -stubs ../fe_amd64.go -pkg field. DO NOT EDIT.
+
+//go:build amd64 && gc && !purego
+// +build amd64,gc,!purego
+
+#include "textflag.h"
+
+// func feMul(out *Element, a *Element, b *Element)
+TEXT ·feMul(SB), NOSPLIT, $0-24
+	MOVQ a+8(FP), CX
+	MOVQ b+16(FP), BX
+
+	// r0 = a0×b0
+	MOVQ (CX), AX
+	MULQ (BX)
+	MOVQ AX, DI
+	MOVQ DX, SI
+
+	// r0 += 19×a1×b4
+	MOVQ   8(CX), AX
+	IMUL3Q $0x13, AX, AX
+	MULQ   32(BX)
+	ADDQ   AX, DI
+	ADCQ   DX, SI
+
+	// r0 += 19×a2×b3
+	MOVQ   16(CX), AX
+	IMUL3Q $0x13, AX, AX
+	MULQ   24(BX)
+	ADDQ   AX, DI
+	ADCQ   DX, SI
+
+	// r0 += 19×a3×b2
+	MOVQ   24(CX), AX
+	IMUL3Q $0x13, AX, AX
+	MULQ   16(BX)
+	ADDQ   AX, DI
+	ADCQ   DX, SI
+
+	// r0 += 19×a4×b1
+	MOVQ   32(CX), AX
+	IMUL3Q $0x13, AX, AX
+	MULQ   8(BX)
+	ADDQ   AX, DI
+	ADCQ   DX, SI
+
+	// r1 = a0×b1
+	MOVQ (CX), AX
+	MULQ 8(BX)
+	MOVQ AX, R9
+	MOVQ DX, R8
+
+	// r1 += a1×b0
+	MOVQ 8(CX), AX
+	MULQ (BX)
+	ADDQ AX, R9
+	ADCQ DX, R8
+
+	// r1 += 19×a2×b4
+	MOVQ   16(CX), AX
+	IMUL3Q $0x13, AX, AX
+	MULQ   32(BX)
+	ADDQ   AX, R9
+	ADCQ   DX, R8
+
+	// r1 += 19×a3×b3
+	MOVQ   24(CX), AX
+	IMUL3Q $0x13, AX, AX
+	MULQ   24(BX)
+	ADDQ   AX, R9
+	ADCQ   DX, R8
+
+	// r1 += 19×a4×b2
+	MOVQ   32(CX), AX
+	IMUL3Q $0x13, AX, AX
+	MULQ   16(BX)
+	ADDQ   AX, R9
+	ADCQ   DX, R8
+
+	// r2 = a0×b2
+	MOVQ (CX), AX
+	MULQ 16(BX)
+	MOVQ AX, R11
+	MOVQ DX, R10
+
+	// r2 += a1×b1
+	MOVQ 8(CX), AX
+	MULQ 8(BX)
+	ADDQ AX, R11
+	ADCQ DX, R10
+
+	// r2 += a2×b0
+	MOVQ 16(CX), AX
+	MULQ (BX)
+	ADDQ AX, R11
+	ADCQ DX, R10
+
+	// r2 += 19×a3×b4
+	MOVQ   24(CX), AX
+	IMUL3Q $0x13, AX, AX
+	MULQ   32(BX)
+	ADDQ   AX, R11
+	ADCQ   DX, R10
+
+	// r2 += 19×a4×b3
+	MOVQ   32(CX), AX
+	IMUL3Q $0x13, AX, AX
+	MULQ   24(BX)
+	ADDQ   AX, R11
+	ADCQ   DX, R10
+
+	// r3 = a0×b3
+	MOVQ (CX), AX
+	MULQ 24(BX)
+	MOVQ AX, R13
+	MOVQ DX, R12
+
+	// r3 += a1×b2
+	MOVQ 8(CX), AX
+	MULQ 16(BX)
+	ADDQ AX, R13
+	ADCQ DX, R12
+
+	// r3 += a2×b1
+	MOVQ 16(CX), AX
+	MULQ 8(BX)
+	ADDQ AX, R13
+	ADCQ DX, R12
+
+	// r3 += a3×b0
+	MOVQ 24(CX), AX
+	MULQ (BX)
+	ADDQ AX, R13
+	ADCQ DX, R12
+
+	// r3 += 19×a4×b4
+	MOVQ   32(CX), AX
+	IMUL3Q $0x13, AX, AX
+	MULQ   32(BX)
+	ADDQ   AX, R13
+	ADCQ   DX, R12
+
+	// r4 = a0×b4
+	MOVQ (CX), AX
+	MULQ 32(BX)
+	MOVQ AX, R15
+	MOVQ DX, R14
+
+	// r4 += a1×b3
+	MOVQ 8(CX), AX
+	MULQ 24(BX)
+	ADDQ AX, R15
+	ADCQ DX, R14
+
+	// r4 += a2×b2
+	MOVQ 16(CX), AX
+	MULQ 16(BX)
+	ADDQ AX, R15
+	ADCQ DX, R14
+
+	// r4 += a3×b1
+	MOVQ 24(CX), AX
+	MULQ 8(BX)
+	ADDQ AX, R15
+	ADCQ DX, R14
+
+	// r4 += a4×b0
+	MOVQ 32(CX), AX
+	MULQ (BX)
+	ADDQ AX, R15
+	ADCQ DX, R14
+
+	// First reduction chain
+	MOVQ   $0x0007ffffffffffff, AX
+	SHLQ   $0x0d, DI, SI
+	SHLQ   $0x0d, R9, R8
+	SHLQ   $0x0d, R11, R10
+	SHLQ   $0x0d, R13, R12
+	SHLQ   $0x0d, R15, R14
+	ANDQ   AX, DI
+	IMUL3Q $0x13, R14, R14
+	ADDQ   R14, DI
+	ANDQ   AX, R9
+	ADDQ   SI, R9
+	ANDQ   AX, R11
+	ADDQ   R8, R11
+	ANDQ   AX, R13
+	ADDQ   R10, R13
+	ANDQ   AX, R15
+	ADDQ   R12, R15
+
+	// Second reduction chain (carryPropagate)
+	MOVQ   DI, SI
+	SHRQ   $0x33, SI
+	MOVQ   R9, R8
+	SHRQ   $0x33, R8
+	MOVQ   R11, R10
+	SHRQ   $0x33, R10
+	MOVQ   R13, R12
+	SHRQ   $0x33, R12
+	MOVQ   R15, R14
+	SHRQ   $0x33, R14
+	ANDQ   AX, DI
+	IMUL3Q $0x13, R14, R14
+	ADDQ   R14, DI
+	ANDQ   AX, R9
+	ADDQ   SI, R9
+	ANDQ   AX, R11
+	ADDQ   R8, R11
+	ANDQ   AX, R13
+	ADDQ   R10, R13
+	ANDQ   AX, R15
+	ADDQ   R12, R15
+
+	// Store output
+	MOVQ out+0(FP), AX
+	MOVQ DI, (AX)
+	MOVQ R9, 8(AX)
+	MOVQ R11, 16(AX)
+	MOVQ R13, 24(AX)
+	MOVQ R15, 32(AX)
+	RET
+
+// func feSquare(out *Element, a *Element)
+TEXT ·feSquare(SB), NOSPLIT, $0-16
+	MOVQ a+8(FP), CX
+
+	// r0 = l0×l0
+	MOVQ (CX), AX
+	MULQ (CX)
+	MOVQ AX, SI
+	MOVQ DX, BX
+
+	// r0 += 38×l1×l4
+	MOVQ   8(CX), AX
+	IMUL3Q $0x26, AX, AX
+	MULQ   32(CX)
+	ADDQ   AX, SI
+	ADCQ   DX, BX
+
+	// r0 += 38×l2×l3
+	MOVQ   16(CX), AX
+	IMUL3Q $0x26, AX, AX
+	MULQ   24(CX)
+	ADDQ   AX, SI
+	ADCQ   DX, BX
+
+	// r1 = 2×l0×l1
+	MOVQ (CX), AX
+	SHLQ $0x01, AX
+	MULQ 8(CX)
+	MOVQ AX, R8
+	MOVQ DX, DI
+
+	// r1 += 38×l2×l4
+	MOVQ   16(CX), AX
+	IMUL3Q $0x26, AX, AX
+	MULQ   32(CX)
+	ADDQ   AX, R8
+	ADCQ   DX, DI
+
+	// r1 += 19×l3×l3
+	MOVQ   24(CX), AX
+	IMUL3Q $0x13, AX, AX
+	MULQ   24(CX)
+	ADDQ   AX, R8
+	ADCQ   DX, DI
+
+	// r2 = 2×l0×l2
+	MOVQ (CX), AX
+	SHLQ $0x01, AX
+	MULQ 16(CX)
+	MOVQ AX, R10
+	MOVQ DX, R9
+
+	// r2 += l1×l1
+	MOVQ 8(CX), AX
+	MULQ 8(CX)
+	ADDQ AX, R10
+	ADCQ DX, R9
+
+	// r2 += 38×l3×l4
+	MOVQ   24(CX), AX
+	IMUL3Q $0x26, AX, AX
+	MULQ   32(CX)
+	ADDQ   AX, R10
+	ADCQ   DX, R9
+
+	// r3 = 2×l0×l3
+	MOVQ (CX), AX
+	SHLQ $0x01, AX
+	MULQ 24(CX)
+	MOVQ AX, R12
+	MOVQ DX, R11
+
+	// r3 += 2×l1×l2
+	MOVQ   8(CX), AX
+	IMUL3Q $0x02, AX, AX
+	MULQ   16(CX)
+	ADDQ   AX, R12
+	ADCQ   DX, R11
+
+	// r3 += 19×l4×l4
+	MOVQ   32(CX), AX
+	IMUL3Q $0x13, AX, AX
+	MULQ   32(CX)
+	ADDQ   AX, R12
+	ADCQ   DX, R11
+
+	// r4 = 2×l0×l4
+	MOVQ (CX), AX
+	SHLQ $0x01, AX
+	MULQ 32(CX)
+	MOVQ AX, R14
+	MOVQ DX, R13
+
+	// r4 += 2×l1×l3
+	MOVQ   8(CX), AX
+	IMUL3Q $0x02, AX, AX
+	MULQ   24(CX)
+	ADDQ   AX, R14
+	ADCQ   DX, R13
+
+	// r4 += l2×l2
+	MOVQ 16(CX), AX
+	MULQ 16(CX)
+	ADDQ AX, R14
+	ADCQ DX, R13
+
+	// First reduction chain
+	MOVQ   $0x0007ffffffffffff, AX
+	SHLQ   $0x0d, SI, BX
+	SHLQ   $0x0d, R8, DI
+	SHLQ   $0x0d, R10, R9
+	SHLQ   $0x0d, R12, R11
+	SHLQ   $0x0d, R14, R13
+	ANDQ   AX, SI
+	IMUL3Q $0x13, R13, R13
+	ADDQ   R13, SI
+	ANDQ   AX, R8
+	ADDQ   BX, R8
+	ANDQ   AX, R10
+	ADDQ   DI, R10
+	ANDQ   AX, R12
+	ADDQ   R9, R12
+	ANDQ   AX, R14
+	ADDQ   R11, R14
+
+	// Second reduction chain (carryPropagate)
+	MOVQ   SI, BX
+	SHRQ   $0x33, BX
+	MOVQ   R8, DI
+	SHRQ   $0x33, DI
+	MOVQ   R10, R9
+	SHRQ   $0x33, R9
+	MOVQ   R12, R11
+	SHRQ   $0x33, R11
+	MOVQ   R14, R13
+	SHRQ   $0x33, R13
+	ANDQ   AX, SI
+	IMUL3Q $0x13, R13, R13
+	ADDQ   R13, SI
+	ANDQ   AX, R8
+	ADDQ   BX, R8
+	ANDQ   AX, R10
+	ADDQ   DI, R10
+	ANDQ   AX, R12
+	ADDQ   R9, R12
+	ANDQ   AX, R14
+	ADDQ   R11, R14
+
+	// Store output
+	MOVQ out+0(FP), AX
+	MOVQ SI, (AX)
+	MOVQ R8, 8(AX)
+	MOVQ R10, 16(AX)
+	MOVQ R12, 24(AX)
+	MOVQ R14, 32(AX)
+	RET
diff --git a/vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64_noasm.go b/vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64_noasm.go
new file mode 100644
index 0000000000..ddb6c9b8f7
--- /dev/null
+++ b/vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64_noasm.go
@@ -0,0 +1,12 @@
+// Copyright (c) 2019 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.
+
+//go:build !amd64 || !gc || purego
+// +build !amd64 !gc purego
+
+package field
+
+func feMul(v, x, y *Element) { feMulGeneric(v, x, y) }
+
+func feSquare(v, x *Element) { feSquareGeneric(v, x) }
diff --git a/vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64.go b/vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64.go
new file mode 100644
index 0000000000..af459ef515
--- /dev/null
+++ b/vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64.go
@@ -0,0 +1,16 @@
+// Copyright (c) 2020 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.
+
+//go:build arm64 && gc && !purego
+// +build arm64,gc,!purego
+
+package field
+
+//go:noescape
+func carryPropagate(v *Element)
+
+func (v *Element) carryPropagate() *Element {
+	carryPropagate(v)
+	return v
+}
diff --git a/vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64.s b/vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64.s
new file mode 100644
index 0000000000..5c91e45892
--- /dev/null
+++ b/vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64.s
@@ -0,0 +1,43 @@
+// Copyright (c) 2020 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.
+
+//go:build arm64 && gc && !purego
+// +build arm64,gc,!purego
+
+#include "textflag.h"
+
+// carryPropagate works exactly like carryPropagateGeneric and uses the
+// same AND, ADD, and LSR+MADD instructions emitted by the compiler, but
+// avoids loading R0-R4 twice and uses LDP and STP.
+//
+// See https://golang.org/issues/43145 for the main compiler issue.
+//
+// func carryPropagate(v *Element)
+TEXT ·carryPropagate(SB),NOFRAME|NOSPLIT,$0-8
+	MOVD v+0(FP), R20
+
+	LDP 0(R20), (R0, R1)
+	LDP 16(R20), (R2, R3)
+	MOVD 32(R20), R4
+
+	AND $0x7ffffffffffff, R0, R10
+	AND $0x7ffffffffffff, R1, R11
+	AND $0x7ffffffffffff, R2, R12
+	AND $0x7ffffffffffff, R3, R13
+	AND $0x7ffffffffffff, R4, R14
+
+	ADD R0>>51, R11, R11
+	ADD R1>>51, R12, R12
+	ADD R2>>51, R13, R13
+	ADD R3>>51, R14, R14
+	// R4>>51 * 19 + R10 -> R10
+	LSR $51, R4, R21
+	MOVD $19, R22
+	MADD R22, R10, R21, R10
+
+	STP (R10, R11), 0(R20)
+	STP (R12, R13), 16(R20)
+	MOVD R14, 32(R20)
+
+	RET
diff --git a/vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64_noasm.go b/vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64_noasm.go
new file mode 100644
index 0000000000..234a5b2e5d
--- /dev/null
+++ b/vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64_noasm.go
@@ -0,0 +1,12 @@
+// Copyright (c) 2021 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.
+
+//go:build !arm64 || !gc || purego
+// +build !arm64 !gc purego
+
+package field
+
+func (v *Element) carryPropagate() *Element {
+	return v.carryPropagateGeneric()
+}
diff --git a/vendor/golang.org/x/crypto/curve25519/internal/field/fe_generic.go b/vendor/golang.org/x/crypto/curve25519/internal/field/fe_generic.go
new file mode 100644
index 0000000000..7b5b78cbd6
--- /dev/null
+++ b/vendor/golang.org/x/crypto/curve25519/internal/field/fe_generic.go
@@ -0,0 +1,264 @@
+// Copyright (c) 2017 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 field
+
+import "math/bits"
+
+// uint128 holds a 128-bit number as two 64-bit limbs, for use with the
+// bits.Mul64 and bits.Add64 intrinsics.
+type uint128 struct {
+	lo, hi uint64
+}
+
+// mul64 returns a * b.
+func mul64(a, b uint64) uint128 {
+	hi, lo := bits.Mul64(a, b)
+	return uint128{lo, hi}
+}
+
+// addMul64 returns v + a * b.
+func addMul64(v uint128, a, b uint64) uint128 {
+	hi, lo := bits.Mul64(a, b)
+	lo, c := bits.Add64(lo, v.lo, 0)
+	hi, _ = bits.Add64(hi, v.hi, c)
+	return uint128{lo, hi}
+}
+
+// shiftRightBy51 returns a >> 51. a is assumed to be at most 115 bits.
+func shiftRightBy51(a uint128) uint64 {
+	return (a.hi << (64 - 51)) | (a.lo >> 51)
+}
+
+func feMulGeneric(v, a, b *Element) {
+	a0 := a.l0
+	a1 := a.l1
+	a2 := a.l2
+	a3 := a.l3
+	a4 := a.l4
+
+	b0 := b.l0
+	b1 := b.l1
+	b2 := b.l2
+	b3 := b.l3
+	b4 := b.l4
+
+	// Limb multiplication works like pen-and-paper columnar multiplication, but
+	// with 51-bit limbs instead of digits.
+	//
+	//                          a4   a3   a2   a1   a0  x
+	//                          b4   b3   b2   b1   b0  =
+	//                         ------------------------
+	//                        a4b0 a3b0 a2b0 a1b0 a0b0  +
+	//                   a4b1 a3b1 a2b1 a1b1 a0b1       +
+	//              a4b2 a3b2 a2b2 a1b2 a0b2            +
+	//         a4b3 a3b3 a2b3 a1b3 a0b3                 +
+	//    a4b4 a3b4 a2b4 a1b4 a0b4                      =
+	//   ----------------------------------------------
+	//      r8   r7   r6   r5   r4   r3   r2   r1   r0
+	//
+	// We can then use the reduction identity (a * 2²⁵⁵ + b = a * 19 + b) to
+	// reduce the limbs that would overflow 255 bits. r5 * 2²⁵⁵ becomes 19 * r5,
+	// r6 * 2³⁰⁶ becomes 19 * r6 * 2⁵¹, etc.
+	//
+	// Reduction can be carried out simultaneously to multiplication. For
+	// example, we do not compute r5: whenever the result of a multiplication
+	// belongs to r5, like a1b4, we multiply it by 19 and add the result to r0.
+	//
+	//            a4b0    a3b0    a2b0    a1b0    a0b0  +
+	//            a3b1    a2b1    a1b1    a0b1 19×a4b1  +
+	//            a2b2    a1b2    a0b2 19×a4b2 19×a3b2  +
+	//            a1b3    a0b3 19×a4b3 19×a3b3 19×a2b3  +
+	//            a0b4 19×a4b4 19×a3b4 19×a2b4 19×a1b4  =
+	//           --------------------------------------
+	//              r4      r3      r2      r1      r0
+	//
+	// Finally we add up the columns into wide, overlapping limbs.
+
+	a1_19 := a1 * 19
+	a2_19 := a2 * 19
+	a3_19 := a3 * 19
+	a4_19 := a4 * 19
+
+	// r0 = a0×b0 + 19×(a1×b4 + a2×b3 + a3×b2 + a4×b1)
+	r0 := mul64(a0, b0)
+	r0 = addMul64(r0, a1_19, b4)
+	r0 = addMul64(r0, a2_19, b3)
+	r0 = addMul64(r0, a3_19, b2)
+	r0 = addMul64(r0, a4_19, b1)
+
+	// r1 = a0×b1 + a1×b0 + 19×(a2×b4 + a3×b3 + a4×b2)
+	r1 := mul64(a0, b1)
+	r1 = addMul64(r1, a1, b0)
+	r1 = addMul64(r1, a2_19, b4)
+	r1 = addMul64(r1, a3_19, b3)
+	r1 = addMul64(r1, a4_19, b2)
+
+	// r2 = a0×b2 + a1×b1 + a2×b0 + 19×(a3×b4 + a4×b3)
+	r2 := mul64(a0, b2)
+	r2 = addMul64(r2, a1, b1)
+	r2 = addMul64(r2, a2, b0)
+	r2 = addMul64(r2, a3_19, b4)
+	r2 = addMul64(r2, a4_19, b3)
+
+	// r3 = a0×b3 + a1×b2 + a2×b1 + a3×b0 + 19×a4×b4
+	r3 := mul64(a0, b3)
+	r3 = addMul64(r3, a1, b2)
+	r3 = addMul64(r3, a2, b1)
+	r3 = addMul64(r3, a3, b0)
+	r3 = addMul64(r3, a4_19, b4)
+
+	// r4 = a0×b4 + a1×b3 + a2×b2 + a3×b1 + a4×b0
+	r4 := mul64(a0, b4)
+	r4 = addMul64(r4, a1, b3)
+	r4 = addMul64(r4, a2, b2)
+	r4 = addMul64(r4, a3, b1)
+	r4 = addMul64(r4, a4, b0)
+
+	// After the multiplication, we need to reduce (carry) the five coefficients
+	// to obtain a result with limbs that are at most slightly larger than 2⁵¹,
+	// to respect the Element invariant.
+	//
+	// Overall, the reduction works the same as carryPropagate, except with
+	// wider inputs: we take the carry for each coefficient by shifting it right
+	// by 51, and add it to the limb above it. The top carry is multiplied by 19
+	// according to the reduction identity and added to the lowest limb.
+	//
+	// The largest coefficient (r0) will be at most 111 bits, which guarantees
+	// that all carries are at most 111 - 51 = 60 bits, which fits in a uint64.
+	//
+	//     r0 = a0×b0 + 19×(a1×b4 + a2×b3 + a3×b2 + a4×b1)
+	//     r0 < 2⁵²×2⁵² + 19×(2⁵²×2⁵² + 2⁵²×2⁵² + 2⁵²×2⁵² + 2⁵²×2⁵²)
+	//     r0 < (1 + 19 × 4) × 2⁵² × 2⁵²
+	//     r0 < 2⁷ × 2⁵² × 2⁵²
+	//     r0 < 2¹¹¹
+	//
+	// Moreover, the top coefficient (r4) is at most 107 bits, so c4 is at most
+	// 56 bits, and c4 * 19 is at most 61 bits, which again fits in a uint64 and
+	// allows us to easily apply the reduction identity.
+	//
+	//     r4 = a0×b4 + a1×b3 + a2×b2 + a3×b1 + a4×b0
+	//     r4 < 5 × 2⁵² × 2⁵²
+	//     r4 < 2¹⁰⁷
+	//
+
+	c0 := shiftRightBy51(r0)
+	c1 := shiftRightBy51(r1)
+	c2 := shiftRightBy51(r2)
+	c3 := shiftRightBy51(r3)
+	c4 := shiftRightBy51(r4)
+
+	rr0 := r0.lo&maskLow51Bits + c4*19
+	rr1 := r1.lo&maskLow51Bits + c0
+	rr2 := r2.lo&maskLow51Bits + c1
+	rr3 := r3.lo&maskLow51Bits + c2
+	rr4 := r4.lo&maskLow51Bits + c3
+
+	// Now all coefficients fit into 64-bit registers but are still too large to
+	// be passed around as a Element. We therefore do one last carry chain,
+	// where the carries will be small enough to fit in the wiggle room above 2⁵¹.
+	*v = Element{rr0, rr1, rr2, rr3, rr4}
+	v.carryPropagate()
+}
+
+func feSquareGeneric(v, a *Element) {
+	l0 := a.l0
+	l1 := a.l1
+	l2 := a.l2
+	l3 := a.l3
+	l4 := a.l4
+
+	// Squaring works precisely like multiplication above, but thanks to its
+	// symmetry we get to group a few terms together.
+	//
+	//                          l4   l3   l2   l1   l0  x
+	//                          l4   l3   l2   l1   l0  =
+	//                         ------------------------
+	//                        l4l0 l3l0 l2l0 l1l0 l0l0  +
+	//                   l4l1 l3l1 l2l1 l1l1 l0l1       +
+	//              l4l2 l3l2 l2l2 l1l2 l0l2            +
+	//         l4l3 l3l3 l2l3 l1l3 l0l3                 +
+	//    l4l4 l3l4 l2l4 l1l4 l0l4                      =
+	//   ----------------------------------------------
+	//      r8   r7   r6   r5   r4   r3   r2   r1   r0
+	//
+	//            l4l0    l3l0    l2l0    l1l0    l0l0  +
+	//            l3l1    l2l1    l1l1    l0l1 19×l4l1  +
+	//            l2l2    l1l2    l0l2 19×l4l2 19×l3l2  +
+	//            l1l3    l0l3 19×l4l3 19×l3l3 19×l2l3  +
+	//            l0l4 19×l4l4 19×l3l4 19×l2l4 19×l1l4  =
+	//           --------------------------------------
+	//              r4      r3      r2      r1      r0
+	//
+	// With precomputed 2×, 19×, and 2×19× terms, we can compute each limb with
+	// only three Mul64 and four Add64, instead of five and eight.
+
+	l0_2 := l0 * 2
+	l1_2 := l1 * 2
+
+	l1_38 := l1 * 38
+	l2_38 := l2 * 38
+	l3_38 := l3 * 38
+
+	l3_19 := l3 * 19
+	l4_19 := l4 * 19
+
+	// r0 = l0×l0 + 19×(l1×l4 + l2×l3 + l3×l2 + l4×l1) = l0×l0 + 19×2×(l1×l4 + l2×l3)
+	r0 := mul64(l0, l0)
+	r0 = addMul64(r0, l1_38, l4)
+	r0 = addMul64(r0, l2_38, l3)
+
+	// r1 = l0×l1 + l1×l0 + 19×(l2×l4 + l3×l3 + l4×l2) = 2×l0×l1 + 19×2×l2×l4 + 19×l3×l3
+	r1 := mul64(l0_2, l1)
+	r1 = addMul64(r1, l2_38, l4)
+	r1 = addMul64(r1, l3_19, l3)
+
+	// r2 = l0×l2 + l1×l1 + l2×l0 + 19×(l3×l4 + l4×l3) = 2×l0×l2 + l1×l1 + 19×2×l3×l4
+	r2 := mul64(l0_2, l2)
+	r2 = addMul64(r2, l1, l1)
+	r2 = addMul64(r2, l3_38, l4)
+
+	// r3 = l0×l3 + l1×l2 + l2×l1 + l3×l0 + 19×l4×l4 = 2×l0×l3 + 2×l1×l2 + 19×l4×l4
+	r3 := mul64(l0_2, l3)
+	r3 = addMul64(r3, l1_2, l2)
+	r3 = addMul64(r3, l4_19, l4)
+
+	// r4 = l0×l4 + l1×l3 + l2×l2 + l3×l1 + l4×l0 = 2×l0×l4 + 2×l1×l3 + l2×l2
+	r4 := mul64(l0_2, l4)
+	r4 = addMul64(r4, l1_2, l3)
+	r4 = addMul64(r4, l2, l2)
+
+	c0 := shiftRightBy51(r0)
+	c1 := shiftRightBy51(r1)
+	c2 := shiftRightBy51(r2)
+	c3 := shiftRightBy51(r3)
+	c4 := shiftRightBy51(r4)
+
+	rr0 := r0.lo&maskLow51Bits + c4*19
+	rr1 := r1.lo&maskLow51Bits + c0
+	rr2 := r2.lo&maskLow51Bits + c1
+	rr3 := r3.lo&maskLow51Bits + c2
+	rr4 := r4.lo&maskLow51Bits + c3
+
+	*v = Element{rr0, rr1, rr2, rr3, rr4}
+	v.carryPropagate()
+}
+
+// carryPropagate brings the limbs below 52 bits by applying the reduction
+// identity (a * 2²⁵⁵ + b = a * 19 + b) to the l4 carry. TODO inline
+func (v *Element) carryPropagateGeneric() *Element {
+	c0 := v.l0 >> 51
+	c1 := v.l1 >> 51
+	c2 := v.l2 >> 51
+	c3 := v.l3 >> 51
+	c4 := v.l4 >> 51
+
+	v.l0 = v.l0&maskLow51Bits + c4*19
+	v.l1 = v.l1&maskLow51Bits + c0
+	v.l2 = v.l2&maskLow51Bits + c1
+	v.l3 = v.l3&maskLow51Bits + c2
+	v.l4 = v.l4&maskLow51Bits + c3
+
+	return v
+}
diff --git a/vendor/golang.org/x/crypto/curve25519/internal/field/sync.checkpoint b/vendor/golang.org/x/crypto/curve25519/internal/field/sync.checkpoint
new file mode 100644
index 0000000000..e3685f95ca
--- /dev/null
+++ b/vendor/golang.org/x/crypto/curve25519/internal/field/sync.checkpoint
@@ -0,0 +1 @@
+b0c49ae9f59d233526f8934262c5bbbe14d4358d
diff --git a/vendor/golang.org/x/crypto/curve25519/internal/field/sync.sh b/vendor/golang.org/x/crypto/curve25519/internal/field/sync.sh
new file mode 100755
index 0000000000..1ba22a8b4c
--- /dev/null
+++ b/vendor/golang.org/x/crypto/curve25519/internal/field/sync.sh
@@ -0,0 +1,19 @@
+#! /bin/bash
+set -euo pipefail
+
+cd "$(git rev-parse --show-toplevel)"
+
+STD_PATH=src/crypto/ed25519/internal/edwards25519/field
+LOCAL_PATH=curve25519/internal/field
+LAST_SYNC_REF=$(cat $LOCAL_PATH/sync.checkpoint)
+
+git fetch https://go.googlesource.com/go master
+
+if git diff --quiet $LAST_SYNC_REF:$STD_PATH FETCH_HEAD:$STD_PATH; then
+    echo "No changes."
+else
+    NEW_REF=$(git rev-parse FETCH_HEAD | tee $LOCAL_PATH/sync.checkpoint)
+    echo "Applying changes from $LAST_SYNC_REF to $NEW_REF..."
+    git diff $LAST_SYNC_REF:$STD_PATH FETCH_HEAD:$STD_PATH | \
+        git apply -3 --directory=$LOCAL_PATH
+fi
diff --git a/vendor/golang.org/x/crypto/ed25519/ed25519.go b/vendor/golang.org/x/crypto/ed25519/ed25519.go
index c7f8c7e64e..a7828345fc 100644
--- a/vendor/golang.org/x/crypto/ed25519/ed25519.go
+++ b/vendor/golang.org/x/crypto/ed25519/ed25519.go
@@ -1,12 +1,7 @@
-// Copyright 2016 The Go Authors. All rights reserved.
+// Copyright 2019 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.
 
-// In Go 1.13, the ed25519 package was promoted to the standard library as
-// crypto/ed25519, and this package became a wrapper for the standard library one.
-//
-// +build !go1.13
-
 // Package ed25519 implements the Ed25519 signature algorithm. See
 // https://ed25519.cr.yp.to/.
 //
@@ -15,21 +10,15 @@
 // representation includes a public key suffix to make multiple signing
 // operations with the same key more efficient. This package refers to the RFC
 // 8032 private key as the “seed”.
+//
+// Beginning with Go 1.13, the functionality of this package was moved to the
+// standard library as crypto/ed25519. This package only acts as a compatibility
+// wrapper.
 package ed25519
 
-// This code is a port of the public domain, “ref10” implementation of ed25519
-// from SUPERCOP.
-
 import (
-	"bytes"
-	"crypto"
-	cryptorand "crypto/rand"
-	"crypto/sha512"
-	"errors"
+	"crypto/ed25519"
 	"io"
-	"strconv"
-
-	"golang.org/x/crypto/ed25519/internal/edwards25519"
 )
 
 const (
@@ -44,57 +33,21 @@ const (
 )
 
 // PublicKey is the type of Ed25519 public keys.
-type PublicKey []byte
+//
+// This type is an alias for crypto/ed25519's PublicKey type.
+// See the crypto/ed25519 package for the methods on this type.
+type PublicKey = ed25519.PublicKey
 
 // PrivateKey is the type of Ed25519 private keys. It implements crypto.Signer.
-type PrivateKey []byte
-
-// Public returns the PublicKey corresponding to priv.
-func (priv PrivateKey) Public() crypto.PublicKey {
-	publicKey := make([]byte, PublicKeySize)
-	copy(publicKey, priv[32:])
-	return PublicKey(publicKey)
-}
-
-// Seed returns the private key seed corresponding to priv. It is provided for
-// interoperability with RFC 8032. RFC 8032's private keys correspond to seeds
-// in this package.
-func (priv PrivateKey) Seed() []byte {
-	seed := make([]byte, SeedSize)
-	copy(seed, priv[:32])
-	return seed
-}
-
-// Sign signs the given message with priv.
-// Ed25519 performs two passes over messages to be signed and therefore cannot
-// handle pre-hashed messages. Thus opts.HashFunc() must return zero to
-// indicate the message hasn't been hashed. This can be achieved by passing
-// crypto.Hash(0) as the value for opts.
-func (priv PrivateKey) Sign(rand io.Reader, message []byte, opts crypto.SignerOpts) (signature []byte, err error) {
-	if opts.HashFunc() != crypto.Hash(0) {
-		return nil, errors.New("ed25519: cannot sign hashed message")
-	}
-
-	return Sign(priv, message), nil
-}
+//
+// This type is an alias for crypto/ed25519's PrivateKey type.
+// See the crypto/ed25519 package for the methods on this type.
+type PrivateKey = ed25519.PrivateKey
 
 // GenerateKey generates a public/private key pair using entropy from rand.
 // If rand is nil, crypto/rand.Reader will be used.
 func GenerateKey(rand io.Reader) (PublicKey, PrivateKey, error) {
-	if rand == nil {
-		rand = cryptorand.Reader
-	}
-
-	seed := make([]byte, SeedSize)
-	if _, err := io.ReadFull(rand, seed); err != nil {
-		return nil, nil, err
-	}
-
-	privateKey := NewKeyFromSeed(seed)
-	publicKey := make([]byte, PublicKeySize)
-	copy(publicKey, privateKey[32:])
-
-	return publicKey, privateKey, nil
+	return ed25519.GenerateKey(rand)
 }
 
 // NewKeyFromSeed calculates a private key from a seed. It will panic if
@@ -102,121 +55,17 @@ func GenerateKey(rand io.Reader) (PublicKey, PrivateKey, error) {
 // with RFC 8032. RFC 8032's private keys correspond to seeds in this
 // package.
 func NewKeyFromSeed(seed []byte) PrivateKey {
-	if l := len(seed); l != SeedSize {
-		panic("ed25519: bad seed length: " + strconv.Itoa(l))
-	}
-
-	digest := sha512.Sum512(seed)
-	digest[0] &= 248
-	digest[31] &= 127
-	digest[31] |= 64
-
-	var A edwards25519.ExtendedGroupElement
-	var hBytes [32]byte
-	copy(hBytes[:], digest[:])
-	edwards25519.GeScalarMultBase(&A, &hBytes)
-	var publicKeyBytes [32]byte
-	A.ToBytes(&publicKeyBytes)
-
-	privateKey := make([]byte, PrivateKeySize)
-	copy(privateKey, seed)
-	copy(privateKey[32:], publicKeyBytes[:])
-
-	return privateKey
+	return ed25519.NewKeyFromSeed(seed)
 }
 
 // Sign signs the message with privateKey and returns a signature. It will
 // panic if len(privateKey) is not PrivateKeySize.
 func Sign(privateKey PrivateKey, message []byte) []byte {
-	if l := len(privateKey); l != PrivateKeySize {
-		panic("ed25519: bad private key length: " + strconv.Itoa(l))
-	}
-
-	h := sha512.New()
-	h.Write(privateKey[:32])
-
-	var digest1, messageDigest, hramDigest [64]byte
-	var expandedSecretKey [32]byte
-	h.Sum(digest1[:0])
-	copy(expandedSecretKey[:], digest1[:])
-	expandedSecretKey[0] &= 248
-	expandedSecretKey[31] &= 63
-	expandedSecretKey[31] |= 64
-
-	h.Reset()
-	h.Write(digest1[32:])
-	h.Write(message)
-	h.Sum(messageDigest[:0])
-
-	var messageDigestReduced [32]byte
-	edwards25519.ScReduce(&messageDigestReduced, &messageDigest)
-	var R edwards25519.ExtendedGroupElement
-	edwards25519.GeScalarMultBase(&R, &messageDigestReduced)
-
-	var encodedR [32]byte
-	R.ToBytes(&encodedR)
-
-	h.Reset()
-	h.Write(encodedR[:])
-	h.Write(privateKey[32:])
-	h.Write(message)
-	h.Sum(hramDigest[:0])
-	var hramDigestReduced [32]byte
-	edwards25519.ScReduce(&hramDigestReduced, &hramDigest)
-
-	var s [32]byte
-	edwards25519.ScMulAdd(&s, &hramDigestReduced, &expandedSecretKey, &messageDigestReduced)
-
-	signature := make([]byte, SignatureSize)
-	copy(signature[:], encodedR[:])
-	copy(signature[32:], s[:])
-
-	return signature
+	return ed25519.Sign(privateKey, message)
 }
 
 // Verify reports whether sig is a valid signature of message by publicKey. It
 // will panic if len(publicKey) is not PublicKeySize.
 func Verify(publicKey PublicKey, message, sig []byte) bool {
-	if l := len(publicKey); l != PublicKeySize {
-		panic("ed25519: bad public key length: " + strconv.Itoa(l))
-	}
-
-	if len(sig) != SignatureSize || sig[63]&224 != 0 {
-		return false
-	}
-
-	var A edwards25519.ExtendedGroupElement
-	var publicKeyBytes [32]byte
-	copy(publicKeyBytes[:], publicKey)
-	if !A.FromBytes(&publicKeyBytes) {
-		return false
-	}
-	edwards25519.FeNeg(&A.X, &A.X)
-	edwards25519.FeNeg(&A.T, &A.T)
-
-	h := sha512.New()
-	h.Write(sig[:32])
-	h.Write(publicKey[:])
-	h.Write(message)
-	var digest [64]byte
-	h.Sum(digest[:0])
-
-	var hReduced [32]byte
-	edwards25519.ScReduce(&hReduced, &digest)
-
-	var R edwards25519.ProjectiveGroupElement
-	var s [32]byte
-	copy(s[:], sig[32:])
-
-	// https://tools.ietf.org/html/rfc8032#section-5.1.7 requires that s be in
-	// the range [0, order) in order to prevent signature malleability.
-	if !edwards25519.ScMinimal(&s) {
-		return false
-	}
-
-	edwards25519.GeDoubleScalarMultVartime(&R, &hReduced, &A, &s)
-
-	var checkR [32]byte
-	R.ToBytes(&checkR)
-	return bytes.Equal(sig[:32], checkR[:])
+	return ed25519.Verify(publicKey, message, sig)
 }
diff --git a/vendor/golang.org/x/crypto/ed25519/ed25519_go113.go b/vendor/golang.org/x/crypto/ed25519/ed25519_go113.go
deleted file mode 100644
index d1448d8d22..0000000000
--- a/vendor/golang.org/x/crypto/ed25519/ed25519_go113.go
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright 2019 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 go1.13
-
-// Package ed25519 implements the Ed25519 signature algorithm. See
-// https://ed25519.cr.yp.to/.
-//
-// These functions are also compatible with the “Ed25519” function defined in
-// RFC 8032. However, unlike RFC 8032's formulation, this package's private key
-// representation includes a public key suffix to make multiple signing
-// operations with the same key more efficient. This package refers to the RFC
-// 8032 private key as the “seed”.
-//
-// Beginning with Go 1.13, the functionality of this package was moved to the
-// standard library as crypto/ed25519. This package only acts as a compatibility
-// wrapper.
-package ed25519
-
-import (
-	"crypto/ed25519"
-	"io"
-)
-
-const (
-	// PublicKeySize is the size, in bytes, of public keys as used in this package.
-	PublicKeySize = 32
-	// PrivateKeySize is the size, in bytes, of private keys as used in this package.
-	PrivateKeySize = 64
-	// SignatureSize is the size, in bytes, of signatures generated and verified by this package.
-	SignatureSize = 64
-	// SeedSize is the size, in bytes, of private key seeds. These are the private key representations used by RFC 8032.
-	SeedSize = 32
-)
-
-// PublicKey is the type of Ed25519 public keys.
-//
-// This type is an alias for crypto/ed25519's PublicKey type.
-// See the crypto/ed25519 package for the methods on this type.
-type PublicKey = ed25519.PublicKey
-
-// PrivateKey is the type of Ed25519 private keys. It implements crypto.Signer.
-//
-// This type is an alias for crypto/ed25519's PrivateKey type.
-// See the crypto/ed25519 package for the methods on this type.
-type PrivateKey = ed25519.PrivateKey
-
-// GenerateKey generates a public/private key pair using entropy from rand.
-// If rand is nil, crypto/rand.Reader will be used.
-func GenerateKey(rand io.Reader) (PublicKey, PrivateKey, error) {
-	return ed25519.GenerateKey(rand)
-}
-
-// NewKeyFromSeed calculates a private key from a seed. It will panic if
-// len(seed) is not SeedSize. This function is provided for interoperability
-// with RFC 8032. RFC 8032's private keys correspond to seeds in this
-// package.
-func NewKeyFromSeed(seed []byte) PrivateKey {
-	return ed25519.NewKeyFromSeed(seed)
-}
-
-// Sign signs the message with privateKey and returns a signature. It will
-// panic if len(privateKey) is not PrivateKeySize.
-func Sign(privateKey PrivateKey, message []byte) []byte {
-	return ed25519.Sign(privateKey, message)
-}
-
-// Verify reports whether sig is a valid signature of message by publicKey. It
-// will panic if len(publicKey) is not PublicKeySize.
-func Verify(publicKey PublicKey, message, sig []byte) bool {
-	return ed25519.Verify(publicKey, message, sig)
-}
diff --git a/vendor/golang.org/x/crypto/ed25519/internal/edwards25519/const.go b/vendor/golang.org/x/crypto/ed25519/internal/edwards25519/const.go
deleted file mode 100644
index e39f086c1d..0000000000
--- a/vendor/golang.org/x/crypto/ed25519/internal/edwards25519/const.go
+++ /dev/null
@@ -1,1422 +0,0 @@
-// Copyright 2016 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package edwards25519
-
-// These values are from the public domain, “ref10” implementation of ed25519
-// from SUPERCOP.
-
-// d is a constant in the Edwards curve equation.
-var d = FieldElement{
-	-10913610, 13857413, -15372611, 6949391, 114729, -8787816, -6275908, -3247719, -18696448, -12055116,
-}
-
-// d2 is 2*d.
-var d2 = FieldElement{
-	-21827239, -5839606, -30745221, 13898782, 229458, 15978800, -12551817, -6495438, 29715968, 9444199,
-}
-
-// SqrtM1 is the square-root of -1 in the field.
-var SqrtM1 = FieldElement{
-	-32595792, -7943725, 9377950, 3500415, 12389472, -272473, -25146209, -2005654, 326686, 11406482,
-}
-
-// A is a constant in the Montgomery-form of curve25519.
-var A = FieldElement{
-	486662, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-}
-
-// bi contains precomputed multiples of the base-point. See the Ed25519 paper
-// for a discussion about how these values are used.
-var bi = [8]PreComputedGroupElement{
-	{
-		FieldElement{25967493, -14356035, 29566456, 3660896, -12694345, 4014787, 27544626, -11754271, -6079156, 2047605},
-		FieldElement{-12545711, 934262, -2722910, 3049990, -727428, 9406986, 12720692, 5043384, 19500929, -15469378},
-		FieldElement{-8738181, 4489570, 9688441, -14785194, 10184609, -12363380, 29287919, 11864899, -24514362, -4438546},
-	},
-	{
-		FieldElement{15636291, -9688557, 24204773, -7912398, 616977, -16685262, 27787600, -14772189, 28944400, -1550024},
-		FieldElement{16568933, 4717097, -11556148, -1102322, 15682896, -11807043, 16354577, -11775962, 7689662, 11199574},
-		FieldElement{30464156, -5976125, -11779434, -15670865, 23220365, 15915852, 7512774, 10017326, -17749093, -9920357},
-	},
-	{
-		FieldElement{10861363, 11473154, 27284546, 1981175, -30064349, 12577861, 32867885, 14515107, -15438304, 10819380},
-		FieldElement{4708026, 6336745, 20377586, 9066809, -11272109, 6594696, -25653668, 12483688, -12668491, 5581306},
-		FieldElement{19563160, 16186464, -29386857, 4097519, 10237984, -4348115, 28542350, 13850243, -23678021, -15815942},
-	},
-	{
-		FieldElement{5153746, 9909285, 1723747, -2777874, 30523605, 5516873, 19480852, 5230134, -23952439, -15175766},
-		FieldElement{-30269007, -3463509, 7665486, 10083793, 28475525, 1649722, 20654025, 16520125, 30598449, 7715701},
-		FieldElement{28881845, 14381568, 9657904, 3680757, -20181635, 7843316, -31400660, 1370708, 29794553, -1409300},
-	},
-	{
-		FieldElement{-22518993, -6692182, 14201702, -8745502, -23510406, 8844726, 18474211, -1361450, -13062696, 13821877},
-		FieldElement{-6455177, -7839871, 3374702, -4740862, -27098617, -10571707, 31655028, -7212327, 18853322, -14220951},
-		FieldElement{4566830, -12963868, -28974889, -12240689, -7602672, -2830569, -8514358, -10431137, 2207753, -3209784},
-	},
-	{
-		FieldElement{-25154831, -4185821, 29681144, 7868801, -6854661, -9423865, -12437364, -663000, -31111463, -16132436},
-		FieldElement{25576264, -2703214, 7349804, -11814844, 16472782, 9300885, 3844789, 15725684, 171356, 6466918},
-		FieldElement{23103977, 13316479, 9739013, -16149481, 817875, -15038942, 8965339, -14088058, -30714912, 16193877},
-	},
-	{
-		FieldElement{-33521811, 3180713, -2394130, 14003687, -16903474, -16270840, 17238398, 4729455, -18074513, 9256800},
-		FieldElement{-25182317, -4174131, 32336398, 5036987, -21236817, 11360617, 22616405, 9761698, -19827198, 630305},
-		FieldElement{-13720693, 2639453, -24237460, -7406481, 9494427, -5774029, -6554551, -15960994, -2449256, -14291300},
-	},
-	{
-		FieldElement{-3151181, -5046075, 9282714, 6866145, -31907062, -863023, -18940575, 15033784, 25105118, -7894876},
-		FieldElement{-24326370, 15950226, -31801215, -14592823, -11662737, -5090925, 1573892, -2625887, 2198790, -15804619},
-		FieldElement{-3099351, 10324967, -2241613, 7453183, -5446979, -2735503, -13812022, -16236442, -32461234, -12290683},
-	},
-}
-
-// base contains precomputed multiples of the base-point. See the Ed25519 paper
-// for a discussion about how these values are used.
-var base = [32][8]PreComputedGroupElement{
-	{
-		{
-			FieldElement{25967493, -14356035, 29566456, 3660896, -12694345, 4014787, 27544626, -11754271, -6079156, 2047605},
-			FieldElement{-12545711, 934262, -2722910, 3049990, -727428, 9406986, 12720692, 5043384, 19500929, -15469378},
-			FieldElement{-8738181, 4489570, 9688441, -14785194, 10184609, -12363380, 29287919, 11864899, -24514362, -4438546},
-		},
-		{
-			FieldElement{-12815894, -12976347, -21581243, 11784320, -25355658, -2750717, -11717903, -3814571, -358445, -10211303},
-			FieldElement{-21703237, 6903825, 27185491, 6451973, -29577724, -9554005, -15616551, 11189268, -26829678, -5319081},
-			FieldElement{26966642, 11152617, 32442495, 15396054, 14353839, -12752335, -3128826, -9541118, -15472047, -4166697},
-		},
-		{
-			FieldElement{15636291, -9688557, 24204773, -7912398, 616977, -16685262, 27787600, -14772189, 28944400, -1550024},
-			FieldElement{16568933, 4717097, -11556148, -1102322, 15682896, -11807043, 16354577, -11775962, 7689662, 11199574},
-			FieldElement{30464156, -5976125, -11779434, -15670865, 23220365, 15915852, 7512774, 10017326, -17749093, -9920357},
-		},
-		{
-			FieldElement{-17036878, 13921892, 10945806, -6033431, 27105052, -16084379, -28926210, 15006023, 3284568, -6276540},
-			FieldElement{23599295, -8306047, -11193664, -7687416, 13236774, 10506355, 7464579, 9656445, 13059162, 10374397},
-			FieldElement{7798556, 16710257, 3033922, 2874086, 28997861, 2835604, 32406664, -3839045, -641708, -101325},
-		},
-		{
-			FieldElement{10861363, 11473154, 27284546, 1981175, -30064349, 12577861, 32867885, 14515107, -15438304, 10819380},
-			FieldElement{4708026, 6336745, 20377586, 9066809, -11272109, 6594696, -25653668, 12483688, -12668491, 5581306},
-			FieldElement{19563160, 16186464, -29386857, 4097519, 10237984, -4348115, 28542350, 13850243, -23678021, -15815942},
-		},
-		{
-			FieldElement{-15371964, -12862754, 32573250, 4720197, -26436522, 5875511, -19188627, -15224819, -9818940, -12085777},
-			FieldElement{-8549212, 109983, 15149363, 2178705, 22900618, 4543417, 3044240, -15689887, 1762328, 14866737},
-			FieldElement{-18199695, -15951423, -10473290, 1707278, -17185920, 3916101, -28236412, 3959421, 27914454, 4383652},
-		},
-		{
-			FieldElement{5153746, 9909285, 1723747, -2777874, 30523605, 5516873, 19480852, 5230134, -23952439, -15175766},
-			FieldElement{-30269007, -3463509, 7665486, 10083793, 28475525, 1649722, 20654025, 16520125, 30598449, 7715701},
-			FieldElement{28881845, 14381568, 9657904, 3680757, -20181635, 7843316, -31400660, 1370708, 29794553, -1409300},
-		},
-		{
-			FieldElement{14499471, -2729599, -33191113, -4254652, 28494862, 14271267, 30290735, 10876454, -33154098, 2381726},
-			FieldElement{-7195431, -2655363, -14730155, 462251, -27724326, 3941372, -6236617, 3696005, -32300832, 15351955},
-			FieldElement{27431194, 8222322, 16448760, -3907995, -18707002, 11938355, -32961401, -2970515, 29551813, 10109425},
-		},
-	},
-	{
-		{
-			FieldElement{-13657040, -13155431, -31283750, 11777098, 21447386, 6519384, -2378284, -1627556, 10092783, -4764171},
-			FieldElement{27939166, 14210322, 4677035, 16277044, -22964462, -12398139, -32508754, 12005538, -17810127, 12803510},
-			FieldElement{17228999, -15661624, -1233527, 300140, -1224870, -11714777, 30364213, -9038194, 18016357, 4397660},
-		},
-		{
-			FieldElement{-10958843, -7690207, 4776341, -14954238, 27850028, -15602212, -26619106, 14544525, -17477504, 982639},
-			FieldElement{29253598, 15796703, -2863982, -9908884, 10057023, 3163536, 7332899, -4120128, -21047696, 9934963},
-			FieldElement{5793303, 16271923, -24131614, -10116404, 29188560, 1206517, -14747930, 4559895, -30123922, -10897950},
-		},
-		{
-			FieldElement{-27643952, -11493006, 16282657, -11036493, 28414021, -15012264, 24191034, 4541697, -13338309, 5500568},
-			FieldElement{12650548, -1497113, 9052871, 11355358, -17680037, -8400164, -17430592, 12264343, 10874051, 13524335},
-			FieldElement{25556948, -3045990, 714651, 2510400, 23394682, -10415330, 33119038, 5080568, -22528059, 5376628},
-		},
-		{
-			FieldElement{-26088264, -4011052, -17013699, -3537628, -6726793, 1920897, -22321305, -9447443, 4535768, 1569007},
-			FieldElement{-2255422, 14606630, -21692440, -8039818, 28430649, 8775819, -30494562, 3044290, 31848280, 12543772},
-			FieldElement{-22028579, 2943893, -31857513, 6777306, 13784462, -4292203, -27377195, -2062731, 7718482, 14474653},
-		},
-		{
-			FieldElement{2385315, 2454213, -22631320, 46603, -4437935, -15680415, 656965, -7236665, 24316168, -5253567},
-			FieldElement{13741529, 10911568, -33233417, -8603737, -20177830, -1033297, 33040651, -13424532, -20729456, 8321686},
-			FieldElement{21060490, -2212744, 15712757, -4336099, 1639040, 10656336, 23845965, -11874838, -9984458, 608372},
-		},
-		{
-			FieldElement{-13672732, -15087586, -10889693, -7557059, -6036909, 11305547, 1123968, -6780577, 27229399, 23887},
-			FieldElement{-23244140, -294205, -11744728, 14712571, -29465699, -2029617, 12797024, -6440308, -1633405, 16678954},
-			FieldElement{-29500620, 4770662, -16054387, 14001338, 7830047, 9564805, -1508144, -4795045, -17169265, 4904953},
-		},
-		{
-			FieldElement{24059557, 14617003, 19037157, -15039908, 19766093, -14906429, 5169211, 16191880, 2128236, -4326833},
-			FieldElement{-16981152, 4124966, -8540610, -10653797, 30336522, -14105247, -29806336, 916033, -6882542, -2986532},
-			FieldElement{-22630907, 12419372, -7134229, -7473371, -16478904, 16739175, 285431, 2763829, 15736322, 4143876},
-		},
-		{
-			FieldElement{2379352, 11839345, -4110402, -5988665, 11274298, 794957, 212801, -14594663, 23527084, -16458268},
-			FieldElement{33431127, -11130478, -17838966, -15626900, 8909499, 8376530, -32625340, 4087881, -15188911, -14416214},
-			FieldElement{1767683, 7197987, -13205226, -2022635, -13091350, 448826, 5799055, 4357868, -4774191, -16323038},
-		},
-	},
-	{
-		{
-			FieldElement{6721966, 13833823, -23523388, -1551314, 26354293, -11863321, 23365147, -3949732, 7390890, 2759800},
-			FieldElement{4409041, 2052381, 23373853, 10530217, 7676779, -12885954, 21302353, -4264057, 1244380, -12919645},
-			FieldElement{-4421239, 7169619, 4982368, -2957590, 30256825, -2777540, 14086413, 9208236, 15886429, 16489664},
-		},
-		{
-			FieldElement{1996075, 10375649, 14346367, 13311202, -6874135, -16438411, -13693198, 398369, -30606455, -712933},
-			FieldElement{-25307465, 9795880, -2777414, 14878809, -33531835, 14780363, 13348553, 12076947, -30836462, 5113182},
-			FieldElement{-17770784, 11797796, 31950843, 13929123, -25888302, 12288344, -30341101, -7336386, 13847711, 5387222},
-		},
-		{
-			FieldElement{-18582163, -3416217, 17824843, -2340966, 22744343, -10442611, 8763061, 3617786, -19600662, 10370991},
-			FieldElement{20246567, -14369378, 22358229, -543712, 18507283, -10413996, 14554437, -8746092, 32232924, 16763880},
-			FieldElement{9648505, 10094563, 26416693, 14745928, -30374318, -6472621, 11094161, 15689506, 3140038, -16510092},
-		},
-		{
-			FieldElement{-16160072, 5472695, 31895588, 4744994, 8823515, 10365685, -27224800, 9448613, -28774454, 366295},
-			FieldElement{19153450, 11523972, -11096490, -6503142, -24647631, 5420647, 28344573, 8041113, 719605, 11671788},
-			FieldElement{8678025, 2694440, -6808014, 2517372, 4964326, 11152271, -15432916, -15266516, 27000813, -10195553},
-		},
-		{
-			FieldElement{-15157904, 7134312, 8639287, -2814877, -7235688, 10421742, 564065, 5336097, 6750977, -14521026},
-			FieldElement{11836410, -3979488, 26297894, 16080799, 23455045, 15735944, 1695823, -8819122, 8169720, 16220347},
-			FieldElement{-18115838, 8653647, 17578566, -6092619, -8025777, -16012763, -11144307, -2627664, -5990708, -14166033},
-		},
-		{
-			FieldElement{-23308498, -10968312, 15213228, -10081214, -30853605, -11050004, 27884329, 2847284, 2655861, 1738395},
-			FieldElement{-27537433, -14253021, -25336301, -8002780, -9370762, 8129821, 21651608, -3239336, -19087449, -11005278},
-			FieldElement{1533110, 3437855, 23735889, 459276, 29970501, 11335377, 26030092, 5821408, 10478196, 8544890},
-		},
-		{
-			FieldElement{32173121, -16129311, 24896207, 3921497, 22579056, -3410854, 19270449, 12217473, 17789017, -3395995},
-			FieldElement{-30552961, -2228401, -15578829, -10147201, 13243889, 517024, 15479401, -3853233, 30460520, 1052596},
-			FieldElement{-11614875, 13323618, 32618793, 8175907, -15230173, 12596687, 27491595, -4612359, 3179268, -9478891},
-		},
-		{
-			FieldElement{31947069, -14366651, -4640583, -15339921, -15125977, -6039709, -14756777, -16411740, 19072640, -9511060},
-			FieldElement{11685058, 11822410, 3158003, -13952594, 33402194, -4165066, 5977896, -5215017, 473099, 5040608},
-			FieldElement{-20290863, 8198642, -27410132, 11602123, 1290375, -2799760, 28326862, 1721092, -19558642, -3131606},
-		},
-	},
-	{
-		{
-			FieldElement{7881532, 10687937, 7578723, 7738378, -18951012, -2553952, 21820786, 8076149, -27868496, 11538389},
-			FieldElement{-19935666, 3899861, 18283497, -6801568, -15728660, -11249211, 8754525, 7446702, -5676054, 5797016},
-			FieldElement{-11295600, -3793569, -15782110, -7964573, 12708869, -8456199, 2014099, -9050574, -2369172, -5877341},
-		},
-		{
-			FieldElement{-22472376, -11568741, -27682020, 1146375, 18956691, 16640559, 1192730, -3714199, 15123619, 10811505},
-			FieldElement{14352098, -3419715, -18942044, 10822655, 32750596, 4699007, -70363, 15776356, -28886779, -11974553},
-			FieldElement{-28241164, -8072475, -4978962, -5315317, 29416931, 1847569, -20654173, -16484855, 4714547, -9600655},
-		},
-		{
-			FieldElement{15200332, 8368572, 19679101, 15970074, -31872674, 1959451, 24611599, -4543832, -11745876, 12340220},
-			FieldElement{12876937, -10480056, 33134381, 6590940, -6307776, 14872440, 9613953, 8241152, 15370987, 9608631},
-			FieldElement{-4143277, -12014408, 8446281, -391603, 4407738, 13629032, -7724868, 15866074, -28210621, -8814099},
-		},
-		{
-			FieldElement{26660628, -15677655, 8393734, 358047, -7401291, 992988, -23904233, 858697, 20571223, 8420556},
-			FieldElement{14620715, 13067227, -15447274, 8264467, 14106269, 15080814, 33531827, 12516406, -21574435, -12476749},
-			FieldElement{236881, 10476226, 57258, -14677024, 6472998, 2466984, 17258519, 7256740, 8791136, 15069930},
-		},
-		{
-			FieldElement{1276410, -9371918, 22949635, -16322807, -23493039, -5702186, 14711875, 4874229, -30663140, -2331391},
-			FieldElement{5855666, 4990204, -13711848, 7294284, -7804282, 1924647, -1423175, -7912378, -33069337, 9234253},
-			FieldElement{20590503, -9018988, 31529744, -7352666, -2706834, 10650548, 31559055, -11609587, 18979186, 13396066},
-		},
-		{
-			FieldElement{24474287, 4968103, 22267082, 4407354, 24063882, -8325180, -18816887, 13594782, 33514650, 7021958},
-			FieldElement{-11566906, -6565505, -21365085, 15928892, -26158305, 4315421, -25948728, -3916677, -21480480, 12868082},
-			FieldElement{-28635013, 13504661, 19988037, -2132761, 21078225, 6443208, -21446107, 2244500, -12455797, -8089383},
-		},
-		{
-			FieldElement{-30595528, 13793479, -5852820, 319136, -25723172, -6263899, 33086546, 8957937, -15233648, 5540521},
-			FieldElement{-11630176, -11503902, -8119500, -7643073, 2620056, 1022908, -23710744, -1568984, -16128528, -14962807},
-			FieldElement{23152971, 775386, 27395463, 14006635, -9701118, 4649512, 1689819, 892185, -11513277, -15205948},
-		},
-		{
-			FieldElement{9770129, 9586738, 26496094, 4324120, 1556511, -3550024, 27453819, 4763127, -19179614, 5867134},
-			FieldElement{-32765025, 1927590, 31726409, -4753295, 23962434, -16019500, 27846559, 5931263, -29749703, -16108455},
-			FieldElement{27461885, -2977536, 22380810, 1815854, -23033753, -3031938, 7283490, -15148073, -19526700, 7734629},
-		},
-	},
-	{
-		{
-			FieldElement{-8010264, -9590817, -11120403, 6196038, 29344158, -13430885, 7585295, -3176626, 18549497, 15302069},
-			FieldElement{-32658337, -6171222, -7672793, -11051681, 6258878, 13504381, 10458790, -6418461, -8872242, 8424746},
-			FieldElement{24687205, 8613276, -30667046, -3233545, 1863892, -1830544, 19206234, 7134917, -11284482, -828919},
-		},
-		{
-			FieldElement{11334899, -9218022, 8025293, 12707519, 17523892, -10476071, 10243738, -14685461, -5066034, 16498837},
-			FieldElement{8911542, 6887158, -9584260, -6958590, 11145641, -9543680, 17303925, -14124238, 6536641, 10543906},
-			FieldElement{-28946384, 15479763, -17466835, 568876, -1497683, 11223454, -2669190, -16625574, -27235709, 8876771},
-		},
-		{
-			FieldElement{-25742899, -12566864, -15649966, -846607, -33026686, -796288, -33481822, 15824474, -604426, -9039817},
-			FieldElement{10330056, 70051, 7957388, -9002667, 9764902, 15609756, 27698697, -4890037, 1657394, 3084098},
-			FieldElement{10477963, -7470260, 12119566, -13250805, 29016247, -5365589, 31280319, 14396151, -30233575, 15272409},
-		},
-		{
-			FieldElement{-12288309, 3169463, 28813183, 16658753, 25116432, -5630466, -25173957, -12636138, -25014757, 1950504},
-			FieldElement{-26180358, 9489187, 11053416, -14746161, -31053720, 5825630, -8384306, -8767532, 15341279, 8373727},
-			FieldElement{28685821, 7759505, -14378516, -12002860, -31971820, 4079242, 298136, -10232602, -2878207, 15190420},
-		},
-		{
-			FieldElement{-32932876, 13806336, -14337485, -15794431, -24004620, 10940928, 8669718, 2742393, -26033313, -6875003},
-			FieldElement{-1580388, -11729417, -25979658, -11445023, -17411874, -10912854, 9291594, -16247779, -12154742, 6048605},
-			FieldElement{-30305315, 14843444, 1539301, 11864366, 20201677, 1900163, 13934231, 5128323, 11213262, 9168384},
-		},
-		{
-			FieldElement{-26280513, 11007847, 19408960, -940758, -18592965, -4328580, -5088060, -11105150, 20470157, -16398701},
-			FieldElement{-23136053, 9282192, 14855179, -15390078, -7362815, -14408560, -22783952, 14461608, 14042978, 5230683},
-			FieldElement{29969567, -2741594, -16711867, -8552442, 9175486, -2468974, 21556951, 3506042, -5933891, -12449708},
-		},
-		{
-			FieldElement{-3144746, 8744661, 19704003, 4581278, -20430686, 6830683, -21284170, 8971513, -28539189, 15326563},
-			FieldElement{-19464629, 10110288, -17262528, -3503892, -23500387, 1355669, -15523050, 15300988, -20514118, 9168260},
-			FieldElement{-5353335, 4488613, -23803248, 16314347, 7780487, -15638939, -28948358, 9601605, 33087103, -9011387},
-		},
-		{
-			FieldElement{-19443170, -15512900, -20797467, -12445323, -29824447, 10229461, -27444329, -15000531, -5996870, 15664672},
-			FieldElement{23294591, -16632613, -22650781, -8470978, 27844204, 11461195, 13099750, -2460356, 18151676, 13417686},
-			FieldElement{-24722913, -4176517, -31150679, 5988919, -26858785, 6685065, 1661597, -12551441, 15271676, -15452665},
-		},
-	},
-	{
-		{
-			FieldElement{11433042, -13228665, 8239631, -5279517, -1985436, -725718, -18698764, 2167544, -6921301, -13440182},
-			FieldElement{-31436171, 15575146, 30436815, 12192228, -22463353, 9395379, -9917708, -8638997, 12215110, 12028277},
-			FieldElement{14098400, 6555944, 23007258, 5757252, -15427832, -12950502, 30123440, 4617780, -16900089, -655628},
-		},
-		{
-			FieldElement{-4026201, -15240835, 11893168, 13718664, -14809462, 1847385, -15819999, 10154009, 23973261, -12684474},
-			FieldElement{-26531820, -3695990, -1908898, 2534301, -31870557, -16550355, 18341390, -11419951, 32013174, -10103539},
-			FieldElement{-25479301, 10876443, -11771086, -14625140, -12369567, 1838104, 21911214, 6354752, 4425632, -837822},
-		},
-		{
-			FieldElement{-10433389, -14612966, 22229858, -3091047, -13191166, 776729, -17415375, -12020462, 4725005, 14044970},
-			FieldElement{19268650, -7304421, 1555349, 8692754, -21474059, -9910664, 6347390, -1411784, -19522291, -16109756},
-			FieldElement{-24864089, 12986008, -10898878, -5558584, -11312371, -148526, 19541418, 8180106, 9282262, 10282508},
-		},
-		{
-			FieldElement{-26205082, 4428547, -8661196, -13194263, 4098402, -14165257, 15522535, 8372215, 5542595, -10702683},
-			FieldElement{-10562541, 14895633, 26814552, -16673850, -17480754, -2489360, -2781891, 6993761, -18093885, 10114655},
-			FieldElement{-20107055, -929418, 31422704, 10427861, -7110749, 6150669, -29091755, -11529146, 25953725, -106158},
-		},
-		{
-			FieldElement{-4234397, -8039292, -9119125, 3046000, 2101609, -12607294, 19390020, 6094296, -3315279, 12831125},
-			FieldElement{-15998678, 7578152, 5310217, 14408357, -33548620, -224739, 31575954, 6326196, 7381791, -2421839},
-			FieldElement{-20902779, 3296811, 24736065, -16328389, 18374254, 7318640, 6295303, 8082724, -15362489, 12339664},
-		},
-		{
-			FieldElement{27724736, 2291157, 6088201, -14184798, 1792727, 5857634, 13848414, 15768922, 25091167, 14856294},
-			FieldElement{-18866652, 8331043, 24373479, 8541013, -701998, -9269457, 12927300, -12695493, -22182473, -9012899},
-			FieldElement{-11423429, -5421590, 11632845, 3405020, 30536730, -11674039, -27260765, 13866390, 30146206, 9142070},
-		},
-		{
-			FieldElement{3924129, -15307516, -13817122, -10054960, 12291820, -668366, -27702774, 9326384, -8237858, 4171294},
-			FieldElement{-15921940, 16037937, 6713787, 16606682, -21612135, 2790944, 26396185, 3731949, 345228, -5462949},
-			FieldElement{-21327538, 13448259, 25284571, 1143661, 20614966, -8849387, 2031539, -12391231, -16253183, -13582083},
-		},
-		{
-			FieldElement{31016211, -16722429, 26371392, -14451233, -5027349, 14854137, 17477601, 3842657, 28012650, -16405420},
-			FieldElement{-5075835, 9368966, -8562079, -4600902, -15249953, 6970560, -9189873, 16292057, -8867157, 3507940},
-			FieldElement{29439664, 3537914, 23333589, 6997794, -17555561, -11018068, -15209202, -15051267, -9164929, 6580396},
-		},
-	},
-	{
-		{
-			FieldElement{-12185861, -7679788, 16438269, 10826160, -8696817, -6235611, 17860444, -9273846, -2095802, 9304567},
-			FieldElement{20714564, -4336911, 29088195, 7406487, 11426967, -5095705, 14792667, -14608617, 5289421, -477127},
-			FieldElement{-16665533, -10650790, -6160345, -13305760, 9192020, -1802462, 17271490, 12349094, 26939669, -3752294},
-		},
-		{
-			FieldElement{-12889898, 9373458, 31595848, 16374215, 21471720, 13221525, -27283495, -12348559, -3698806, 117887},
-			FieldElement{22263325, -6560050, 3984570, -11174646, -15114008, -566785, 28311253, 5358056, -23319780, 541964},
-			FieldElement{16259219, 3261970, 2309254, -15534474, -16885711, -4581916, 24134070, -16705829, -13337066, -13552195},
-		},
-		{
-			FieldElement{9378160, -13140186, -22845982, -12745264, 28198281, -7244098, -2399684, -717351, 690426, 14876244},
-			FieldElement{24977353, -314384, -8223969, -13465086, 28432343, -1176353, -13068804, -12297348, -22380984, 6618999},
-			FieldElement{-1538174, 11685646, 12944378, 13682314, -24389511, -14413193, 8044829, -13817328, 32239829, -5652762},
-		},
-		{
-			FieldElement{-18603066, 4762990, -926250, 8885304, -28412480, -3187315, 9781647, -10350059, 32779359, 5095274},
-			FieldElement{-33008130, -5214506, -32264887, -3685216, 9460461, -9327423, -24601656, 14506724, 21639561, -2630236},
-			FieldElement{-16400943, -13112215, 25239338, 15531969, 3987758, -4499318, -1289502, -6863535, 17874574, 558605},
-		},
-		{
-			FieldElement{-13600129, 10240081, 9171883, 16131053, -20869254, 9599700, 33499487, 5080151, 2085892, 5119761},
-			FieldElement{-22205145, -2519528, -16381601, 414691, -25019550, 2170430, 30634760, -8363614, -31999993, -5759884},
-			FieldElement{-6845704, 15791202, 8550074, -1312654, 29928809, -12092256, 27534430, -7192145, -22351378, 12961482},
-		},
-		{
-			FieldElement{-24492060, -9570771, 10368194, 11582341, -23397293, -2245287, 16533930, 8206996, -30194652, -5159638},
-			FieldElement{-11121496, -3382234, 2307366, 6362031, -135455, 8868177, -16835630, 7031275, 7589640, 8945490},
-			FieldElement{-32152748, 8917967, 6661220, -11677616, -1192060, -15793393, 7251489, -11182180, 24099109, -14456170},
-		},
-		{
-			FieldElement{5019558, -7907470, 4244127, -14714356, -26933272, 6453165, -19118182, -13289025, -6231896, -10280736},
-			FieldElement{10853594, 10721687, 26480089, 5861829, -22995819, 1972175, -1866647, -10557898, -3363451, -6441124},
-			FieldElement{-17002408, 5906790, 221599, -6563147, 7828208, -13248918, 24362661, -2008168, -13866408, 7421392},
-		},
-		{
-			FieldElement{8139927, -6546497, 32257646, -5890546, 30375719, 1886181, -21175108, 15441252, 28826358, -4123029},
-			FieldElement{6267086, 9695052, 7709135, -16603597, -32869068, -1886135, 14795160, -7840124, 13746021, -1742048},
-			FieldElement{28584902, 7787108, -6732942, -15050729, 22846041, -7571236, -3181936, -363524, 4771362, -8419958},
-		},
-	},
-	{
-		{
-			FieldElement{24949256, 6376279, -27466481, -8174608, -18646154, -9930606, 33543569, -12141695, 3569627, 11342593},
-			FieldElement{26514989, 4740088, 27912651, 3697550, 19331575, -11472339, 6809886, 4608608, 7325975, -14801071},
-			FieldElement{-11618399, -14554430, -24321212, 7655128, -1369274, 5214312, -27400540, 10258390, -17646694, -8186692},
-		},
-		{
-			FieldElement{11431204, 15823007, 26570245, 14329124, 18029990, 4796082, -31446179, 15580664, 9280358, -3973687},
-			FieldElement{-160783, -10326257, -22855316, -4304997, -20861367, -13621002, -32810901, -11181622, -15545091, 4387441},
-			FieldElement{-20799378, 12194512, 3937617, -5805892, -27154820, 9340370, -24513992, 8548137, 20617071, -7482001},
-		},
-		{
-			FieldElement{-938825, -3930586, -8714311, 16124718, 24603125, -6225393, -13775352, -11875822, 24345683, 10325460},
-			FieldElement{-19855277, -1568885, -22202708, 8714034, 14007766, 6928528, 16318175, -1010689, 4766743, 3552007},
-			FieldElement{-21751364, -16730916, 1351763, -803421, -4009670, 3950935, 3217514, 14481909, 10988822, -3994762},
-		},
-		{
-			FieldElement{15564307, -14311570, 3101243, 5684148, 30446780, -8051356, 12677127, -6505343, -8295852, 13296005},
-			FieldElement{-9442290, 6624296, -30298964, -11913677, -4670981, -2057379, 31521204, 9614054, -30000824, 12074674},
-			FieldElement{4771191, -135239, 14290749, -13089852, 27992298, 14998318, -1413936, -1556716, 29832613, -16391035},
-		},
-		{
-			FieldElement{7064884, -7541174, -19161962, -5067537, -18891269, -2912736, 25825242, 5293297, -27122660, 13101590},
-			FieldElement{-2298563, 2439670, -7466610, 1719965, -27267541, -16328445, 32512469, -5317593, -30356070, -4190957},
-			FieldElement{-30006540, 10162316, -33180176, 3981723, -16482138, -13070044, 14413974, 9515896, 19568978, 9628812},
-		},
-		{
-			FieldElement{33053803, 199357, 15894591, 1583059, 27380243, -4580435, -17838894, -6106839, -6291786, 3437740},
-			FieldElement{-18978877, 3884493, 19469877, 12726490, 15913552, 13614290, -22961733, 70104, 7463304, 4176122},
-			FieldElement{-27124001, 10659917, 11482427, -16070381, 12771467, -6635117, -32719404, -5322751, 24216882, 5944158},
-		},
-		{
-			FieldElement{8894125, 7450974, -2664149, -9765752, -28080517, -12389115, 19345746, 14680796, 11632993, 5847885},
-			FieldElement{26942781, -2315317, 9129564, -4906607, 26024105, 11769399, -11518837, 6367194, -9727230, 4782140},
-			FieldElement{19916461, -4828410, -22910704, -11414391, 25606324, -5972441, 33253853, 8220911, 6358847, -1873857},
-		},
-		{
-			FieldElement{801428, -2081702, 16569428, 11065167, 29875704, 96627, 7908388, -4480480, -13538503, 1387155},
-			FieldElement{19646058, 5720633, -11416706, 12814209, 11607948, 12749789, 14147075, 15156355, -21866831, 11835260},
-			FieldElement{19299512, 1155910, 28703737, 14890794, 2925026, 7269399, 26121523, 15467869, -26560550, 5052483},
-		},
-	},
-	{
-		{
-			FieldElement{-3017432, 10058206, 1980837, 3964243, 22160966, 12322533, -6431123, -12618185, 12228557, -7003677},
-			FieldElement{32944382, 14922211, -22844894, 5188528, 21913450, -8719943, 4001465, 13238564, -6114803, 8653815},
-			FieldElement{22865569, -4652735, 27603668, -12545395, 14348958, 8234005, 24808405, 5719875, 28483275, 2841751},
-		},
-		{
-			FieldElement{-16420968, -1113305, -327719, -12107856, 21886282, -15552774, -1887966, -315658, 19932058, -12739203},
-			FieldElement{-11656086, 10087521, -8864888, -5536143, -19278573, -3055912, 3999228, 13239134, -4777469, -13910208},
-			FieldElement{1382174, -11694719, 17266790, 9194690, -13324356, 9720081, 20403944, 11284705, -14013818, 3093230},
-		},
-		{
-			FieldElement{16650921, -11037932, -1064178, 1570629, -8329746, 7352753, -302424, 16271225, -24049421, -6691850},
-			FieldElement{-21911077, -5927941, -4611316, -5560156, -31744103, -10785293, 24123614, 15193618, -21652117, -16739389},
-			FieldElement{-9935934, -4289447, -25279823, 4372842, 2087473, 10399484, 31870908, 14690798, 17361620, 11864968},
-		},
-		{
-			FieldElement{-11307610, 6210372, 13206574, 5806320, -29017692, -13967200, -12331205, -7486601, -25578460, -16240689},
-			FieldElement{14668462, -12270235, 26039039, 15305210, 25515617, 4542480, 10453892, 6577524, 9145645, -6443880},
-			FieldElement{5974874, 3053895, -9433049, -10385191, -31865124, 3225009, -7972642, 3936128, -5652273, -3050304},
-		},
-		{
-			FieldElement{30625386, -4729400, -25555961, -12792866, -20484575, 7695099, 17097188, -16303496, -27999779, 1803632},
-			FieldElement{-3553091, 9865099, -5228566, 4272701, -5673832, -16689700, 14911344, 12196514, -21405489, 7047412},
-			FieldElement{20093277, 9920966, -11138194, -5343857, 13161587, 12044805, -32856851, 4124601, -32343828, -10257566},
-		},
-		{
-			FieldElement{-20788824, 14084654, -13531713, 7842147, 19119038, -13822605, 4752377, -8714640, -21679658, 2288038},
-			FieldElement{-26819236, -3283715, 29965059, 3039786, -14473765, 2540457, 29457502, 14625692, -24819617, 12570232},
-			FieldElement{-1063558, -11551823, 16920318, 12494842, 1278292, -5869109, -21159943, -3498680, -11974704, 4724943},
-		},
-		{
-			FieldElement{17960970, -11775534, -4140968, -9702530, -8876562, -1410617, -12907383, -8659932, -29576300, 1903856},
-			FieldElement{23134274, -14279132, -10681997, -1611936, 20684485, 15770816, -12989750, 3190296, 26955097, 14109738},
-			FieldElement{15308788, 5320727, -30113809, -14318877, 22902008, 7767164, 29425325, -11277562, 31960942, 11934971},
-		},
-		{
-			FieldElement{-27395711, 8435796, 4109644, 12222639, -24627868, 14818669, 20638173, 4875028, 10491392, 1379718},
-			FieldElement{-13159415, 9197841, 3875503, -8936108, -1383712, -5879801, 33518459, 16176658, 21432314, 12180697},
-			FieldElement{-11787308, 11500838, 13787581, -13832590, -22430679, 10140205, 1465425, 12689540, -10301319, -13872883},
-		},
-	},
-	{
-		{
-			FieldElement{5414091, -15386041, -21007664, 9643570, 12834970, 1186149, -2622916, -1342231, 26128231, 6032912},
-			FieldElement{-26337395, -13766162, 32496025, -13653919, 17847801, -12669156, 3604025, 8316894, -25875034, -10437358},
-			FieldElement{3296484, 6223048, 24680646, -12246460, -23052020, 5903205, -8862297, -4639164, 12376617, 3188849},
-		},
-		{
-			FieldElement{29190488, -14659046, 27549113, -1183516, 3520066, -10697301, 32049515, -7309113, -16109234, -9852307},
-			FieldElement{-14744486, -9309156, 735818, -598978, -20407687, -5057904, 25246078, -15795669, 18640741, -960977},
-			FieldElement{-6928835, -16430795, 10361374, 5642961, 4910474, 12345252, -31638386, -494430, 10530747, 1053335},
-		},
-		{
-			FieldElement{-29265967, -14186805, -13538216, -12117373, -19457059, -10655384, -31462369, -2948985, 24018831, 15026644},
-			FieldElement{-22592535, -3145277, -2289276, 5953843, -13440189, 9425631, 25310643, 13003497, -2314791, -15145616},
-			FieldElement{-27419985, -603321, -8043984, -1669117, -26092265, 13987819, -27297622, 187899, -23166419, -2531735},
-		},
-		{
-			FieldElement{-21744398, -13810475, 1844840, 5021428, -10434399, -15911473, 9716667, 16266922, -5070217, 726099},
-			FieldElement{29370922, -6053998, 7334071, -15342259, 9385287, 2247707, -13661962, -4839461, 30007388, -15823341},
-			FieldElement{-936379, 16086691, 23751945, -543318, -1167538, -5189036, 9137109, 730663, 9835848, 4555336},
-		},
-		{
-			FieldElement{-23376435, 1410446, -22253753, -12899614, 30867635, 15826977, 17693930, 544696, -11985298, 12422646},
-			FieldElement{31117226, -12215734, -13502838, 6561947, -9876867, -12757670, -5118685, -4096706, 29120153, 13924425},
-			FieldElement{-17400879, -14233209, 19675799, -2734756, -11006962, -5858820, -9383939, -11317700, 7240931, -237388},
-		},
-		{
-			FieldElement{-31361739, -11346780, -15007447, -5856218, -22453340, -12152771, 1222336, 4389483, 3293637, -15551743},
-			FieldElement{-16684801, -14444245, 11038544, 11054958, -13801175, -3338533, -24319580, 7733547, 12796905, -6335822},
-			FieldElement{-8759414, -10817836, -25418864, 10783769, -30615557, -9746811, -28253339, 3647836, 3222231, -11160462},
-		},
-		{
-			FieldElement{18606113, 1693100, -25448386, -15170272, 4112353, 10045021, 23603893, -2048234, -7550776, 2484985},
-			FieldElement{9255317, -3131197, -12156162, -1004256, 13098013, -9214866, 16377220, -2102812, -19802075, -3034702},
-			FieldElement{-22729289, 7496160, -5742199, 11329249, 19991973, -3347502, -31718148, 9936966, -30097688, -10618797},
-		},
-		{
-			FieldElement{21878590, -5001297, 4338336, 13643897, -3036865, 13160960, 19708896, 5415497, -7360503, -4109293},
-			FieldElement{27736861, 10103576, 12500508, 8502413, -3413016, -9633558, 10436918, -1550276, -23659143, -8132100},
-			FieldElement{19492550, -12104365, -29681976, -852630, -3208171, 12403437, 30066266, 8367329, 13243957, 8709688},
-		},
-	},
-	{
-		{
-			FieldElement{12015105, 2801261, 28198131, 10151021, 24818120, -4743133, -11194191, -5645734, 5150968, 7274186},
-			FieldElement{2831366, -12492146, 1478975, 6122054, 23825128, -12733586, 31097299, 6083058, 31021603, -9793610},
-			FieldElement{-2529932, -2229646, 445613, 10720828, -13849527, -11505937, -23507731, 16354465, 15067285, -14147707},
-		},
-		{
-			FieldElement{7840942, 14037873, -33364863, 15934016, -728213, -3642706, 21403988, 1057586, -19379462, -12403220},
-			FieldElement{915865, -16469274, 15608285, -8789130, -24357026, 6060030, -17371319, 8410997, -7220461, 16527025},
-			FieldElement{32922597, -556987, 20336074, -16184568, 10903705, -5384487, 16957574, 52992, 23834301, 6588044},
-		},
-		{
-			FieldElement{32752030, 11232950, 3381995, -8714866, 22652988, -10744103, 17159699, 16689107, -20314580, -1305992},
-			FieldElement{-4689649, 9166776, -25710296, -10847306, 11576752, 12733943, 7924251, -2752281, 1976123, -7249027},
-			FieldElement{21251222, 16309901, -2983015, -6783122, 30810597, 12967303, 156041, -3371252, 12331345, -8237197},
-		},
-		{
-			FieldElement{8651614, -4477032, -16085636, -4996994, 13002507, 2950805, 29054427, -5106970, 10008136, -4667901},
-			FieldElement{31486080, 15114593, -14261250, 12951354, 14369431, -7387845, 16347321, -13662089, 8684155, -10532952},
-			FieldElement{19443825, 11385320, 24468943, -9659068, -23919258, 2187569, -26263207, -6086921, 31316348, 14219878},
-		},
-		{
-			FieldElement{-28594490, 1193785, 32245219, 11392485, 31092169, 15722801, 27146014, 6992409, 29126555, 9207390},
-			FieldElement{32382935, 1110093, 18477781, 11028262, -27411763, -7548111, -4980517, 10843782, -7957600, -14435730},
-			FieldElement{2814918, 7836403, 27519878, -7868156, -20894015, -11553689, -21494559, 8550130, 28346258, 1994730},
-		},
-		{
-			FieldElement{-19578299, 8085545, -14000519, -3948622, 2785838, -16231307, -19516951, 7174894, 22628102, 8115180},
-			FieldElement{-30405132, 955511, -11133838, -15078069, -32447087, -13278079, -25651578, 3317160, -9943017, 930272},
-			FieldElement{-15303681, -6833769, 28856490, 1357446, 23421993, 1057177, 24091212, -1388970, -22765376, -10650715},
-		},
-		{
-			FieldElement{-22751231, -5303997, -12907607, -12768866, -15811511, -7797053, -14839018, -16554220, -1867018, 8398970},
-			FieldElement{-31969310, 2106403, -4736360, 1362501, 12813763, 16200670, 22981545, -6291273, 18009408, -15772772},
-			FieldElement{-17220923, -9545221, -27784654, 14166835, 29815394, 7444469, 29551787, -3727419, 19288549, 1325865},
-		},
-		{
-			FieldElement{15100157, -15835752, -23923978, -1005098, -26450192, 15509408, 12376730, -3479146, 33166107, -8042750},
-			FieldElement{20909231, 13023121, -9209752, 16251778, -5778415, -8094914, 12412151, 10018715, 2213263, -13878373},
-			FieldElement{32529814, -11074689, 30361439, -16689753, -9135940, 1513226, 22922121, 6382134, -5766928, 8371348},
-		},
-	},
-	{
-		{
-			FieldElement{9923462, 11271500, 12616794, 3544722, -29998368, -1721626, 12891687, -8193132, -26442943, 10486144},
-			FieldElement{-22597207, -7012665, 8587003, -8257861, 4084309, -12970062, 361726, 2610596, -23921530, -11455195},
-			FieldElement{5408411, -1136691, -4969122, 10561668, 24145918, 14240566, 31319731, -4235541, 19985175, -3436086},
-		},
-		{
-			FieldElement{-13994457, 16616821, 14549246, 3341099, 32155958, 13648976, -17577068, 8849297, 65030, 8370684},
-			FieldElement{-8320926, -12049626, 31204563, 5839400, -20627288, -1057277, -19442942, 6922164, 12743482, -9800518},
-			FieldElement{-2361371, 12678785, 28815050, 4759974, -23893047, 4884717, 23783145, 11038569, 18800704, 255233},
-		},
-		{
-			FieldElement{-5269658, -1773886, 13957886, 7990715, 23132995, 728773, 13393847, 9066957, 19258688, -14753793},
-			FieldElement{-2936654, -10827535, -10432089, 14516793, -3640786, 4372541, -31934921, 2209390, -1524053, 2055794},
-			FieldElement{580882, 16705327, 5468415, -2683018, -30926419, -14696000, -7203346, -8994389, -30021019, 7394435},
-		},
-		{
-			FieldElement{23838809, 1822728, -15738443, 15242727, 8318092, -3733104, -21672180, -3492205, -4821741, 14799921},
-			FieldElement{13345610, 9759151, 3371034, -16137791, 16353039, 8577942, 31129804, 13496856, -9056018, 7402518},
-			FieldElement{2286874, -4435931, -20042458, -2008336, -13696227, 5038122, 11006906, -15760352, 8205061, 1607563},
-		},
-		{
-			FieldElement{14414086, -8002132, 3331830, -3208217, 22249151, -5594188, 18364661, -2906958, 30019587, -9029278},
-			FieldElement{-27688051, 1585953, -10775053, 931069, -29120221, -11002319, -14410829, 12029093, 9944378, 8024},
-			FieldElement{4368715, -3709630, 29874200, -15022983, -20230386, -11410704, -16114594, -999085, -8142388, 5640030},
-		},
-		{
-			FieldElement{10299610, 13746483, 11661824, 16234854, 7630238, 5998374, 9809887, -16694564, 15219798, -14327783},
-			FieldElement{27425505, -5719081, 3055006, 10660664, 23458024, 595578, -15398605, -1173195, -18342183, 9742717},
-			FieldElement{6744077, 2427284, 26042789, 2720740, -847906, 1118974, 32324614, 7406442, 12420155, 1994844},
-		},
-		{
-			FieldElement{14012521, -5024720, -18384453, -9578469, -26485342, -3936439, -13033478, -10909803, 24319929, -6446333},
-			FieldElement{16412690, -4507367, 10772641, 15929391, -17068788, -4658621, 10555945, -10484049, -30102368, -4739048},
-			FieldElement{22397382, -7767684, -9293161, -12792868, 17166287, -9755136, -27333065, 6199366, 21880021, -12250760},
-		},
-		{
-			FieldElement{-4283307, 5368523, -31117018, 8163389, -30323063, 3209128, 16557151, 8890729, 8840445, 4957760},
-			FieldElement{-15447727, 709327, -6919446, -10870178, -29777922, 6522332, -21720181, 12130072, -14796503, 5005757},
-			FieldElement{-2114751, -14308128, 23019042, 15765735, -25269683, 6002752, 10183197, -13239326, -16395286, -2176112},
-		},
-	},
-	{
-		{
-			FieldElement{-19025756, 1632005, 13466291, -7995100, -23640451, 16573537, -32013908, -3057104, 22208662, 2000468},
-			FieldElement{3065073, -1412761, -25598674, -361432, -17683065, -5703415, -8164212, 11248527, -3691214, -7414184},
-			FieldElement{10379208, -6045554, 8877319, 1473647, -29291284, -12507580, 16690915, 2553332, -3132688, 16400289},
-		},
-		{
-			FieldElement{15716668, 1254266, -18472690, 7446274, -8448918, 6344164, -22097271, -7285580, 26894937, 9132066},
-			FieldElement{24158887, 12938817, 11085297, -8177598, -28063478, -4457083, -30576463, 64452, -6817084, -2692882},
-			FieldElement{13488534, 7794716, 22236231, 5989356, 25426474, -12578208, 2350710, -3418511, -4688006, 2364226},
-		},
-		{
-			FieldElement{16335052, 9132434, 25640582, 6678888, 1725628, 8517937, -11807024, -11697457, 15445875, -7798101},
-			FieldElement{29004207, -7867081, 28661402, -640412, -12794003, -7943086, 31863255, -4135540, -278050, -15759279},
-			FieldElement{-6122061, -14866665, -28614905, 14569919, -10857999, -3591829, 10343412, -6976290, -29828287, -10815811},
-		},
-		{
-			FieldElement{27081650, 3463984, 14099042, -4517604, 1616303, -6205604, 29542636, 15372179, 17293797, 960709},
-			FieldElement{20263915, 11434237, -5765435, 11236810, 13505955, -10857102, -16111345, 6493122, -19384511, 7639714},
-			FieldElement{-2830798, -14839232, 25403038, -8215196, -8317012, -16173699, 18006287, -16043750, 29994677, -15808121},
-		},
-		{
-			FieldElement{9769828, 5202651, -24157398, -13631392, -28051003, -11561624, -24613141, -13860782, -31184575, 709464},
-			FieldElement{12286395, 13076066, -21775189, -1176622, -25003198, 4057652, -32018128, -8890874, 16102007, 13205847},
-			FieldElement{13733362, 5599946, 10557076, 3195751, -5557991, 8536970, -25540170, 8525972, 10151379, 10394400},
-		},
-		{
-			FieldElement{4024660, -16137551, 22436262, 12276534, -9099015, -2686099, 19698229, 11743039, -33302334, 8934414},
-			FieldElement{-15879800, -4525240, -8580747, -2934061, 14634845, -698278, -9449077, 3137094, -11536886, 11721158},
-			FieldElement{17555939, -5013938, 8268606, 2331751, -22738815, 9761013, 9319229, 8835153, -9205489, -1280045},
-		},
-		{
-			FieldElement{-461409, -7830014, 20614118, 16688288, -7514766, -4807119, 22300304, 505429, 6108462, -6183415},
-			FieldElement{-5070281, 12367917, -30663534, 3234473, 32617080, -8422642, 29880583, -13483331, -26898490, -7867459},
-			FieldElement{-31975283, 5726539, 26934134, 10237677, -3173717, -605053, 24199304, 3795095, 7592688, -14992079},
-		},
-		{
-			FieldElement{21594432, -14964228, 17466408, -4077222, 32537084, 2739898, 6407723, 12018833, -28256052, 4298412},
-			FieldElement{-20650503, -11961496, -27236275, 570498, 3767144, -1717540, 13891942, -1569194, 13717174, 10805743},
-			FieldElement{-14676630, -15644296, 15287174, 11927123, 24177847, -8175568, -796431, 14860609, -26938930, -5863836},
-		},
-	},
-	{
-		{
-			FieldElement{12962541, 5311799, -10060768, 11658280, 18855286, -7954201, 13286263, -12808704, -4381056, 9882022},
-			FieldElement{18512079, 11319350, -20123124, 15090309, 18818594, 5271736, -22727904, 3666879, -23967430, -3299429},
-			FieldElement{-6789020, -3146043, 16192429, 13241070, 15898607, -14206114, -10084880, -6661110, -2403099, 5276065},
-		},
-		{
-			FieldElement{30169808, -5317648, 26306206, -11750859, 27814964, 7069267, 7152851, 3684982, 1449224, 13082861},
-			FieldElement{10342826, 3098505, 2119311, 193222, 25702612, 12233820, 23697382, 15056736, -21016438, -8202000},
-			FieldElement{-33150110, 3261608, 22745853, 7948688, 19370557, -15177665, -26171976, 6482814, -10300080, -11060101},
-		},
-		{
-			FieldElement{32869458, -5408545, 25609743, 15678670, -10687769, -15471071, 26112421, 2521008, -22664288, 6904815},
-			FieldElement{29506923, 4457497, 3377935, -9796444, -30510046, 12935080, 1561737, 3841096, -29003639, -6657642},
-			FieldElement{10340844, -6630377, -18656632, -2278430, 12621151, -13339055, 30878497, -11824370, -25584551, 5181966},
-		},
-		{
-			FieldElement{25940115, -12658025, 17324188, -10307374, -8671468, 15029094, 24396252, -16450922, -2322852, -12388574},
-			FieldElement{-21765684, 9916823, -1300409, 4079498, -1028346, 11909559, 1782390, 12641087, 20603771, -6561742},
-			FieldElement{-18882287, -11673380, 24849422, 11501709, 13161720, -4768874, 1925523, 11914390, 4662781, 7820689},
-		},
-		{
-			FieldElement{12241050, -425982, 8132691, 9393934, 32846760, -1599620, 29749456, 12172924, 16136752, 15264020},
-			FieldElement{-10349955, -14680563, -8211979, 2330220, -17662549, -14545780, 10658213, 6671822, 19012087, 3772772},
-			FieldElement{3753511, -3421066, 10617074, 2028709, 14841030, -6721664, 28718732, -15762884, 20527771, 12988982},
-		},
-		{
-			FieldElement{-14822485, -5797269, -3707987, 12689773, -898983, -10914866, -24183046, -10564943, 3299665, -12424953},
-			FieldElement{-16777703, -15253301, -9642417, 4978983, 3308785, 8755439, 6943197, 6461331, -25583147, 8991218},
-			FieldElement{-17226263, 1816362, -1673288, -6086439, 31783888, -8175991, -32948145, 7417950, -30242287, 1507265},
-		},
-		{
-			FieldElement{29692663, 6829891, -10498800, 4334896, 20945975, -11906496, -28887608, 8209391, 14606362, -10647073},
-			FieldElement{-3481570, 8707081, 32188102, 5672294, 22096700, 1711240, -33020695, 9761487, 4170404, -2085325},
-			FieldElement{-11587470, 14855945, -4127778, -1531857, -26649089, 15084046, 22186522, 16002000, -14276837, -8400798},
-		},
-		{
-			FieldElement{-4811456, 13761029, -31703877, -2483919, -3312471, 7869047, -7113572, -9620092, 13240845, 10965870},
-			FieldElement{-7742563, -8256762, -14768334, -13656260, -23232383, 12387166, 4498947, 14147411, 29514390, 4302863},
-			FieldElement{-13413405, -12407859, 20757302, -13801832, 14785143, 8976368, -5061276, -2144373, 17846988, -13971927},
-		},
-	},
-	{
-		{
-			FieldElement{-2244452, -754728, -4597030, -1066309, -6247172, 1455299, -21647728, -9214789, -5222701, 12650267},
-			FieldElement{-9906797, -16070310, 21134160, 12198166, -27064575, 708126, 387813, 13770293, -19134326, 10958663},
-			FieldElement{22470984, 12369526, 23446014, -5441109, -21520802, -9698723, -11772496, -11574455, -25083830, 4271862},
-		},
-		{
-			FieldElement{-25169565, -10053642, -19909332, 15361595, -5984358, 2159192, 75375, -4278529, -32526221, 8469673},
-			FieldElement{15854970, 4148314, -8893890, 7259002, 11666551, 13824734, -30531198, 2697372, 24154791, -9460943},
-			FieldElement{15446137, -15806644, 29759747, 14019369, 30811221, -9610191, -31582008, 12840104, 24913809, 9815020},
-		},
-		{
-			FieldElement{-4709286, -5614269, -31841498, -12288893, -14443537, 10799414, -9103676, 13438769, 18735128, 9466238},
-			FieldElement{11933045, 9281483, 5081055, -5183824, -2628162, -4905629, -7727821, -10896103, -22728655, 16199064},
-			FieldElement{14576810, 379472, -26786533, -8317236, -29426508, -10812974, -102766, 1876699, 30801119, 2164795},
-		},
-		{
-			FieldElement{15995086, 3199873, 13672555, 13712240, -19378835, -4647646, -13081610, -15496269, -13492807, 1268052},
-			FieldElement{-10290614, -3659039, -3286592, 10948818, 23037027, 3794475, -3470338, -12600221, -17055369, 3565904},
-			FieldElement{29210088, -9419337, -5919792, -4952785, 10834811, -13327726, -16512102, -10820713, -27162222, -14030531},
-		},
-		{
-			FieldElement{-13161890, 15508588, 16663704, -8156150, -28349942, 9019123, -29183421, -3769423, 2244111, -14001979},
-			FieldElement{-5152875, -3800936, -9306475, -6071583, 16243069, 14684434, -25673088, -16180800, 13491506, 4641841},
-			FieldElement{10813417, 643330, -19188515, -728916, 30292062, -16600078, 27548447, -7721242, 14476989, -12767431},
-		},
-		{
-			FieldElement{10292079, 9984945, 6481436, 8279905, -7251514, 7032743, 27282937, -1644259, -27912810, 12651324},
-			FieldElement{-31185513, -813383, 22271204, 11835308, 10201545, 15351028, 17099662, 3988035, 21721536, -3148940},
-			FieldElement{10202177, -6545839, -31373232, -9574638, -32150642, -8119683, -12906320, 3852694, 13216206, 14842320},
-		},
-		{
-			FieldElement{-15815640, -10601066, -6538952, -7258995, -6984659, -6581778, -31500847, 13765824, -27434397, 9900184},
-			FieldElement{14465505, -13833331, -32133984, -14738873, -27443187, 12990492, 33046193, 15796406, -7051866, -8040114},
-			FieldElement{30924417, -8279620, 6359016, -12816335, 16508377, 9071735, -25488601, 15413635, 9524356, -7018878},
-		},
-		{
-			FieldElement{12274201, -13175547, 32627641, -1785326, 6736625, 13267305, 5237659, -5109483, 15663516, 4035784},
-			FieldElement{-2951309, 8903985, 17349946, 601635, -16432815, -4612556, -13732739, -15889334, -22258478, 4659091},
-			FieldElement{-16916263, -4952973, -30393711, -15158821, 20774812, 15897498, 5736189, 15026997, -2178256, -13455585},
-		},
-	},
-	{
-		{
-			FieldElement{-8858980, -2219056, 28571666, -10155518, -474467, -10105698, -3801496, 278095, 23440562, -290208},
-			FieldElement{10226241, -5928702, 15139956, 120818, -14867693, 5218603, 32937275, 11551483, -16571960, -7442864},
-			FieldElement{17932739, -12437276, -24039557, 10749060, 11316803, 7535897, 22503767, 5561594, -3646624, 3898661},
-		},
-		{
-			FieldElement{7749907, -969567, -16339731, -16464, -25018111, 15122143, -1573531, 7152530, 21831162, 1245233},
-			FieldElement{26958459, -14658026, 4314586, 8346991, -5677764, 11960072, -32589295, -620035, -30402091, -16716212},
-			FieldElement{-12165896, 9166947, 33491384, 13673479, 29787085, 13096535, 6280834, 14587357, -22338025, 13987525},
-		},
-		{
-			FieldElement{-24349909, 7778775, 21116000, 15572597, -4833266, -5357778, -4300898, -5124639, -7469781, -2858068},
-			FieldElement{9681908, -6737123, -31951644, 13591838, -6883821, 386950, 31622781, 6439245, -14581012, 4091397},
-			FieldElement{-8426427, 1470727, -28109679, -1596990, 3978627, -5123623, -19622683, 12092163, 29077877, -14741988},
-		},
-		{
-			FieldElement{5269168, -6859726, -13230211, -8020715, 25932563, 1763552, -5606110, -5505881, -20017847, 2357889},
-			FieldElement{32264008, -15407652, -5387735, -1160093, -2091322, -3946900, 23104804, -12869908, 5727338, 189038},
-			FieldElement{14609123, -8954470, -6000566, -16622781, -14577387, -7743898, -26745169, 10942115, -25888931, -14884697},
-		},
-		{
-			FieldElement{20513500, 5557931, -15604613, 7829531, 26413943, -2019404, -21378968, 7471781, 13913677, -5137875},
-			FieldElement{-25574376, 11967826, 29233242, 12948236, -6754465, 4713227, -8940970, 14059180, 12878652, 8511905},
-			FieldElement{-25656801, 3393631, -2955415, -7075526, -2250709, 9366908, -30223418, 6812974, 5568676, -3127656},
-		},
-		{
-			FieldElement{11630004, 12144454, 2116339, 13606037, 27378885, 15676917, -17408753, -13504373, -14395196, 8070818},
-			FieldElement{27117696, -10007378, -31282771, -5570088, 1127282, 12772488, -29845906, 10483306, -11552749, -1028714},
-			FieldElement{10637467, -5688064, 5674781, 1072708, -26343588, -6982302, -1683975, 9177853, -27493162, 15431203},
-		},
-		{
-			FieldElement{20525145, 10892566, -12742472, 12779443, -29493034, 16150075, -28240519, 14943142, -15056790, -7935931},
-			FieldElement{-30024462, 5626926, -551567, -9981087, 753598, 11981191, 25244767, -3239766, -3356550, 9594024},
-			FieldElement{-23752644, 2636870, -5163910, -10103818, 585134, 7877383, 11345683, -6492290, 13352335, -10977084},
-		},
-		{
-			FieldElement{-1931799, -5407458, 3304649, -12884869, 17015806, -4877091, -29783850, -7752482, -13215537, -319204},
-			FieldElement{20239939, 6607058, 6203985, 3483793, -18386976, -779229, -20723742, 15077870, -22750759, 14523817},
-			FieldElement{27406042, -6041657, 27423596, -4497394, 4996214, 10002360, -28842031, -4545494, -30172742, -4805667},
-		},
-	},
-	{
-		{
-			FieldElement{11374242, 12660715, 17861383, -12540833, 10935568, 1099227, -13886076, -9091740, -27727044, 11358504},
-			FieldElement{-12730809, 10311867, 1510375, 10778093, -2119455, -9145702, 32676003, 11149336, -26123651, 4985768},
-			FieldElement{-19096303, 341147, -6197485, -239033, 15756973, -8796662, -983043, 13794114, -19414307, -15621255},
-		},
-		{
-			FieldElement{6490081, 11940286, 25495923, -7726360, 8668373, -8751316, 3367603, 6970005, -1691065, -9004790},
-			FieldElement{1656497, 13457317, 15370807, 6364910, 13605745, 8362338, -19174622, -5475723, -16796596, -5031438},
-			FieldElement{-22273315, -13524424, -64685, -4334223, -18605636, -10921968, -20571065, -7007978, -99853, -10237333},
-		},
-		{
-			FieldElement{17747465, 10039260, 19368299, -4050591, -20630635, -16041286, 31992683, -15857976, -29260363, -5511971},
-			FieldElement{31932027, -4986141, -19612382, 16366580, 22023614, 88450, 11371999, -3744247, 4882242, -10626905},
-			FieldElement{29796507, 37186, 19818052, 10115756, -11829032, 3352736, 18551198, 3272828, -5190932, -4162409},
-		},
-		{
-			FieldElement{12501286, 4044383, -8612957, -13392385, -32430052, 5136599, -19230378, -3529697, 330070, -3659409},
-			FieldElement{6384877, 2899513, 17807477, 7663917, -2358888, 12363165, 25366522, -8573892, -271295, 12071499},
-			FieldElement{-8365515, -4042521, 25133448, -4517355, -6211027, 2265927, -32769618, 1936675, -5159697, 3829363},
-		},
-		{
-			FieldElement{28425966, -5835433, -577090, -4697198, -14217555, 6870930, 7921550, -6567787, 26333140, 14267664},
-			FieldElement{-11067219, 11871231, 27385719, -10559544, -4585914, -11189312, 10004786, -8709488, -21761224, 8930324},
-			FieldElement{-21197785, -16396035, 25654216, -1725397, 12282012, 11008919, 1541940, 4757911, -26491501, -16408940},
-		},
-		{
-			FieldElement{13537262, -7759490, -20604840, 10961927, -5922820, -13218065, -13156584, 6217254, -15943699, 13814990},
-			FieldElement{-17422573, 15157790, 18705543, 29619, 24409717, -260476, 27361681, 9257833, -1956526, -1776914},
-			FieldElement{-25045300, -10191966, 15366585, 15166509, -13105086, 8423556, -29171540, 12361135, -18685978, 4578290},
-		},
-		{
-			FieldElement{24579768, 3711570, 1342322, -11180126, -27005135, 14124956, -22544529, 14074919, 21964432, 8235257},
-			FieldElement{-6528613, -2411497, 9442966, -5925588, 12025640, -1487420, -2981514, -1669206, 13006806, 2355433},
-			FieldElement{-16304899, -13605259, -6632427, -5142349, 16974359, -10911083, 27202044, 1719366, 1141648, -12796236},
-		},
-		{
-			FieldElement{-12863944, -13219986, -8318266, -11018091, -6810145, -4843894, 13475066, -3133972, 32674895, 13715045},
-			FieldElement{11423335, -5468059, 32344216, 8962751, 24989809, 9241752, -13265253, 16086212, -28740881, -15642093},
-			FieldElement{-1409668, 12530728, -6368726, 10847387, 19531186, -14132160, -11709148, 7791794, -27245943, 4383347},
-		},
-	},
-	{
-		{
-			FieldElement{-28970898, 5271447, -1266009, -9736989, -12455236, 16732599, -4862407, -4906449, 27193557, 6245191},
-			FieldElement{-15193956, 5362278, -1783893, 2695834, 4960227, 12840725, 23061898, 3260492, 22510453, 8577507},
-			FieldElement{-12632451, 11257346, -32692994, 13548177, -721004, 10879011, 31168030, 13952092, -29571492, -3635906},
-		},
-		{
-			FieldElement{3877321, -9572739, 32416692, 5405324, -11004407, -13656635, 3759769, 11935320, 5611860, 8164018},
-			FieldElement{-16275802, 14667797, 15906460, 12155291, -22111149, -9039718, 32003002, -8832289, 5773085, -8422109},
-			FieldElement{-23788118, -8254300, 1950875, 8937633, 18686727, 16459170, -905725, 12376320, 31632953, 190926},
-		},
-		{
-			FieldElement{-24593607, -16138885, -8423991, 13378746, 14162407, 6901328, -8288749, 4508564, -25341555, -3627528},
-			FieldElement{8884438, -5884009, 6023974, 10104341, -6881569, -4941533, 18722941, -14786005, -1672488, 827625},
-			FieldElement{-32720583, -16289296, -32503547, 7101210, 13354605, 2659080, -1800575, -14108036, -24878478, 1541286},
-		},
-		{
-			FieldElement{2901347, -1117687, 3880376, -10059388, -17620940, -3612781, -21802117, -3567481, 20456845, -1885033},
-			FieldElement{27019610, 12299467, -13658288, -1603234, -12861660, -4861471, -19540150, -5016058, 29439641, 15138866},
-			FieldElement{21536104, -6626420, -32447818, -10690208, -22408077, 5175814, -5420040, -16361163, 7779328, 109896},
-		},
-		{
-			FieldElement{30279744, 14648750, -8044871, 6425558, 13639621, -743509, 28698390, 12180118, 23177719, -554075},
-			FieldElement{26572847, 3405927, -31701700, 12890905, -19265668, 5335866, -6493768, 2378492, 4439158, -13279347},
-			FieldElement{-22716706, 3489070, -9225266, -332753, 18875722, -1140095, 14819434, -12731527, -17717757, -5461437},
-		},
-		{
-			FieldElement{-5056483, 16566551, 15953661, 3767752, -10436499, 15627060, -820954, 2177225, 8550082, -15114165},
-			FieldElement{-18473302, 16596775, -381660, 15663611, 22860960, 15585581, -27844109, -3582739, -23260460, -8428588},
-			FieldElement{-32480551, 15707275, -8205912, -5652081, 29464558, 2713815, -22725137, 15860482, -21902570, 1494193},
-		},
-		{
-			FieldElement{-19562091, -14087393, -25583872, -9299552, 13127842, 759709, 21923482, 16529112, 8742704, 12967017},
-			FieldElement{-28464899, 1553205, 32536856, -10473729, -24691605, -406174, -8914625, -2933896, -29903758, 15553883},
-			FieldElement{21877909, 3230008, 9881174, 10539357, -4797115, 2841332, 11543572, 14513274, 19375923, -12647961},
-		},
-		{
-			FieldElement{8832269, -14495485, 13253511, 5137575, 5037871, 4078777, 24880818, -6222716, 2862653, 9455043},
-			FieldElement{29306751, 5123106, 20245049, -14149889, 9592566, 8447059, -2077124, -2990080, 15511449, 4789663},
-			FieldElement{-20679756, 7004547, 8824831, -9434977, -4045704, -3750736, -5754762, 108893, 23513200, 16652362},
-		},
-	},
-	{
-		{
-			FieldElement{-33256173, 4144782, -4476029, -6579123, 10770039, -7155542, -6650416, -12936300, -18319198, 10212860},
-			FieldElement{2756081, 8598110, 7383731, -6859892, 22312759, -1105012, 21179801, 2600940, -9988298, -12506466},
-			FieldElement{-24645692, 13317462, -30449259, -15653928, 21365574, -10869657, 11344424, 864440, -2499677, -16710063},
-		},
-		{
-			FieldElement{-26432803, 6148329, -17184412, -14474154, 18782929, -275997, -22561534, 211300, 2719757, 4940997},
-			FieldElement{-1323882, 3911313, -6948744, 14759765, -30027150, 7851207, 21690126, 8518463, 26699843, 5276295},
-			FieldElement{-13149873, -6429067, 9396249, 365013, 24703301, -10488939, 1321586, 149635, -15452774, 7159369},
-		},
-		{
-			FieldElement{9987780, -3404759, 17507962, 9505530, 9731535, -2165514, 22356009, 8312176, 22477218, -8403385},
-			FieldElement{18155857, -16504990, 19744716, 9006923, 15154154, -10538976, 24256460, -4864995, -22548173, 9334109},
-			FieldElement{2986088, -4911893, 10776628, -3473844, 10620590, -7083203, -21413845, 14253545, -22587149, 536906},
-		},
-		{
-			FieldElement{4377756, 8115836, 24567078, 15495314, 11625074, 13064599, 7390551, 10589625, 10838060, -15420424},
-			FieldElement{-19342404, 867880, 9277171, -3218459, -14431572, -1986443, 19295826, -15796950, 6378260, 699185},
-			FieldElement{7895026, 4057113, -7081772, -13077756, -17886831, -323126, -716039, 15693155, -5045064, -13373962},
-		},
-		{
-			FieldElement{-7737563, -5869402, -14566319, -7406919, 11385654, 13201616, 31730678, -10962840, -3918636, -9669325},
-			FieldElement{10188286, -15770834, -7336361, 13427543, 22223443, 14896287, 30743455, 7116568, -21786507, 5427593},
-			FieldElement{696102, 13206899, 27047647, -10632082, 15285305, -9853179, 10798490, -4578720, 19236243, 12477404},
-		},
-		{
-			FieldElement{-11229439, 11243796, -17054270, -8040865, -788228, -8167967, -3897669, 11180504, -23169516, 7733644},
-			FieldElement{17800790, -14036179, -27000429, -11766671, 23887827, 3149671, 23466177, -10538171, 10322027, 15313801},
-			FieldElement{26246234, 11968874, 32263343, -5468728, 6830755, -13323031, -15794704, -101982, -24449242, 10890804},
-		},
-		{
-			FieldElement{-31365647, 10271363, -12660625, -6267268, 16690207, -13062544, -14982212, 16484931, 25180797, -5334884},
-			FieldElement{-586574, 10376444, -32586414, -11286356, 19801893, 10997610, 2276632, 9482883, 316878, 13820577},
-			FieldElement{-9882808, -4510367, -2115506, 16457136, -11100081, 11674996, 30756178, -7515054, 30696930, -3712849},
-		},
-		{
-			FieldElement{32988917, -9603412, 12499366, 7910787, -10617257, -11931514, -7342816, -9985397, -32349517, 7392473},
-			FieldElement{-8855661, 15927861, 9866406, -3649411, -2396914, -16655781, -30409476, -9134995, 25112947, -2926644},
-			FieldElement{-2504044, -436966, 25621774, -5678772, 15085042, -5479877, -24884878, -13526194, 5537438, -13914319},
-		},
-	},
-	{
-		{
-			FieldElement{-11225584, 2320285, -9584280, 10149187, -33444663, 5808648, -14876251, -1729667, 31234590, 6090599},
-			FieldElement{-9633316, 116426, 26083934, 2897444, -6364437, -2688086, 609721, 15878753, -6970405, -9034768},
-			FieldElement{-27757857, 247744, -15194774, -9002551, 23288161, -10011936, -23869595, 6503646, 20650474, 1804084},
-		},
-		{
-			FieldElement{-27589786, 15456424, 8972517, 8469608, 15640622, 4439847, 3121995, -10329713, 27842616, -202328},
-			FieldElement{-15306973, 2839644, 22530074, 10026331, 4602058, 5048462, 28248656, 5031932, -11375082, 12714369},
-			FieldElement{20807691, -7270825, 29286141, 11421711, -27876523, -13868230, -21227475, 1035546, -19733229, 12796920},
-		},
-		{
-			FieldElement{12076899, -14301286, -8785001, -11848922, -25012791, 16400684, -17591495, -12899438, 3480665, -15182815},
-			FieldElement{-32361549, 5457597, 28548107, 7833186, 7303070, -11953545, -24363064, -15921875, -33374054, 2771025},
-			FieldElement{-21389266, 421932, 26597266, 6860826, 22486084, -6737172, -17137485, -4210226, -24552282, 15673397},
-		},
-		{
-			FieldElement{-20184622, 2338216, 19788685, -9620956, -4001265, -8740893, -20271184, 4733254, 3727144, -12934448},
-			FieldElement{6120119, 814863, -11794402, -622716, 6812205, -15747771, 2019594, 7975683, 31123697, -10958981},
-			FieldElement{30069250, -11435332, 30434654, 2958439, 18399564, -976289, 12296869, 9204260, -16432438, 9648165},
-		},
-		{
-			FieldElement{32705432, -1550977, 30705658, 7451065, -11805606, 9631813, 3305266, 5248604, -26008332, -11377501},
-			FieldElement{17219865, 2375039, -31570947, -5575615, -19459679, 9219903, 294711, 15298639, 2662509, -16297073},
-			FieldElement{-1172927, -7558695, -4366770, -4287744, -21346413, -8434326, 32087529, -1222777, 32247248, -14389861},
-		},
-		{
-			FieldElement{14312628, 1221556, 17395390, -8700143, -4945741, -8684635, -28197744, -9637817, -16027623, -13378845},
-			FieldElement{-1428825, -9678990, -9235681, 6549687, -7383069, -468664, 23046502, 9803137, 17597934, 2346211},
-			FieldElement{18510800, 15337574, 26171504, 981392, -22241552, 7827556, -23491134, -11323352, 3059833, -11782870},
-		},
-		{
-			FieldElement{10141598, 6082907, 17829293, -1947643, 9830092, 13613136, -25556636, -5544586, -33502212, 3592096},
-			FieldElement{33114168, -15889352, -26525686, -13343397, 33076705, 8716171, 1151462, 1521897, -982665, -6837803},
-			FieldElement{-32939165, -4255815, 23947181, -324178, -33072974, -12305637, -16637686, 3891704, 26353178, 693168},
-		},
-		{
-			FieldElement{30374239, 1595580, -16884039, 13186931, 4600344, 406904, 9585294, -400668, 31375464, 14369965},
-			FieldElement{-14370654, -7772529, 1510301, 6434173, -18784789, -6262728, 32732230, -13108839, 17901441, 16011505},
-			FieldElement{18171223, -11934626, -12500402, 15197122, -11038147, -15230035, -19172240, -16046376, 8764035, 12309598},
-		},
-	},
-	{
-		{
-			FieldElement{5975908, -5243188, -19459362, -9681747, -11541277, 14015782, -23665757, 1228319, 17544096, -10593782},
-			FieldElement{5811932, -1715293, 3442887, -2269310, -18367348, -8359541, -18044043, -15410127, -5565381, 12348900},
-			FieldElement{-31399660, 11407555, 25755363, 6891399, -3256938, 14872274, -24849353, 8141295, -10632534, -585479},
-		},
-		{
-			FieldElement{-12675304, 694026, -5076145, 13300344, 14015258, -14451394, -9698672, -11329050, 30944593, 1130208},
-			FieldElement{8247766, -6710942, -26562381, -7709309, -14401939, -14648910, 4652152, 2488540, 23550156, -271232},
-			FieldElement{17294316, -3788438, 7026748, 15626851, 22990044, 113481, 2267737, -5908146, -408818, -137719},
-		},
-		{
-			FieldElement{16091085, -16253926, 18599252, 7340678, 2137637, -1221657, -3364161, 14550936, 3260525, -7166271},
-			FieldElement{-4910104, -13332887, 18550887, 10864893, -16459325, -7291596, -23028869, -13204905, -12748722, 2701326},
-			FieldElement{-8574695, 16099415, 4629974, -16340524, -20786213, -6005432, -10018363, 9276971, 11329923, 1862132},
-		},
-		{
-			FieldElement{14763076, -15903608, -30918270, 3689867, 3511892, 10313526, -21951088, 12219231, -9037963, -940300},
-			FieldElement{8894987, -3446094, 6150753, 3013931, 301220, 15693451, -31981216, -2909717, -15438168, 11595570},
-			FieldElement{15214962, 3537601, -26238722, -14058872, 4418657, -15230761, 13947276, 10730794, -13489462, -4363670},
-		},
-		{
-			FieldElement{-2538306, 7682793, 32759013, 263109, -29984731, -7955452, -22332124, -10188635, 977108, 699994},
-			FieldElement{-12466472, 4195084, -9211532, 550904, -15565337, 12917920, 19118110, -439841, -30534533, -14337913},
-			FieldElement{31788461, -14507657, 4799989, 7372237, 8808585, -14747943, 9408237, -10051775, 12493932, -5409317},
-		},
-		{
-			FieldElement{-25680606, 5260744, -19235809, -6284470, -3695942, 16566087, 27218280, 2607121, 29375955, 6024730},
-			FieldElement{842132, -2794693, -4763381, -8722815, 26332018, -12405641, 11831880, 6985184, -9940361, 2854096},
-			FieldElement{-4847262, -7969331, 2516242, -5847713, 9695691, -7221186, 16512645, 960770, 12121869, 16648078},
-		},
-		{
-			FieldElement{-15218652, 14667096, -13336229, 2013717, 30598287, -464137, -31504922, -7882064, 20237806, 2838411},
-			FieldElement{-19288047, 4453152, 15298546, -16178388, 22115043, -15972604, 12544294, -13470457, 1068881, -12499905},
-			FieldElement{-9558883, -16518835, 33238498, 13506958, 30505848, -1114596, -8486907, -2630053, 12521378, 4845654},
-		},
-		{
-			FieldElement{-28198521, 10744108, -2958380, 10199664, 7759311, -13088600, 3409348, -873400, -6482306, -12885870},
-			FieldElement{-23561822, 6230156, -20382013, 10655314, -24040585, -11621172, 10477734, -1240216, -3113227, 13974498},
-			FieldElement{12966261, 15550616, -32038948, -1615346, 21025980, -629444, 5642325, 7188737, 18895762, 12629579},
-		},
-	},
-	{
-		{
-			FieldElement{14741879, -14946887, 22177208, -11721237, 1279741, 8058600, 11758140, 789443, 32195181, 3895677},
-			FieldElement{10758205, 15755439, -4509950, 9243698, -4879422, 6879879, -2204575, -3566119, -8982069, 4429647},
-			FieldElement{-2453894, 15725973, -20436342, -10410672, -5803908, -11040220, -7135870, -11642895, 18047436, -15281743},
-		},
-		{
-			FieldElement{-25173001, -11307165, 29759956, 11776784, -22262383, -15820455, 10993114, -12850837, -17620701, -9408468},
-			FieldElement{21987233, 700364, -24505048, 14972008, -7774265, -5718395, 32155026, 2581431, -29958985, 8773375},
-			FieldElement{-25568350, 454463, -13211935, 16126715, 25240068, 8594567, 20656846, 12017935, -7874389, -13920155},
-		},
-		{
-			FieldElement{6028182, 6263078, -31011806, -11301710, -818919, 2461772, -31841174, -5468042, -1721788, -2776725},
-			FieldElement{-12278994, 16624277, 987579, -5922598, 32908203, 1248608, 7719845, -4166698, 28408820, 6816612},
-			FieldElement{-10358094, -8237829, 19549651, -12169222, 22082623, 16147817, 20613181, 13982702, -10339570, 5067943},
-		},
-		{
-			FieldElement{-30505967, -3821767, 12074681, 13582412, -19877972, 2443951, -19719286, 12746132, 5331210, -10105944},
-			FieldElement{30528811, 3601899, -1957090, 4619785, -27361822, -15436388, 24180793, -12570394, 27679908, -1648928},
-			FieldElement{9402404, -13957065, 32834043, 10838634, -26580150, -13237195, 26653274, -8685565, 22611444, -12715406},
-		},
-		{
-			FieldElement{22190590, 1118029, 22736441, 15130463, -30460692, -5991321, 19189625, -4648942, 4854859, 6622139},
-			FieldElement{-8310738, -2953450, -8262579, -3388049, -10401731, -271929, 13424426, -3567227, 26404409, 13001963},
-			FieldElement{-31241838, -15415700, -2994250, 8939346, 11562230, -12840670, -26064365, -11621720, -15405155, 11020693},
-		},
-		{
-			FieldElement{1866042, -7949489, -7898649, -10301010, 12483315, 13477547, 3175636, -12424163, 28761762, 1406734},
-			FieldElement{-448555, -1777666, 13018551, 3194501, -9580420, -11161737, 24760585, -4347088, 25577411, -13378680},
-			FieldElement{-24290378, 4759345, -690653, -1852816, 2066747, 10693769, -29595790, 9884936, -9368926, 4745410},
-		},
-		{
-			FieldElement{-9141284, 6049714, -19531061, -4341411, -31260798, 9944276, -15462008, -11311852, 10931924, -11931931},
-			FieldElement{-16561513, 14112680, -8012645, 4817318, -8040464, -11414606, -22853429, 10856641, -20470770, 13434654},
-			FieldElement{22759489, -10073434, -16766264, -1871422, 13637442, -10168091, 1765144, -12654326, 28445307, -5364710},
-		},
-		{
-			FieldElement{29875063, 12493613, 2795536, -3786330, 1710620, 15181182, -10195717, -8788675, 9074234, 1167180},
-			FieldElement{-26205683, 11014233, -9842651, -2635485, -26908120, 7532294, -18716888, -9535498, 3843903, 9367684},
-			FieldElement{-10969595, -6403711, 9591134, 9582310, 11349256, 108879, 16235123, 8601684, -139197, 4242895},
-		},
-	},
-	{
-		{
-			FieldElement{22092954, -13191123, -2042793, -11968512, 32186753, -11517388, -6574341, 2470660, -27417366, 16625501},
-			FieldElement{-11057722, 3042016, 13770083, -9257922, 584236, -544855, -7770857, 2602725, -27351616, 14247413},
-			FieldElement{6314175, -10264892, -32772502, 15957557, -10157730, 168750, -8618807, 14290061, 27108877, -1180880},
-		},
-		{
-			FieldElement{-8586597, -7170966, 13241782, 10960156, -32991015, -13794596, 33547976, -11058889, -27148451, 981874},
-			FieldElement{22833440, 9293594, -32649448, -13618667, -9136966, 14756819, -22928859, -13970780, -10479804, -16197962},
-			FieldElement{-7768587, 3326786, -28111797, 10783824, 19178761, 14905060, 22680049, 13906969, -15933690, 3797899},
-		},
-		{
-			FieldElement{21721356, -4212746, -12206123, 9310182, -3882239, -13653110, 23740224, -2709232, 20491983, -8042152},
-			FieldElement{9209270, -15135055, -13256557, -6167798, -731016, 15289673, 25947805, 15286587, 30997318, -6703063},
-			FieldElement{7392032, 16618386, 23946583, -8039892, -13265164, -1533858, -14197445, -2321576, 17649998, -250080},
-		},
-		{
-			FieldElement{-9301088, -14193827, 30609526, -3049543, -25175069, -1283752, -15241566, -9525724, -2233253, 7662146},
-			FieldElement{-17558673, 1763594, -33114336, 15908610, -30040870, -12174295, 7335080, -8472199, -3174674, 3440183},
-			FieldElement{-19889700, -5977008, -24111293, -9688870, 10799743, -16571957, 40450, -4431835, 4862400, 1133},
-		},
-		{
-			FieldElement{-32856209, -7873957, -5422389, 14860950, -16319031, 7956142, 7258061, 311861, -30594991, -7379421},
-			FieldElement{-3773428, -1565936, 28985340, 7499440, 24445838, 9325937, 29727763, 16527196, 18278453, 15405622},
-			FieldElement{-4381906, 8508652, -19898366, -3674424, -5984453, 15149970, -13313598, 843523, -21875062, 13626197},
-		},
-		{
-			FieldElement{2281448, -13487055, -10915418, -2609910, 1879358, 16164207, -10783882, 3953792, 13340839, 15928663},
-			FieldElement{31727126, -7179855, -18437503, -8283652, 2875793, -16390330, -25269894, -7014826, -23452306, 5964753},
-			FieldElement{4100420, -5959452, -17179337, 6017714, -18705837, 12227141, -26684835, 11344144, 2538215, -7570755},
-		},
-		{
-			FieldElement{-9433605, 6123113, 11159803, -2156608, 30016280, 14966241, -20474983, 1485421, -629256, -15958862},
-			FieldElement{-26804558, 4260919, 11851389, 9658551, -32017107, 16367492, -20205425, -13191288, 11659922, -11115118},
-			FieldElement{26180396, 10015009, -30844224, -8581293, 5418197, 9480663, 2231568, -10170080, 33100372, -1306171},
-		},
-		{
-			FieldElement{15121113, -5201871, -10389905, 15427821, -27509937, -15992507, 21670947, 4486675, -5931810, -14466380},
-			FieldElement{16166486, -9483733, -11104130, 6023908, -31926798, -1364923, 2340060, -16254968, -10735770, -10039824},
-			FieldElement{28042865, -3557089, -12126526, 12259706, -3717498, -6945899, 6766453, -8689599, 18036436, 5803270},
-		},
-	},
-	{
-		{
-			FieldElement{-817581, 6763912, 11803561, 1585585, 10958447, -2671165, 23855391, 4598332, -6159431, -14117438},
-			FieldElement{-31031306, -14256194, 17332029, -2383520, 31312682, -5967183, 696309, 50292, -20095739, 11763584},
-			FieldElement{-594563, -2514283, -32234153, 12643980, 12650761, 14811489, 665117, -12613632, -19773211, -10713562},
-		},
-		{
-			FieldElement{30464590, -11262872, -4127476, -12734478, 19835327, -7105613, -24396175, 2075773, -17020157, 992471},
-			FieldElement{18357185, -6994433, 7766382, 16342475, -29324918, 411174, 14578841, 8080033, -11574335, -10601610},
-			FieldElement{19598397, 10334610, 12555054, 2555664, 18821899, -10339780, 21873263, 16014234, 26224780, 16452269},
-		},
-		{
-			FieldElement{-30223925, 5145196, 5944548, 16385966, 3976735, 2009897, -11377804, -7618186, -20533829, 3698650},
-			FieldElement{14187449, 3448569, -10636236, -10810935, -22663880, -3433596, 7268410, -10890444, 27394301, 12015369},
-			FieldElement{19695761, 16087646, 28032085, 12999827, 6817792, 11427614, 20244189, -1312777, -13259127, -3402461},
-		},
-		{
-			FieldElement{30860103, 12735208, -1888245, -4699734, -16974906, 2256940, -8166013, 12298312, -8550524, -10393462},
-			FieldElement{-5719826, -11245325, -1910649, 15569035, 26642876, -7587760, -5789354, -15118654, -4976164, 12651793},
-			FieldElement{-2848395, 9953421, 11531313, -5282879, 26895123, -12697089, -13118820, -16517902, 9768698, -2533218},
-		},
-		{
-			FieldElement{-24719459, 1894651, -287698, -4704085, 15348719, -8156530, 32767513, 12765450, 4940095, 10678226},
-			FieldElement{18860224, 15980149, -18987240, -1562570, -26233012, -11071856, -7843882, 13944024, -24372348, 16582019},
-			FieldElement{-15504260, 4970268, -29893044, 4175593, -20993212, -2199756, -11704054, 15444560, -11003761, 7989037},
-		},
-		{
-			FieldElement{31490452, 5568061, -2412803, 2182383, -32336847, 4531686, -32078269, 6200206, -19686113, -14800171},
-			FieldElement{-17308668, -15879940, -31522777, -2831, -32887382, 16375549, 8680158, -16371713, 28550068, -6857132},
-			FieldElement{-28126887, -5688091, 16837845, -1820458, -6850681, 12700016, -30039981, 4364038, 1155602, 5988841},
-		},
-		{
-			FieldElement{21890435, -13272907, -12624011, 12154349, -7831873, 15300496, 23148983, -4470481, 24618407, 8283181},
-			FieldElement{-33136107, -10512751, 9975416, 6841041, -31559793, 16356536, 3070187, -7025928, 1466169, 10740210},
-			FieldElement{-1509399, -15488185, -13503385, -10655916, 32799044, 909394, -13938903, -5779719, -32164649, -15327040},
-		},
-		{
-			FieldElement{3960823, -14267803, -28026090, -15918051, -19404858, 13146868, 15567327, 951507, -3260321, -573935},
-			FieldElement{24740841, 5052253, -30094131, 8961361, 25877428, 6165135, -24368180, 14397372, -7380369, -6144105},
-			FieldElement{-28888365, 3510803, -28103278, -1158478, -11238128, -10631454, -15441463, -14453128, -1625486, -6494814},
-		},
-	},
-	{
-		{
-			FieldElement{793299, -9230478, 8836302, -6235707, -27360908, -2369593, 33152843, -4885251, -9906200, -621852},
-			FieldElement{5666233, 525582, 20782575, -8038419, -24538499, 14657740, 16099374, 1468826, -6171428, -15186581},
-			FieldElement{-4859255, -3779343, -2917758, -6748019, 7778750, 11688288, -30404353, -9871238, -1558923, -9863646},
-		},
-		{
-			FieldElement{10896332, -7719704, 824275, 472601, -19460308, 3009587, 25248958, 14783338, -30581476, -15757844},
-			FieldElement{10566929, 12612572, -31944212, 11118703, -12633376, 12362879, 21752402, 8822496, 24003793, 14264025},
-			FieldElement{27713862, -7355973, -11008240, 9227530, 27050101, 2504721, 23886875, -13117525, 13958495, -5732453},
-		},
-		{
-			FieldElement{-23481610, 4867226, -27247128, 3900521, 29838369, -8212291, -31889399, -10041781, 7340521, -15410068},
-			FieldElement{4646514, -8011124, -22766023, -11532654, 23184553, 8566613, 31366726, -1381061, -15066784, -10375192},
-			FieldElement{-17270517, 12723032, -16993061, 14878794, 21619651, -6197576, 27584817, 3093888, -8843694, 3849921},
-		},
-		{
-			FieldElement{-9064912, 2103172, 25561640, -15125738, -5239824, 9582958, 32477045, -9017955, 5002294, -15550259},
-			FieldElement{-12057553, -11177906, 21115585, -13365155, 8808712, -12030708, 16489530, 13378448, -25845716, 12741426},
-			FieldElement{-5946367, 10645103, -30911586, 15390284, -3286982, -7118677, 24306472, 15852464, 28834118, -7646072},
-		},
-		{
-			FieldElement{-17335748, -9107057, -24531279, 9434953, -8472084, -583362, -13090771, 455841, 20461858, 5491305},
-			FieldElement{13669248, -16095482, -12481974, -10203039, -14569770, -11893198, -24995986, 11293807, -28588204, -9421832},
-			FieldElement{28497928, 6272777, -33022994, 14470570, 8906179, -1225630, 18504674, -14165166, 29867745, -8795943},
-		},
-		{
-			FieldElement{-16207023, 13517196, -27799630, -13697798, 24009064, -6373891, -6367600, -13175392, 22853429, -4012011},
-			FieldElement{24191378, 16712145, -13931797, 15217831, 14542237, 1646131, 18603514, -11037887, 12876623, -2112447},
-			FieldElement{17902668, 4518229, -411702, -2829247, 26878217, 5258055, -12860753, 608397, 16031844, 3723494},
-		},
-		{
-			FieldElement{-28632773, 12763728, -20446446, 7577504, 33001348, -13017745, 17558842, -7872890, 23896954, -4314245},
-			FieldElement{-20005381, -12011952, 31520464, 605201, 2543521, 5991821, -2945064, 7229064, -9919646, -8826859},
-			FieldElement{28816045, 298879, -28165016, -15920938, 19000928, -1665890, -12680833, -2949325, -18051778, -2082915},
-		},
-		{
-			FieldElement{16000882, -344896, 3493092, -11447198, -29504595, -13159789, 12577740, 16041268, -19715240, 7847707},
-			FieldElement{10151868, 10572098, 27312476, 7922682, 14825339, 4723128, -32855931, -6519018, -10020567, 3852848},
-			FieldElement{-11430470, 15697596, -21121557, -4420647, 5386314, 15063598, 16514493, -15932110, 29330899, -15076224},
-		},
-	},
-	{
-		{
-			FieldElement{-25499735, -4378794, -15222908, -6901211, 16615731, 2051784, 3303702, 15490, -27548796, 12314391},
-			FieldElement{15683520, -6003043, 18109120, -9980648, 15337968, -5997823, -16717435, 15921866, 16103996, -3731215},
-			FieldElement{-23169824, -10781249, 13588192, -1628807, -3798557, -1074929, -19273607, 5402699, -29815713, -9841101},
-		},
-		{
-			FieldElement{23190676, 2384583, -32714340, 3462154, -29903655, -1529132, -11266856, 8911517, -25205859, 2739713},
-			FieldElement{21374101, -3554250, -33524649, 9874411, 15377179, 11831242, -33529904, 6134907, 4931255, 11987849},
-			FieldElement{-7732, -2978858, -16223486, 7277597, 105524, -322051, -31480539, 13861388, -30076310, 10117930},
-		},
-		{
-			FieldElement{-29501170, -10744872, -26163768, 13051539, -25625564, 5089643, -6325503, 6704079, 12890019, 15728940},
-			FieldElement{-21972360, -11771379, -951059, -4418840, 14704840, 2695116, 903376, -10428139, 12885167, 8311031},
-			FieldElement{-17516482, 5352194, 10384213, -13811658, 7506451, 13453191, 26423267, 4384730, 1888765, -5435404},
-		},
-		{
-			FieldElement{-25817338, -3107312, -13494599, -3182506, 30896459, -13921729, -32251644, -12707869, -19464434, -3340243},
-			FieldElement{-23607977, -2665774, -526091, 4651136, 5765089, 4618330, 6092245, 14845197, 17151279, -9854116},
-			FieldElement{-24830458, -12733720, -15165978, 10367250, -29530908, -265356, 22825805, -7087279, -16866484, 16176525},
-		},
-		{
-			FieldElement{-23583256, 6564961, 20063689, 3798228, -4740178, 7359225, 2006182, -10363426, -28746253, -10197509},
-			FieldElement{-10626600, -4486402, -13320562, -5125317, 3432136, -6393229, 23632037, -1940610, 32808310, 1099883},
-			FieldElement{15030977, 5768825, -27451236, -2887299, -6427378, -15361371, -15277896, -6809350, 2051441, -15225865},
-		},
-		{
-			FieldElement{-3362323, -7239372, 7517890, 9824992, 23555850, 295369, 5148398, -14154188, -22686354, 16633660},
-			FieldElement{4577086, -16752288, 13249841, -15304328, 19958763, -14537274, 18559670, -10759549, 8402478, -9864273},
-			FieldElement{-28406330, -1051581, -26790155, -907698, -17212414, -11030789, 9453451, -14980072, 17983010, 9967138},
-		},
-		{
-			FieldElement{-25762494, 6524722, 26585488, 9969270, 24709298, 1220360, -1677990, 7806337, 17507396, 3651560},
-			FieldElement{-10420457, -4118111, 14584639, 15971087, -15768321, 8861010, 26556809, -5574557, -18553322, -11357135},
-			FieldElement{2839101, 14284142, 4029895, 3472686, 14402957, 12689363, -26642121, 8459447, -5605463, -7621941},
-		},
-		{
-			FieldElement{-4839289, -3535444, 9744961, 2871048, 25113978, 3187018, -25110813, -849066, 17258084, -7977739},
-			FieldElement{18164541, -10595176, -17154882, -1542417, 19237078, -9745295, 23357533, -15217008, 26908270, 12150756},
-			FieldElement{-30264870, -7647865, 5112249, -7036672, -1499807, -6974257, 43168, -5537701, -32302074, 16215819},
-		},
-	},
-	{
-		{
-			FieldElement{-6898905, 9824394, -12304779, -4401089, -31397141, -6276835, 32574489, 12532905, -7503072, -8675347},
-			FieldElement{-27343522, -16515468, -27151524, -10722951, 946346, 16291093, 254968, 7168080, 21676107, -1943028},
-			FieldElement{21260961, -8424752, -16831886, -11920822, -23677961, 3968121, -3651949, -6215466, -3556191, -7913075},
-		},
-		{
-			FieldElement{16544754, 13250366, -16804428, 15546242, -4583003, 12757258, -2462308, -8680336, -18907032, -9662799},
-			FieldElement{-2415239, -15577728, 18312303, 4964443, -15272530, -12653564, 26820651, 16690659, 25459437, -4564609},
-			FieldElement{-25144690, 11425020, 28423002, -11020557, -6144921, -15826224, 9142795, -2391602, -6432418, -1644817},
-		},
-		{
-			FieldElement{-23104652, 6253476, 16964147, -3768872, -25113972, -12296437, -27457225, -16344658, 6335692, 7249989},
-			FieldElement{-30333227, 13979675, 7503222, -12368314, -11956721, -4621693, -30272269, 2682242, 25993170, -12478523},
-			FieldElement{4364628, 5930691, 32304656, -10044554, -8054781, 15091131, 22857016, -10598955, 31820368, 15075278},
-		},
-		{
-			FieldElement{31879134, -8918693, 17258761, 90626, -8041836, -4917709, 24162788, -9650886, -17970238, 12833045},
-			FieldElement{19073683, 14851414, -24403169, -11860168, 7625278, 11091125, -19619190, 2074449, -9413939, 14905377},
-			FieldElement{24483667, -11935567, -2518866, -11547418, -1553130, 15355506, -25282080, 9253129, 27628530, -7555480},
-		},
-		{
-			FieldElement{17597607, 8340603, 19355617, 552187, 26198470, -3176583, 4593324, -9157582, -14110875, 15297016},
-			FieldElement{510886, 14337390, -31785257, 16638632, 6328095, 2713355, -20217417, -11864220, 8683221, 2921426},
-			FieldElement{18606791, 11874196, 27155355, -5281482, -24031742, 6265446, -25178240, -1278924, 4674690, 13890525},
-		},
-		{
-			FieldElement{13609624, 13069022, -27372361, -13055908, 24360586, 9592974, 14977157, 9835105, 4389687, 288396},
-			FieldElement{9922506, -519394, 13613107, 5883594, -18758345, -434263, -12304062, 8317628, 23388070, 16052080},
-			FieldElement{12720016, 11937594, -31970060, -5028689, 26900120, 8561328, -20155687, -11632979, -14754271, -10812892},
-		},
-		{
-			FieldElement{15961858, 14150409, 26716931, -665832, -22794328, 13603569, 11829573, 7467844, -28822128, 929275},
-			FieldElement{11038231, -11582396, -27310482, -7316562, -10498527, -16307831, -23479533, -9371869, -21393143, 2465074},
-			FieldElement{20017163, -4323226, 27915242, 1529148, 12396362, 15675764, 13817261, -9658066, 2463391, -4622140},
-		},
-		{
-			FieldElement{-16358878, -12663911, -12065183, 4996454, -1256422, 1073572, 9583558, 12851107, 4003896, 12673717},
-			FieldElement{-1731589, -15155870, -3262930, 16143082, 19294135, 13385325, 14741514, -9103726, 7903886, 2348101},
-			FieldElement{24536016, -16515207, 12715592, -3862155, 1511293, 10047386, -3842346, -7129159, -28377538, 10048127},
-		},
-	},
-	{
-		{
-			FieldElement{-12622226, -6204820, 30718825, 2591312, -10617028, 12192840, 18873298, -7297090, -32297756, 15221632},
-			FieldElement{-26478122, -11103864, 11546244, -1852483, 9180880, 7656409, -21343950, 2095755, 29769758, 6593415},
-			FieldElement{-31994208, -2907461, 4176912, 3264766, 12538965, -868111, 26312345, -6118678, 30958054, 8292160},
-		},
-		{
-			FieldElement{31429822, -13959116, 29173532, 15632448, 12174511, -2760094, 32808831, 3977186, 26143136, -3148876},
-			FieldElement{22648901, 1402143, -22799984, 13746059, 7936347, 365344, -8668633, -1674433, -3758243, -2304625},
-			FieldElement{-15491917, 8012313, -2514730, -12702462, -23965846, -10254029, -1612713, -1535569, -16664475, 8194478},
-		},
-		{
-			FieldElement{27338066, -7507420, -7414224, 10140405, -19026427, -6589889, 27277191, 8855376, 28572286, 3005164},
-			FieldElement{26287124, 4821776, 25476601, -4145903, -3764513, -15788984, -18008582, 1182479, -26094821, -13079595},
-			FieldElement{-7171154, 3178080, 23970071, 6201893, -17195577, -4489192, -21876275, -13982627, 32208683, -1198248},
-		},
-		{
-			FieldElement{-16657702, 2817643, -10286362, 14811298, 6024667, 13349505, -27315504, -10497842, -27672585, -11539858},
-			FieldElement{15941029, -9405932, -21367050, 8062055, 31876073, -238629, -15278393, -1444429, 15397331, -4130193},
-			FieldElement{8934485, -13485467, -23286397, -13423241, -32446090, 14047986, 31170398, -1441021, -27505566, 15087184},
-		},
-		{
-			FieldElement{-18357243, -2156491, 24524913, -16677868, 15520427, -6360776, -15502406, 11461896, 16788528, -5868942},
-			FieldElement{-1947386, 16013773, 21750665, 3714552, -17401782, -16055433, -3770287, -10323320, 31322514, -11615635},
-			FieldElement{21426655, -5650218, -13648287, -5347537, -28812189, -4920970, -18275391, -14621414, 13040862, -12112948},
-		},
-		{
-			FieldElement{11293895, 12478086, -27136401, 15083750, -29307421, 14748872, 14555558, -13417103, 1613711, 4896935},
-			FieldElement{-25894883, 15323294, -8489791, -8057900, 25967126, -13425460, 2825960, -4897045, -23971776, -11267415},
-			FieldElement{-15924766, -5229880, -17443532, 6410664, 3622847, 10243618, 20615400, 12405433, -23753030, -8436416},
-		},
-		{
-			FieldElement{-7091295, 12556208, -20191352, 9025187, -17072479, 4333801, 4378436, 2432030, 23097949, -566018},
-			FieldElement{4565804, -16025654, 20084412, -7842817, 1724999, 189254, 24767264, 10103221, -18512313, 2424778},
-			FieldElement{366633, -11976806, 8173090, -6890119, 30788634, 5745705, -7168678, 1344109, -3642553, 12412659},
-		},
-		{
-			FieldElement{-24001791, 7690286, 14929416, -168257, -32210835, -13412986, 24162697, -15326504, -3141501, 11179385},
-			FieldElement{18289522, -14724954, 8056945, 16430056, -21729724, 7842514, -6001441, -1486897, -18684645, -11443503},
-			FieldElement{476239, 6601091, -6152790, -9723375, 17503545, -4863900, 27672959, 13403813, 11052904, 5219329},
-		},
-	},
-	{
-		{
-			FieldElement{20678546, -8375738, -32671898, 8849123, -5009758, 14574752, 31186971, -3973730, 9014762, -8579056},
-			FieldElement{-13644050, -10350239, -15962508, 5075808, -1514661, -11534600, -33102500, 9160280, 8473550, -3256838},
-			FieldElement{24900749, 14435722, 17209120, -15292541, -22592275, 9878983, -7689309, -16335821, -24568481, 11788948},
-		},
-		{
-			FieldElement{-3118155, -11395194, -13802089, 14797441, 9652448, -6845904, -20037437, 10410733, -24568470, -1458691},
-			FieldElement{-15659161, 16736706, -22467150, 10215878, -9097177, 7563911, 11871841, -12505194, -18513325, 8464118},
-			FieldElement{-23400612, 8348507, -14585951, -861714, -3950205, -6373419, 14325289, 8628612, 33313881, -8370517},
-		},
-		{
-			FieldElement{-20186973, -4967935, 22367356, 5271547, -1097117, -4788838, -24805667, -10236854, -8940735, -5818269},
-			FieldElement{-6948785, -1795212, -32625683, -16021179, 32635414, -7374245, 15989197, -12838188, 28358192, -4253904},
-			FieldElement{-23561781, -2799059, -32351682, -1661963, -9147719, 10429267, -16637684, 4072016, -5351664, 5596589},
-		},
-		{
-			FieldElement{-28236598, -3390048, 12312896, 6213178, 3117142, 16078565, 29266239, 2557221, 1768301, 15373193},
-			FieldElement{-7243358, -3246960, -4593467, -7553353, -127927, -912245, -1090902, -4504991, -24660491, 3442910},
-			FieldElement{-30210571, 5124043, 14181784, 8197961, 18964734, -11939093, 22597931, 7176455, -18585478, 13365930},
-		},
-		{
-			FieldElement{-7877390, -1499958, 8324673, 4690079, 6261860, 890446, 24538107, -8570186, -9689599, -3031667},
-			FieldElement{25008904, -10771599, -4305031, -9638010, 16265036, 15721635, 683793, -11823784, 15723479, -15163481},
-			FieldElement{-9660625, 12374379, -27006999, -7026148, -7724114, -12314514, 11879682, 5400171, 519526, -1235876},
-		},
-		{
-			FieldElement{22258397, -16332233, -7869817, 14613016, -22520255, -2950923, -20353881, 7315967, 16648397, 7605640},
-			FieldElement{-8081308, -8464597, -8223311, 9719710, 19259459, -15348212, 23994942, -5281555, -9468848, 4763278},
-			FieldElement{-21699244, 9220969, -15730624, 1084137, -25476107, -2852390, 31088447, -7764523, -11356529, 728112},
-		},
-		{
-			FieldElement{26047220, -11751471, -6900323, -16521798, 24092068, 9158119, -4273545, -12555558, -29365436, -5498272},
-			FieldElement{17510331, -322857, 5854289, 8403524, 17133918, -3112612, -28111007, 12327945, 10750447, 10014012},
-			FieldElement{-10312768, 3936952, 9156313, -8897683, 16498692, -994647, -27481051, -666732, 3424691, 7540221},
-		},
-		{
-			FieldElement{30322361, -6964110, 11361005, -4143317, 7433304, 4989748, -7071422, -16317219, -9244265, 15258046},
-			FieldElement{13054562, -2779497, 19155474, 469045, -12482797, 4566042, 5631406, 2711395, 1062915, -5136345},
-			FieldElement{-19240248, -11254599, -29509029, -7499965, -5835763, 13005411, -6066489, 12194497, 32960380, 1459310},
-		},
-	},
-	{
-		{
-			FieldElement{19852034, 7027924, 23669353, 10020366, 8586503, -6657907, 394197, -6101885, 18638003, -11174937},
-			FieldElement{31395534, 15098109, 26581030, 8030562, -16527914, -5007134, 9012486, -7584354, -6643087, -5442636},
-			FieldElement{-9192165, -2347377, -1997099, 4529534, 25766844, 607986, -13222, 9677543, -32294889, -6456008},
-		},
-		{
-			FieldElement{-2444496, -149937, 29348902, 8186665, 1873760, 12489863, -30934579, -7839692, -7852844, -8138429},
-			FieldElement{-15236356, -15433509, 7766470, 746860, 26346930, -10221762, -27333451, 10754588, -9431476, 5203576},
-			FieldElement{31834314, 14135496, -770007, 5159118, 20917671, -16768096, -7467973, -7337524, 31809243, 7347066},
-		},
-		{
-			FieldElement{-9606723, -11874240, 20414459, 13033986, 13716524, -11691881, 19797970, -12211255, 15192876, -2087490},
-			FieldElement{-12663563, -2181719, 1168162, -3804809, 26747877, -14138091, 10609330, 12694420, 33473243, -13382104},
-			FieldElement{33184999, 11180355, 15832085, -11385430, -1633671, 225884, 15089336, -11023903, -6135662, 14480053},
-		},
-		{
-			FieldElement{31308717, -5619998, 31030840, -1897099, 15674547, -6582883, 5496208, 13685227, 27595050, 8737275},
-			FieldElement{-20318852, -15150239, 10933843, -16178022, 8335352, -7546022, -31008351, -12610604, 26498114, 66511},
-			FieldElement{22644454, -8761729, -16671776, 4884562, -3105614, -13559366, 30540766, -4286747, -13327787, -7515095},
-		},
-		{
-			FieldElement{-28017847, 9834845, 18617207, -2681312, -3401956, -13307506, 8205540, 13585437, -17127465, 15115439},
-			FieldElement{23711543, -672915, 31206561, -8362711, 6164647, -9709987, -33535882, -1426096, 8236921, 16492939},
-			FieldElement{-23910559, -13515526, -26299483, -4503841, 25005590, -7687270, 19574902, 10071562, 6708380, -6222424},
-		},
-		{
-			FieldElement{2101391, -4930054, 19702731, 2367575, -15427167, 1047675, 5301017, 9328700, 29955601, -11678310},
-			FieldElement{3096359, 9271816, -21620864, -15521844, -14847996, -7592937, -25892142, -12635595, -9917575, 6216608},
-			FieldElement{-32615849, 338663, -25195611, 2510422, -29213566, -13820213, 24822830, -6146567, -26767480, 7525079},
-		},
-		{
-			FieldElement{-23066649, -13985623, 16133487, -7896178, -3389565, 778788, -910336, -2782495, -19386633, 11994101},
-			FieldElement{21691500, -13624626, -641331, -14367021, 3285881, -3483596, -25064666, 9718258, -7477437, 13381418},
-			FieldElement{18445390, -4202236, 14979846, 11622458, -1727110, -3582980, 23111648, -6375247, 28535282, 15779576},
-		},
-		{
-			FieldElement{30098053, 3089662, -9234387, 16662135, -21306940, 11308411, -14068454, 12021730, 9955285, -16303356},
-			FieldElement{9734894, -14576830, -7473633, -9138735, 2060392, 11313496, -18426029, 9924399, 20194861, 13380996},
-			FieldElement{-26378102, -7965207, -22167821, 15789297, -18055342, -6168792, -1984914, 15707771, 26342023, 10146099},
-		},
-	},
-	{
-		{
-			FieldElement{-26016874, -219943, 21339191, -41388, 19745256, -2878700, -29637280, 2227040, 21612326, -545728},
-			FieldElement{-13077387, 1184228, 23562814, -5970442, -20351244, -6348714, 25764461, 12243797, -20856566, 11649658},
-			FieldElement{-10031494, 11262626, 27384172, 2271902, 26947504, -15997771, 39944, 6114064, 33514190, 2333242},
-		},
-		{
-			FieldElement{-21433588, -12421821, 8119782, 7219913, -21830522, -9016134, -6679750, -12670638, 24350578, -13450001},
-			FieldElement{-4116307, -11271533, -23886186, 4843615, -30088339, 690623, -31536088, -10406836, 8317860, 12352766},
-			FieldElement{18200138, -14475911, -33087759, -2696619, -23702521, -9102511, -23552096, -2287550, 20712163, 6719373},
-		},
-		{
-			FieldElement{26656208, 6075253, -7858556, 1886072, -28344043, 4262326, 11117530, -3763210, 26224235, -3297458},
-			FieldElement{-17168938, -14854097, -3395676, -16369877, -19954045, 14050420, 21728352, 9493610, 18620611, -16428628},
-			FieldElement{-13323321, 13325349, 11432106, 5964811, 18609221, 6062965, -5269471, -9725556, -30701573, -16479657},
-		},
-		{
-			FieldElement{-23860538, -11233159, 26961357, 1640861, -32413112, -16737940, 12248509, -5240639, 13735342, 1934062},
-			FieldElement{25089769, 6742589, 17081145, -13406266, 21909293, -16067981, -15136294, -3765346, -21277997, 5473616},
-			FieldElement{31883677, -7961101, 1083432, -11572403, 22828471, 13290673, -7125085, 12469656, 29111212, -5451014},
-		},
-		{
-			FieldElement{24244947, -15050407, -26262976, 2791540, -14997599, 16666678, 24367466, 6388839, -10295587, 452383},
-			FieldElement{-25640782, -3417841, 5217916, 16224624, 19987036, -4082269, -24236251, -5915248, 15766062, 8407814},
-			FieldElement{-20406999, 13990231, 15495425, 16395525, 5377168, 15166495, -8917023, -4388953, -8067909, 2276718},
-		},
-		{
-			FieldElement{30157918, 12924066, -17712050, 9245753, 19895028, 3368142, -23827587, 5096219, 22740376, -7303417},
-			FieldElement{2041139, -14256350, 7783687, 13876377, -25946985, -13352459, 24051124, 13742383, -15637599, 13295222},
-			FieldElement{33338237, -8505733, 12532113, 7977527, 9106186, -1715251, -17720195, -4612972, -4451357, -14669444},
-		},
-		{
-			FieldElement{-20045281, 5454097, -14346548, 6447146, 28862071, 1883651, -2469266, -4141880, 7770569, 9620597},
-			FieldElement{23208068, 7979712, 33071466, 8149229, 1758231, -10834995, 30945528, -1694323, -33502340, -14767970},
-			FieldElement{1439958, -16270480, -1079989, -793782, 4625402, 10647766, -5043801, 1220118, 30494170, -11440799},
-		},
-		{
-			FieldElement{-5037580, -13028295, -2970559, -3061767, 15640974, -6701666, -26739026, 926050, -1684339, -13333647},
-			FieldElement{13908495, -3549272, 30919928, -6273825, -21521863, 7989039, 9021034, 9078865, 3353509, 4033511},
-			FieldElement{-29663431, -15113610, 32259991, -344482, 24295849, -12912123, 23161163, 8839127, 27485041, 7356032},
-		},
-	},
-	{
-		{
-			FieldElement{9661027, 705443, 11980065, -5370154, -1628543, 14661173, -6346142, 2625015, 28431036, -16771834},
-			FieldElement{-23839233, -8311415, -25945511, 7480958, -17681669, -8354183, -22545972, 14150565, 15970762, 4099461},
-			FieldElement{29262576, 16756590, 26350592, -8793563, 8529671, -11208050, 13617293, -9937143, 11465739, 8317062},
-		},
-		{
-			FieldElement{-25493081, -6962928, 32500200, -9419051, -23038724, -2302222, 14898637, 3848455, 20969334, -5157516},
-			FieldElement{-20384450, -14347713, -18336405, 13884722, -33039454, 2842114, -21610826, -3649888, 11177095, 14989547},
-			FieldElement{-24496721, -11716016, 16959896, 2278463, 12066309, 10137771, 13515641, 2581286, -28487508, 9930240},
-		},
-		{
-			FieldElement{-17751622, -2097826, 16544300, -13009300, -15914807, -14949081, 18345767, -13403753, 16291481, -5314038},
-			FieldElement{-33229194, 2553288, 32678213, 9875984, 8534129, 6889387, -9676774, 6957617, 4368891, 9788741},
-			FieldElement{16660756, 7281060, -10830758, 12911820, 20108584, -8101676, -21722536, -8613148, 16250552, -11111103},
-		},
-		{
-			FieldElement{-19765507, 2390526, -16551031, 14161980, 1905286, 6414907, 4689584, 10604807, -30190403, 4782747},
-			FieldElement{-1354539, 14736941, -7367442, -13292886, 7710542, -14155590, -9981571, 4383045, 22546403, 437323},
-			FieldElement{31665577, -12180464, -16186830, 1491339, -18368625, 3294682, 27343084, 2786261, -30633590, -14097016},
-		},
-		{
-			FieldElement{-14467279, -683715, -33374107, 7448552, 19294360, 14334329, -19690631, 2355319, -19284671, -6114373},
-			FieldElement{15121312, -15796162, 6377020, -6031361, -10798111, -12957845, 18952177, 15496498, -29380133, 11754228},
-			FieldElement{-2637277, -13483075, 8488727, -14303896, 12728761, -1622493, 7141596, 11724556, 22761615, -10134141},
-		},
-		{
-			FieldElement{16918416, 11729663, -18083579, 3022987, -31015732, -13339659, -28741185, -12227393, 32851222, 11717399},
-			FieldElement{11166634, 7338049, -6722523, 4531520, -29468672, -7302055, 31474879, 3483633, -1193175, -4030831},
-			FieldElement{-185635, 9921305, 31456609, -13536438, -12013818, 13348923, 33142652, 6546660, -19985279, -3948376},
-		},
-		{
-			FieldElement{-32460596, 11266712, -11197107, -7899103, 31703694, 3855903, -8537131, -12833048, -30772034, -15486313},
-			FieldElement{-18006477, 12709068, 3991746, -6479188, -21491523, -10550425, -31135347, -16049879, 10928917, 3011958},
-			FieldElement{-6957757, -15594337, 31696059, 334240, 29576716, 14796075, -30831056, -12805180, 18008031, 10258577},
-		},
-		{
-			FieldElement{-22448644, 15655569, 7018479, -4410003, -30314266, -1201591, -1853465, 1367120, 25127874, 6671743},
-			FieldElement{29701166, -14373934, -10878120, 9279288, -17568, 13127210, 21382910, 11042292, 25838796, 4642684},
-			FieldElement{-20430234, 14955537, -24126347, 8124619, -5369288, -5990470, 30468147, -13900640, 18423289, 4177476},
-		},
-	},
-}
diff --git a/vendor/golang.org/x/crypto/ed25519/internal/edwards25519/edwards25519.go b/vendor/golang.org/x/crypto/ed25519/internal/edwards25519/edwards25519.go
deleted file mode 100644
index fd03c252af..0000000000
--- a/vendor/golang.org/x/crypto/ed25519/internal/edwards25519/edwards25519.go
+++ /dev/null
@@ -1,1793 +0,0 @@
-// Copyright 2016 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package edwards25519
-
-import "encoding/binary"
-
-// This code is a port of the public domain, “ref10” implementation of ed25519
-// from SUPERCOP.
-
-// 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
-
-var zero FieldElement
-
-func FeZero(fe *FieldElement) {
-	copy(fe[:], zero[:])
-}
-
-func FeOne(fe *FieldElement) {
-	FeZero(fe)
-	fe[0] = 1
-}
-
-func FeAdd(dst, a, b *FieldElement) {
-	dst[0] = a[0] + b[0]
-	dst[1] = a[1] + b[1]
-	dst[2] = a[2] + b[2]
-	dst[3] = a[3] + b[3]
-	dst[4] = a[4] + b[4]
-	dst[5] = a[5] + b[5]
-	dst[6] = a[6] + b[6]
-	dst[7] = a[7] + b[7]
-	dst[8] = a[8] + b[8]
-	dst[9] = a[9] + b[9]
-}
-
-func FeSub(dst, a, b *FieldElement) {
-	dst[0] = a[0] - b[0]
-	dst[1] = a[1] - b[1]
-	dst[2] = a[2] - b[2]
-	dst[3] = a[3] - b[3]
-	dst[4] = a[4] - b[4]
-	dst[5] = a[5] - b[5]
-	dst[6] = a[6] - b[6]
-	dst[7] = a[7] - b[7]
-	dst[8] = a[8] - b[8]
-	dst[9] = a[9] - b[9]
-}
-
-func FeCopy(dst, src *FieldElement) {
-	copy(dst[:], src[:])
-}
-
-// Replace (f,g) with (g,g) if b == 1;
-// replace (f,g) with (f,g) if b == 0.
-//
-// Preconditions: b in {0,1}.
-func FeCMove(f, g *FieldElement, b int32) {
-	b = -b
-	f[0] ^= b & (f[0] ^ g[0])
-	f[1] ^= b & (f[1] ^ g[1])
-	f[2] ^= b & (f[2] ^ g[2])
-	f[3] ^= b & (f[3] ^ g[3])
-	f[4] ^= b & (f[4] ^ g[4])
-	f[5] ^= b & (f[5] ^ g[5])
-	f[6] ^= b & (f[6] ^ g[6])
-	f[7] ^= b & (f[7] ^ g[7])
-	f[8] ^= b & (f[8] ^ g[8])
-	f[9] ^= b & (f[9] ^ g[9])
-}
-
-func load3(in []byte) int64 {
-	var r int64
-	r = int64(in[0])
-	r |= int64(in[1]) << 8
-	r |= int64(in[2]) << 16
-	return r
-}
-
-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:]) & 8388607) << 2
-
-	FeCombine(dst, h0, h1, h2, h3, h4, h5, h6, h7, h8, 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)
-}
-
-func FeIsNegative(f *FieldElement) byte {
-	var s [32]byte
-	FeToBytes(&s, f)
-	return s[0] & 1
-}
-
-func FeIsNonZero(f *FieldElement) int32 {
-	var s [32]byte
-	FeToBytes(&s, f)
-	var x uint8
-	for _, b := range s {
-		x |= b
-	}
-	x |= x >> 4
-	x |= x >> 2
-	x |= x >> 1
-	return int32(x & 1)
-}
-
-// FeNeg sets h = -f
-//
-// Preconditions:
-//    |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
-//
-// Postconditions:
-//    |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
-func FeNeg(h, f *FieldElement) {
-	h[0] = -f[0]
-	h[1] = -f[1]
-	h[2] = -f[2]
-	h[3] = -f[3]
-	h[4] = -f[4]
-	h[5] = -f[5]
-	h[6] = -f[6]
-	h[7] = -f[7]
-	h[8] = -f[8]
-	h[9] = -f[9]
-}
-
-func FeCombine(h *FieldElement, h0, h1, h2, h3, h4, h5, h6, h7, h8, h9 int64) {
-	var c0, c1, c2, c3, c4, c5, c6, c7, c8, c9 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
-	*/
-
-	c0 = (h0 + (1 << 25)) >> 26
-	h1 += c0
-	h0 -= c0 << 26
-	c4 = (h4 + (1 << 25)) >> 26
-	h5 += c4
-	h4 -= c4 << 26
-	/* |h0| <= 2^25 */
-	/* |h4| <= 2^25 */
-	/* |h1| <= 1.51*2^58 */
-	/* |h5| <= 1.51*2^58 */
-
-	c1 = (h1 + (1 << 24)) >> 25
-	h2 += c1
-	h1 -= c1 << 25
-	c5 = (h5 + (1 << 24)) >> 25
-	h6 += c5
-	h5 -= c5 << 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 */
-
-	c2 = (h2 + (1 << 25)) >> 26
-	h3 += c2
-	h2 -= c2 << 26
-	c6 = (h6 + (1 << 25)) >> 26
-	h7 += c6
-	h6 -= c6 << 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 */
-
-	c3 = (h3 + (1 << 24)) >> 25
-	h4 += c3
-	h3 -= c3 << 25
-	c7 = (h7 + (1 << 24)) >> 25
-	h8 += c7
-	h7 -= c7 << 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 */
-
-	c4 = (h4 + (1 << 25)) >> 26
-	h5 += c4
-	h4 -= c4 << 26
-	c8 = (h8 + (1 << 25)) >> 26
-	h9 += c8
-	h8 -= c8 << 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 */
-
-	c9 = (h9 + (1 << 24)) >> 25
-	h0 += c9 * 19
-	h9 -= c9 << 25
-	/* |h9| <= 2^24; from now on fits into int32 unchanged */
-	/* |h0| <= 1.8*2^37 */
-
-	c0 = (h0 + (1 << 25)) >> 26
-	h1 += c0
-	h0 -= c0 << 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)
-}
-
-// 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 := int64(f[0])
-	f1 := int64(f[1])
-	f2 := int64(f[2])
-	f3 := int64(f[3])
-	f4 := int64(f[4])
-	f5 := int64(f[5])
-	f6 := int64(f[6])
-	f7 := int64(f[7])
-	f8 := int64(f[8])
-	f9 := int64(f[9])
-
-	f1_2 := int64(2 * f[1])
-	f3_2 := int64(2 * f[3])
-	f5_2 := int64(2 * f[5])
-	f7_2 := int64(2 * f[7])
-	f9_2 := int64(2 * f[9])
-
-	g0 := int64(g[0])
-	g1 := int64(g[1])
-	g2 := int64(g[2])
-	g3 := int64(g[3])
-	g4 := int64(g[4])
-	g5 := int64(g[5])
-	g6 := int64(g[6])
-	g7 := int64(g[7])
-	g8 := int64(g[8])
-	g9 := int64(g[9])
-
-	g1_19 := int64(19 * g[1]) /* 1.4*2^29 */
-	g2_19 := int64(19 * g[2]) /* 1.4*2^30; still ok */
-	g3_19 := int64(19 * g[3])
-	g4_19 := int64(19 * g[4])
-	g5_19 := int64(19 * g[5])
-	g6_19 := int64(19 * g[6])
-	g7_19 := int64(19 * g[7])
-	g8_19 := int64(19 * g[8])
-	g9_19 := int64(19 * g[9])
-
-	h0 := f0*g0 + f1_2*g9_19 + f2*g8_19 + f3_2*g7_19 + f4*g6_19 + f5_2*g5_19 + f6*g4_19 + f7_2*g3_19 + f8*g2_19 + f9_2*g1_19
-	h1 := f0*g1 + f1*g0 + f2*g9_19 + f3*g8_19 + f4*g7_19 + f5*g6_19 + f6*g5_19 + f7*g4_19 + f8*g3_19 + f9*g2_19
-	h2 := f0*g2 + f1_2*g1 + f2*g0 + f3_2*g9_19 + f4*g8_19 + f5_2*g7_19 + f6*g6_19 + f7_2*g5_19 + f8*g4_19 + f9_2*g3_19
-	h3 := f0*g3 + f1*g2 + f2*g1 + f3*g0 + f4*g9_19 + f5*g8_19 + f6*g7_19 + f7*g6_19 + f8*g5_19 + f9*g4_19
-	h4 := f0*g4 + f1_2*g3 + f2*g2 + f3_2*g1 + f4*g0 + f5_2*g9_19 + f6*g8_19 + f7_2*g7_19 + f8*g6_19 + f9_2*g5_19
-	h5 := f0*g5 + f1*g4 + f2*g3 + f3*g2 + f4*g1 + f5*g0 + f6*g9_19 + f7*g8_19 + f8*g7_19 + f9*g6_19
-	h6 := f0*g6 + f1_2*g5 + f2*g4 + f3_2*g3 + f4*g2 + f5_2*g1 + f6*g0 + f7_2*g9_19 + f8*g8_19 + f9_2*g7_19
-	h7 := f0*g7 + f1*g6 + f2*g5 + f3*g4 + f4*g3 + f5*g2 + f6*g1 + f7*g0 + f8*g9_19 + f9*g8_19
-	h8 := f0*g8 + f1_2*g7 + f2*g6 + f3_2*g5 + f4*g4 + f5_2*g3 + f6*g2 + f7_2*g1 + f8*g0 + f9_2*g9_19
-	h9 := f0*g9 + f1*g8 + f2*g7 + f3*g6 + f4*g5 + f5*g4 + f6*g3 + f7*g2 + f8*g1 + f9*g0
-
-	FeCombine(h, h0, h1, h2, h3, h4, h5, h6, h7, h8, h9)
-}
-
-func feSquare(f *FieldElement) (h0, h1, h2, h3, h4, h5, h6, h7, h8, h9 int64) {
-	f0 := int64(f[0])
-	f1 := int64(f[1])
-	f2 := int64(f[2])
-	f3 := int64(f[3])
-	f4 := int64(f[4])
-	f5 := int64(f[5])
-	f6 := int64(f[6])
-	f7 := int64(f[7])
-	f8 := int64(f[8])
-	f9 := int64(f[9])
-	f0_2 := int64(2 * f[0])
-	f1_2 := int64(2 * f[1])
-	f2_2 := int64(2 * f[2])
-	f3_2 := int64(2 * f[3])
-	f4_2 := int64(2 * f[4])
-	f5_2 := int64(2 * f[5])
-	f6_2 := int64(2 * f[6])
-	f7_2 := int64(2 * f[7])
-	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
-
-	h0 = f0*f0 + f1_2*f9_38 + f2_2*f8_19 + f3_2*f7_38 + f4_2*f6_19 + f5*f5_38
-	h1 = f0_2*f1 + f2*f9_38 + f3_2*f8_19 + f4*f7_38 + f5_2*f6_19
-	h2 = f0_2*f2 + f1_2*f1 + f3_2*f9_38 + f4_2*f8_19 + f5_2*f7_38 + f6*f6_19
-	h3 = f0_2*f3 + f1_2*f2 + f4*f9_38 + f5_2*f8_19 + f6*f7_38
-	h4 = f0_2*f4 + f1_2*f3_2 + f2*f2 + f5_2*f9_38 + f6_2*f8_19 + f7*f7_38
-	h5 = f0_2*f5 + f1_2*f4 + f2_2*f3 + f6*f9_38 + f7_2*f8_19
-	h6 = f0_2*f6 + f1_2*f5_2 + f2_2*f4 + f3_2*f3 + f7_2*f9_38 + f8*f8_19
-	h7 = f0_2*f7 + f1_2*f6 + f2_2*f5 + f3_2*f4 + f8*f9_38
-	h8 = f0_2*f8 + f1_2*f7_2 + f2_2*f6 + f3_2*f5_2 + f4*f4 + f9*f9_38
-	h9 = f0_2*f9 + f1_2*f8 + f2_2*f7 + f3_2*f6 + f4_2*f5
-
-	return
-}
-
-// 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) {
-	h0, h1, h2, h3, h4, h5, h6, h7, h8, h9 := feSquare(f)
-	FeCombine(h, h0, h1, h2, h3, h4, h5, h6, h7, h8, h9)
-}
-
-// FeSquare2 sets h = 2 * f * f
-//
-// Can overlap h with f.
-//
-// Preconditions:
-//    |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc.
-//
-// Postconditions:
-//    |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc.
-// See fe_mul.c for discussion of implementation strategy.
-func FeSquare2(h, f *FieldElement) {
-	h0, h1, h2, h3, h4, h5, h6, h7, h8, h9 := feSquare(f)
-
-	h0 += h0
-	h1 += h1
-	h2 += h2
-	h3 += h3
-	h4 += h4
-	h5 += h5
-	h6 += h6
-	h7 += h7
-	h8 += h8
-	h9 += h9
-
-	FeCombine(h, h0, h1, h2, h3, h4, h5, h6, h7, h8, h9)
-}
-
-func FeInvert(out, z *FieldElement) {
-	var t0, t1, t2, t3 FieldElement
-	var i int
-
-	FeSquare(&t0, z)        // 2^1
-	FeSquare(&t1, &t0)      // 2^2
-	for i = 1; i < 2; i++ { // 2^3
-		FeSquare(&t1, &t1)
-	}
-	FeMul(&t1, z, &t1)      // 2^3 + 2^0
-	FeMul(&t0, &t0, &t1)    // 2^3 + 2^1 + 2^0
-	FeSquare(&t2, &t0)      // 2^4 + 2^2 + 2^1
-	FeMul(&t1, &t1, &t2)    // 2^4 + 2^3 + 2^2 + 2^1 + 2^0
-	FeSquare(&t2, &t1)      // 5,4,3,2,1
-	for i = 1; i < 5; i++ { // 9,8,7,6,5
-		FeSquare(&t2, &t2)
-	}
-	FeMul(&t1, &t2, &t1)     // 9,8,7,6,5,4,3,2,1,0
-	FeSquare(&t2, &t1)       // 10..1
-	for i = 1; i < 10; i++ { // 19..10
-		FeSquare(&t2, &t2)
-	}
-	FeMul(&t2, &t2, &t1)     // 19..0
-	FeSquare(&t3, &t2)       // 20..1
-	for i = 1; i < 20; i++ { // 39..20
-		FeSquare(&t3, &t3)
-	}
-	FeMul(&t2, &t3, &t2)     // 39..0
-	FeSquare(&t2, &t2)       // 40..1
-	for i = 1; i < 10; i++ { // 49..10
-		FeSquare(&t2, &t2)
-	}
-	FeMul(&t1, &t2, &t1)     // 49..0
-	FeSquare(&t2, &t1)       // 50..1
-	for i = 1; i < 50; i++ { // 99..50
-		FeSquare(&t2, &t2)
-	}
-	FeMul(&t2, &t2, &t1)      // 99..0
-	FeSquare(&t3, &t2)        // 100..1
-	for i = 1; i < 100; i++ { // 199..100
-		FeSquare(&t3, &t3)
-	}
-	FeMul(&t2, &t3, &t2)     // 199..0
-	FeSquare(&t2, &t2)       // 200..1
-	for i = 1; i < 50; i++ { // 249..50
-		FeSquare(&t2, &t2)
-	}
-	FeMul(&t1, &t2, &t1)    // 249..0
-	FeSquare(&t1, &t1)      // 250..1
-	for i = 1; i < 5; i++ { // 254..5
-		FeSquare(&t1, &t1)
-	}
-	FeMul(out, &t1, &t0) // 254..5,3,1,0
-}
-
-func fePow22523(out, z *FieldElement) {
-	var t0, t1, t2 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(&t0, &t0)
-	for i = 1; i < 1; i++ {
-		FeSquare(&t0, &t0)
-	}
-	FeMul(&t0, &t1, &t0)
-	FeSquare(&t1, &t0)
-	for i = 1; i < 5; i++ {
-		FeSquare(&t1, &t1)
-	}
-	FeMul(&t0, &t1, &t0)
-	FeSquare(&t1, &t0)
-	for i = 1; i < 10; i++ {
-		FeSquare(&t1, &t1)
-	}
-	FeMul(&t1, &t1, &t0)
-	FeSquare(&t2, &t1)
-	for i = 1; i < 20; i++ {
-		FeSquare(&t2, &t2)
-	}
-	FeMul(&t1, &t2, &t1)
-	FeSquare(&t1, &t1)
-	for i = 1; i < 10; i++ {
-		FeSquare(&t1, &t1)
-	}
-	FeMul(&t0, &t1, &t0)
-	FeSquare(&t1, &t0)
-	for i = 1; i < 50; i++ {
-		FeSquare(&t1, &t1)
-	}
-	FeMul(&t1, &t1, &t0)
-	FeSquare(&t2, &t1)
-	for i = 1; i < 100; i++ {
-		FeSquare(&t2, &t2)
-	}
-	FeMul(&t1, &t2, &t1)
-	FeSquare(&t1, &t1)
-	for i = 1; i < 50; i++ {
-		FeSquare(&t1, &t1)
-	}
-	FeMul(&t0, &t1, &t0)
-	FeSquare(&t0, &t0)
-	for i = 1; i < 2; i++ {
-		FeSquare(&t0, &t0)
-	}
-	FeMul(out, &t0, z)
-}
-
-// Group elements are members of the elliptic curve -x^2 + y^2 = 1 + d * x^2 *
-// y^2 where d = -121665/121666.
-//
-// Several representations are used:
-//   ProjectiveGroupElement: (X:Y:Z) satisfying x=X/Z, y=Y/Z
-//   ExtendedGroupElement: (X:Y:Z:T) satisfying x=X/Z, y=Y/Z, XY=ZT
-//   CompletedGroupElement: ((X:Z),(Y:T)) satisfying x=X/Z, y=Y/T
-//   PreComputedGroupElement: (y+x,y-x,2dxy)
-
-type ProjectiveGroupElement struct {
-	X, Y, Z FieldElement
-}
-
-type ExtendedGroupElement struct {
-	X, Y, Z, T FieldElement
-}
-
-type CompletedGroupElement struct {
-	X, Y, Z, T FieldElement
-}
-
-type PreComputedGroupElement struct {
-	yPlusX, yMinusX, xy2d FieldElement
-}
-
-type CachedGroupElement struct {
-	yPlusX, yMinusX, Z, T2d FieldElement
-}
-
-func (p *ProjectiveGroupElement) Zero() {
-	FeZero(&p.X)
-	FeOne(&p.Y)
-	FeOne(&p.Z)
-}
-
-func (p *ProjectiveGroupElement) Double(r *CompletedGroupElement) {
-	var t0 FieldElement
-
-	FeSquare(&r.X, &p.X)
-	FeSquare(&r.Z, &p.Y)
-	FeSquare2(&r.T, &p.Z)
-	FeAdd(&r.Y, &p.X, &p.Y)
-	FeSquare(&t0, &r.Y)
-	FeAdd(&r.Y, &r.Z, &r.X)
-	FeSub(&r.Z, &r.Z, &r.X)
-	FeSub(&r.X, &t0, &r.Y)
-	FeSub(&r.T, &r.T, &r.Z)
-}
-
-func (p *ProjectiveGroupElement) ToBytes(s *[32]byte) {
-	var recip, x, y FieldElement
-
-	FeInvert(&recip, &p.Z)
-	FeMul(&x, &p.X, &recip)
-	FeMul(&y, &p.Y, &recip)
-	FeToBytes(s, &y)
-	s[31] ^= FeIsNegative(&x) << 7
-}
-
-func (p *ExtendedGroupElement) Zero() {
-	FeZero(&p.X)
-	FeOne(&p.Y)
-	FeOne(&p.Z)
-	FeZero(&p.T)
-}
-
-func (p *ExtendedGroupElement) Double(r *CompletedGroupElement) {
-	var q ProjectiveGroupElement
-	p.ToProjective(&q)
-	q.Double(r)
-}
-
-func (p *ExtendedGroupElement) ToCached(r *CachedGroupElement) {
-	FeAdd(&r.yPlusX, &p.Y, &p.X)
-	FeSub(&r.yMinusX, &p.Y, &p.X)
-	FeCopy(&r.Z, &p.Z)
-	FeMul(&r.T2d, &p.T, &d2)
-}
-
-func (p *ExtendedGroupElement) ToProjective(r *ProjectiveGroupElement) {
-	FeCopy(&r.X, &p.X)
-	FeCopy(&r.Y, &p.Y)
-	FeCopy(&r.Z, &p.Z)
-}
-
-func (p *ExtendedGroupElement) ToBytes(s *[32]byte) {
-	var recip, x, y FieldElement
-
-	FeInvert(&recip, &p.Z)
-	FeMul(&x, &p.X, &recip)
-	FeMul(&y, &p.Y, &recip)
-	FeToBytes(s, &y)
-	s[31] ^= FeIsNegative(&x) << 7
-}
-
-func (p *ExtendedGroupElement) FromBytes(s *[32]byte) bool {
-	var u, v, v3, vxx, check FieldElement
-
-	FeFromBytes(&p.Y, s)
-	FeOne(&p.Z)
-	FeSquare(&u, &p.Y)
-	FeMul(&v, &u, &d)
-	FeSub(&u, &u, &p.Z) // y = y^2-1
-	FeAdd(&v, &v, &p.Z) // v = dy^2+1
-
-	FeSquare(&v3, &v)
-	FeMul(&v3, &v3, &v) // v3 = v^3
-	FeSquare(&p.X, &v3)
-	FeMul(&p.X, &p.X, &v)
-	FeMul(&p.X, &p.X, &u) // x = uv^7
-
-	fePow22523(&p.X, &p.X) // x = (uv^7)^((q-5)/8)
-	FeMul(&p.X, &p.X, &v3)
-	FeMul(&p.X, &p.X, &u) // x = uv^3(uv^7)^((q-5)/8)
-
-	var tmpX, tmp2 [32]byte
-
-	FeSquare(&vxx, &p.X)
-	FeMul(&vxx, &vxx, &v)
-	FeSub(&check, &vxx, &u) // vx^2-u
-	if FeIsNonZero(&check) == 1 {
-		FeAdd(&check, &vxx, &u) // vx^2+u
-		if FeIsNonZero(&check) == 1 {
-			return false
-		}
-		FeMul(&p.X, &p.X, &SqrtM1)
-
-		FeToBytes(&tmpX, &p.X)
-		for i, v := range tmpX {
-			tmp2[31-i] = v
-		}
-	}
-
-	if FeIsNegative(&p.X) != (s[31] >> 7) {
-		FeNeg(&p.X, &p.X)
-	}
-
-	FeMul(&p.T, &p.X, &p.Y)
-	return true
-}
-
-func (p *CompletedGroupElement) ToProjective(r *ProjectiveGroupElement) {
-	FeMul(&r.X, &p.X, &p.T)
-	FeMul(&r.Y, &p.Y, &p.Z)
-	FeMul(&r.Z, &p.Z, &p.T)
-}
-
-func (p *CompletedGroupElement) ToExtended(r *ExtendedGroupElement) {
-	FeMul(&r.X, &p.X, &p.T)
-	FeMul(&r.Y, &p.Y, &p.Z)
-	FeMul(&r.Z, &p.Z, &p.T)
-	FeMul(&r.T, &p.X, &p.Y)
-}
-
-func (p *PreComputedGroupElement) Zero() {
-	FeOne(&p.yPlusX)
-	FeOne(&p.yMinusX)
-	FeZero(&p.xy2d)
-}
-
-func geAdd(r *CompletedGroupElement, p *ExtendedGroupElement, q *CachedGroupElement) {
-	var t0 FieldElement
-
-	FeAdd(&r.X, &p.Y, &p.X)
-	FeSub(&r.Y, &p.Y, &p.X)
-	FeMul(&r.Z, &r.X, &q.yPlusX)
-	FeMul(&r.Y, &r.Y, &q.yMinusX)
-	FeMul(&r.T, &q.T2d, &p.T)
-	FeMul(&r.X, &p.Z, &q.Z)
-	FeAdd(&t0, &r.X, &r.X)
-	FeSub(&r.X, &r.Z, &r.Y)
-	FeAdd(&r.Y, &r.Z, &r.Y)
-	FeAdd(&r.Z, &t0, &r.T)
-	FeSub(&r.T, &t0, &r.T)
-}
-
-func geSub(r *CompletedGroupElement, p *ExtendedGroupElement, q *CachedGroupElement) {
-	var t0 FieldElement
-
-	FeAdd(&r.X, &p.Y, &p.X)
-	FeSub(&r.Y, &p.Y, &p.X)
-	FeMul(&r.Z, &r.X, &q.yMinusX)
-	FeMul(&r.Y, &r.Y, &q.yPlusX)
-	FeMul(&r.T, &q.T2d, &p.T)
-	FeMul(&r.X, &p.Z, &q.Z)
-	FeAdd(&t0, &r.X, &r.X)
-	FeSub(&r.X, &r.Z, &r.Y)
-	FeAdd(&r.Y, &r.Z, &r.Y)
-	FeSub(&r.Z, &t0, &r.T)
-	FeAdd(&r.T, &t0, &r.T)
-}
-
-func geMixedAdd(r *CompletedGroupElement, p *ExtendedGroupElement, q *PreComputedGroupElement) {
-	var t0 FieldElement
-
-	FeAdd(&r.X, &p.Y, &p.X)
-	FeSub(&r.Y, &p.Y, &p.X)
-	FeMul(&r.Z, &r.X, &q.yPlusX)
-	FeMul(&r.Y, &r.Y, &q.yMinusX)
-	FeMul(&r.T, &q.xy2d, &p.T)
-	FeAdd(&t0, &p.Z, &p.Z)
-	FeSub(&r.X, &r.Z, &r.Y)
-	FeAdd(&r.Y, &r.Z, &r.Y)
-	FeAdd(&r.Z, &t0, &r.T)
-	FeSub(&r.T, &t0, &r.T)
-}
-
-func geMixedSub(r *CompletedGroupElement, p *ExtendedGroupElement, q *PreComputedGroupElement) {
-	var t0 FieldElement
-
-	FeAdd(&r.X, &p.Y, &p.X)
-	FeSub(&r.Y, &p.Y, &p.X)
-	FeMul(&r.Z, &r.X, &q.yMinusX)
-	FeMul(&r.Y, &r.Y, &q.yPlusX)
-	FeMul(&r.T, &q.xy2d, &p.T)
-	FeAdd(&t0, &p.Z, &p.Z)
-	FeSub(&r.X, &r.Z, &r.Y)
-	FeAdd(&r.Y, &r.Z, &r.Y)
-	FeSub(&r.Z, &t0, &r.T)
-	FeAdd(&r.T, &t0, &r.T)
-}
-
-func slide(r *[256]int8, a *[32]byte) {
-	for i := range r {
-		r[i] = int8(1 & (a[i>>3] >> uint(i&7)))
-	}
-
-	for i := range r {
-		if r[i] != 0 {
-			for b := 1; b <= 6 && i+b < 256; b++ {
-				if r[i+b] != 0 {
-					if r[i]+(r[i+b]<<uint(b)) <= 15 {
-						r[i] += r[i+b] << uint(b)
-						r[i+b] = 0
-					} else if r[i]-(r[i+b]<<uint(b)) >= -15 {
-						r[i] -= r[i+b] << uint(b)
-						for k := i + b; k < 256; k++ {
-							if r[k] == 0 {
-								r[k] = 1
-								break
-							}
-							r[k] = 0
-						}
-					} else {
-						break
-					}
-				}
-			}
-		}
-	}
-}
-
-// GeDoubleScalarMultVartime sets r = a*A + b*B
-// where a = a[0]+256*a[1]+...+256^31 a[31].
-// and b = b[0]+256*b[1]+...+256^31 b[31].
-// B is the Ed25519 base point (x,4/5) with x positive.
-func GeDoubleScalarMultVartime(r *ProjectiveGroupElement, a *[32]byte, A *ExtendedGroupElement, b *[32]byte) {
-	var aSlide, bSlide [256]int8
-	var Ai [8]CachedGroupElement // A,3A,5A,7A,9A,11A,13A,15A
-	var t CompletedGroupElement
-	var u, A2 ExtendedGroupElement
-	var i int
-
-	slide(&aSlide, a)
-	slide(&bSlide, b)
-
-	A.ToCached(&Ai[0])
-	A.Double(&t)
-	t.ToExtended(&A2)
-
-	for i := 0; i < 7; i++ {
-		geAdd(&t, &A2, &Ai[i])
-		t.ToExtended(&u)
-		u.ToCached(&Ai[i+1])
-	}
-
-	r.Zero()
-
-	for i = 255; i >= 0; i-- {
-		if aSlide[i] != 0 || bSlide[i] != 0 {
-			break
-		}
-	}
-
-	for ; i >= 0; i-- {
-		r.Double(&t)
-
-		if aSlide[i] > 0 {
-			t.ToExtended(&u)
-			geAdd(&t, &u, &Ai[aSlide[i]/2])
-		} else if aSlide[i] < 0 {
-			t.ToExtended(&u)
-			geSub(&t, &u, &Ai[(-aSlide[i])/2])
-		}
-
-		if bSlide[i] > 0 {
-			t.ToExtended(&u)
-			geMixedAdd(&t, &u, &bi[bSlide[i]/2])
-		} else if bSlide[i] < 0 {
-			t.ToExtended(&u)
-			geMixedSub(&t, &u, &bi[(-bSlide[i])/2])
-		}
-
-		t.ToProjective(r)
-	}
-}
-
-// equal returns 1 if b == c and 0 otherwise, assuming that b and c are
-// non-negative.
-func equal(b, c int32) int32 {
-	x := uint32(b ^ c)
-	x--
-	return int32(x >> 31)
-}
-
-// negative returns 1 if b < 0 and 0 otherwise.
-func negative(b int32) int32 {
-	return (b >> 31) & 1
-}
-
-func PreComputedGroupElementCMove(t, u *PreComputedGroupElement, b int32) {
-	FeCMove(&t.yPlusX, &u.yPlusX, b)
-	FeCMove(&t.yMinusX, &u.yMinusX, b)
-	FeCMove(&t.xy2d, &u.xy2d, b)
-}
-
-func selectPoint(t *PreComputedGroupElement, pos int32, b int32) {
-	var minusT PreComputedGroupElement
-	bNegative := negative(b)
-	bAbs := b - (((-bNegative) & b) << 1)
-
-	t.Zero()
-	for i := int32(0); i < 8; i++ {
-		PreComputedGroupElementCMove(t, &base[pos][i], equal(bAbs, i+1))
-	}
-	FeCopy(&minusT.yPlusX, &t.yMinusX)
-	FeCopy(&minusT.yMinusX, &t.yPlusX)
-	FeNeg(&minusT.xy2d, &t.xy2d)
-	PreComputedGroupElementCMove(t, &minusT, bNegative)
-}
-
-// GeScalarMultBase computes h = a*B, where
-//   a = a[0]+256*a[1]+...+256^31 a[31]
-//   B is the Ed25519 base point (x,4/5) with x positive.
-//
-// Preconditions:
-//   a[31] <= 127
-func GeScalarMultBase(h *ExtendedGroupElement, a *[32]byte) {
-	var e [64]int8
-
-	for i, v := range a {
-		e[2*i] = int8(v & 15)
-		e[2*i+1] = int8((v >> 4) & 15)
-	}
-
-	// each e[i] is between 0 and 15 and e[63] is between 0 and 7.
-
-	carry := int8(0)
-	for i := 0; i < 63; i++ {
-		e[i] += carry
-		carry = (e[i] + 8) >> 4
-		e[i] -= carry << 4
-	}
-	e[63] += carry
-	// each e[i] is between -8 and 8.
-
-	h.Zero()
-	var t PreComputedGroupElement
-	var r CompletedGroupElement
-	for i := int32(1); i < 64; i += 2 {
-		selectPoint(&t, i/2, int32(e[i]))
-		geMixedAdd(&r, h, &t)
-		r.ToExtended(h)
-	}
-
-	var s ProjectiveGroupElement
-
-	h.Double(&r)
-	r.ToProjective(&s)
-	s.Double(&r)
-	r.ToProjective(&s)
-	s.Double(&r)
-	r.ToProjective(&s)
-	s.Double(&r)
-	r.ToExtended(h)
-
-	for i := int32(0); i < 64; i += 2 {
-		selectPoint(&t, i/2, int32(e[i]))
-		geMixedAdd(&r, h, &t)
-		r.ToExtended(h)
-	}
-}
-
-// The scalars are GF(2^252 + 27742317777372353535851937790883648493).
-
-// Input:
-//   a[0]+256*a[1]+...+256^31*a[31] = a
-//   b[0]+256*b[1]+...+256^31*b[31] = b
-//   c[0]+256*c[1]+...+256^31*c[31] = c
-//
-// Output:
-//   s[0]+256*s[1]+...+256^31*s[31] = (ab+c) mod l
-//   where l = 2^252 + 27742317777372353535851937790883648493.
-func ScMulAdd(s, a, b, c *[32]byte) {
-	a0 := 2097151 & load3(a[:])
-	a1 := 2097151 & (load4(a[2:]) >> 5)
-	a2 := 2097151 & (load3(a[5:]) >> 2)
-	a3 := 2097151 & (load4(a[7:]) >> 7)
-	a4 := 2097151 & (load4(a[10:]) >> 4)
-	a5 := 2097151 & (load3(a[13:]) >> 1)
-	a6 := 2097151 & (load4(a[15:]) >> 6)
-	a7 := 2097151 & (load3(a[18:]) >> 3)
-	a8 := 2097151 & load3(a[21:])
-	a9 := 2097151 & (load4(a[23:]) >> 5)
-	a10 := 2097151 & (load3(a[26:]) >> 2)
-	a11 := (load4(a[28:]) >> 7)
-	b0 := 2097151 & load3(b[:])
-	b1 := 2097151 & (load4(b[2:]) >> 5)
-	b2 := 2097151 & (load3(b[5:]) >> 2)
-	b3 := 2097151 & (load4(b[7:]) >> 7)
-	b4 := 2097151 & (load4(b[10:]) >> 4)
-	b5 := 2097151 & (load3(b[13:]) >> 1)
-	b6 := 2097151 & (load4(b[15:]) >> 6)
-	b7 := 2097151 & (load3(b[18:]) >> 3)
-	b8 := 2097151 & load3(b[21:])
-	b9 := 2097151 & (load4(b[23:]) >> 5)
-	b10 := 2097151 & (load3(b[26:]) >> 2)
-	b11 := (load4(b[28:]) >> 7)
-	c0 := 2097151 & load3(c[:])
-	c1 := 2097151 & (load4(c[2:]) >> 5)
-	c2 := 2097151 & (load3(c[5:]) >> 2)
-	c3 := 2097151 & (load4(c[7:]) >> 7)
-	c4 := 2097151 & (load4(c[10:]) >> 4)
-	c5 := 2097151 & (load3(c[13:]) >> 1)
-	c6 := 2097151 & (load4(c[15:]) >> 6)
-	c7 := 2097151 & (load3(c[18:]) >> 3)
-	c8 := 2097151 & load3(c[21:])
-	c9 := 2097151 & (load4(c[23:]) >> 5)
-	c10 := 2097151 & (load3(c[26:]) >> 2)
-	c11 := (load4(c[28:]) >> 7)
-	var carry [23]int64
-
-	s0 := c0 + a0*b0
-	s1 := c1 + a0*b1 + a1*b0
-	s2 := c2 + a0*b2 + a1*b1 + a2*b0
-	s3 := c3 + a0*b3 + a1*b2 + a2*b1 + a3*b0
-	s4 := c4 + a0*b4 + a1*b3 + a2*b2 + a3*b1 + a4*b0
-	s5 := c5 + a0*b5 + a1*b4 + a2*b3 + a3*b2 + a4*b1 + a5*b0
-	s6 := c6 + a0*b6 + a1*b5 + a2*b4 + a3*b3 + a4*b2 + a5*b1 + a6*b0
-	s7 := c7 + a0*b7 + a1*b6 + a2*b5 + a3*b4 + a4*b3 + a5*b2 + a6*b1 + a7*b0
-	s8 := c8 + a0*b8 + a1*b7 + a2*b6 + a3*b5 + a4*b4 + a5*b3 + a6*b2 + a7*b1 + a8*b0
-	s9 := c9 + a0*b9 + a1*b8 + a2*b7 + a3*b6 + a4*b5 + a5*b4 + a6*b3 + a7*b2 + a8*b1 + a9*b0
-	s10 := c10 + a0*b10 + a1*b9 + a2*b8 + a3*b7 + a4*b6 + a5*b5 + a6*b4 + a7*b3 + a8*b2 + a9*b1 + a10*b0
-	s11 := c11 + a0*b11 + a1*b10 + a2*b9 + a3*b8 + a4*b7 + a5*b6 + a6*b5 + a7*b4 + a8*b3 + a9*b2 + a10*b1 + a11*b0
-	s12 := a1*b11 + a2*b10 + a3*b9 + a4*b8 + a5*b7 + a6*b6 + a7*b5 + a8*b4 + a9*b3 + a10*b2 + a11*b1
-	s13 := a2*b11 + a3*b10 + a4*b9 + a5*b8 + a6*b7 + a7*b6 + a8*b5 + a9*b4 + a10*b3 + a11*b2
-	s14 := a3*b11 + a4*b10 + a5*b9 + a6*b8 + a7*b7 + a8*b6 + a9*b5 + a10*b4 + a11*b3
-	s15 := a4*b11 + a5*b10 + a6*b9 + a7*b8 + a8*b7 + a9*b6 + a10*b5 + a11*b4
-	s16 := a5*b11 + a6*b10 + a7*b9 + a8*b8 + a9*b7 + a10*b6 + a11*b5
-	s17 := a6*b11 + a7*b10 + a8*b9 + a9*b8 + a10*b7 + a11*b6
-	s18 := a7*b11 + a8*b10 + a9*b9 + a10*b8 + a11*b7
-	s19 := a8*b11 + a9*b10 + a10*b9 + a11*b8
-	s20 := a9*b11 + a10*b10 + a11*b9
-	s21 := a10*b11 + a11*b10
-	s22 := a11 * b11
-	s23 := int64(0)
-
-	carry[0] = (s0 + (1 << 20)) >> 21
-	s1 += carry[0]
-	s0 -= carry[0] << 21
-	carry[2] = (s2 + (1 << 20)) >> 21
-	s3 += carry[2]
-	s2 -= carry[2] << 21
-	carry[4] = (s4 + (1 << 20)) >> 21
-	s5 += carry[4]
-	s4 -= carry[4] << 21
-	carry[6] = (s6 + (1 << 20)) >> 21
-	s7 += carry[6]
-	s6 -= carry[6] << 21
-	carry[8] = (s8 + (1 << 20)) >> 21
-	s9 += carry[8]
-	s8 -= carry[8] << 21
-	carry[10] = (s10 + (1 << 20)) >> 21
-	s11 += carry[10]
-	s10 -= carry[10] << 21
-	carry[12] = (s12 + (1 << 20)) >> 21
-	s13 += carry[12]
-	s12 -= carry[12] << 21
-	carry[14] = (s14 + (1 << 20)) >> 21
-	s15 += carry[14]
-	s14 -= carry[14] << 21
-	carry[16] = (s16 + (1 << 20)) >> 21
-	s17 += carry[16]
-	s16 -= carry[16] << 21
-	carry[18] = (s18 + (1 << 20)) >> 21
-	s19 += carry[18]
-	s18 -= carry[18] << 21
-	carry[20] = (s20 + (1 << 20)) >> 21
-	s21 += carry[20]
-	s20 -= carry[20] << 21
-	carry[22] = (s22 + (1 << 20)) >> 21
-	s23 += carry[22]
-	s22 -= carry[22] << 21
-
-	carry[1] = (s1 + (1 << 20)) >> 21
-	s2 += carry[1]
-	s1 -= carry[1] << 21
-	carry[3] = (s3 + (1 << 20)) >> 21
-	s4 += carry[3]
-	s3 -= carry[3] << 21
-	carry[5] = (s5 + (1 << 20)) >> 21
-	s6 += carry[5]
-	s5 -= carry[5] << 21
-	carry[7] = (s7 + (1 << 20)) >> 21
-	s8 += carry[7]
-	s7 -= carry[7] << 21
-	carry[9] = (s9 + (1 << 20)) >> 21
-	s10 += carry[9]
-	s9 -= carry[9] << 21
-	carry[11] = (s11 + (1 << 20)) >> 21
-	s12 += carry[11]
-	s11 -= carry[11] << 21
-	carry[13] = (s13 + (1 << 20)) >> 21
-	s14 += carry[13]
-	s13 -= carry[13] << 21
-	carry[15] = (s15 + (1 << 20)) >> 21
-	s16 += carry[15]
-	s15 -= carry[15] << 21
-	carry[17] = (s17 + (1 << 20)) >> 21
-	s18 += carry[17]
-	s17 -= carry[17] << 21
-	carry[19] = (s19 + (1 << 20)) >> 21
-	s20 += carry[19]
-	s19 -= carry[19] << 21
-	carry[21] = (s21 + (1 << 20)) >> 21
-	s22 += carry[21]
-	s21 -= carry[21] << 21
-
-	s11 += s23 * 666643
-	s12 += s23 * 470296
-	s13 += s23 * 654183
-	s14 -= s23 * 997805
-	s15 += s23 * 136657
-	s16 -= s23 * 683901
-	s23 = 0
-
-	s10 += s22 * 666643
-	s11 += s22 * 470296
-	s12 += s22 * 654183
-	s13 -= s22 * 997805
-	s14 += s22 * 136657
-	s15 -= s22 * 683901
-	s22 = 0
-
-	s9 += s21 * 666643
-	s10 += s21 * 470296
-	s11 += s21 * 654183
-	s12 -= s21 * 997805
-	s13 += s21 * 136657
-	s14 -= s21 * 683901
-	s21 = 0
-
-	s8 += s20 * 666643
-	s9 += s20 * 470296
-	s10 += s20 * 654183
-	s11 -= s20 * 997805
-	s12 += s20 * 136657
-	s13 -= s20 * 683901
-	s20 = 0
-
-	s7 += s19 * 666643
-	s8 += s19 * 470296
-	s9 += s19 * 654183
-	s10 -= s19 * 997805
-	s11 += s19 * 136657
-	s12 -= s19 * 683901
-	s19 = 0
-
-	s6 += s18 * 666643
-	s7 += s18 * 470296
-	s8 += s18 * 654183
-	s9 -= s18 * 997805
-	s10 += s18 * 136657
-	s11 -= s18 * 683901
-	s18 = 0
-
-	carry[6] = (s6 + (1 << 20)) >> 21
-	s7 += carry[6]
-	s6 -= carry[6] << 21
-	carry[8] = (s8 + (1 << 20)) >> 21
-	s9 += carry[8]
-	s8 -= carry[8] << 21
-	carry[10] = (s10 + (1 << 20)) >> 21
-	s11 += carry[10]
-	s10 -= carry[10] << 21
-	carry[12] = (s12 + (1 << 20)) >> 21
-	s13 += carry[12]
-	s12 -= carry[12] << 21
-	carry[14] = (s14 + (1 << 20)) >> 21
-	s15 += carry[14]
-	s14 -= carry[14] << 21
-	carry[16] = (s16 + (1 << 20)) >> 21
-	s17 += carry[16]
-	s16 -= carry[16] << 21
-
-	carry[7] = (s7 + (1 << 20)) >> 21
-	s8 += carry[7]
-	s7 -= carry[7] << 21
-	carry[9] = (s9 + (1 << 20)) >> 21
-	s10 += carry[9]
-	s9 -= carry[9] << 21
-	carry[11] = (s11 + (1 << 20)) >> 21
-	s12 += carry[11]
-	s11 -= carry[11] << 21
-	carry[13] = (s13 + (1 << 20)) >> 21
-	s14 += carry[13]
-	s13 -= carry[13] << 21
-	carry[15] = (s15 + (1 << 20)) >> 21
-	s16 += carry[15]
-	s15 -= carry[15] << 21
-
-	s5 += s17 * 666643
-	s6 += s17 * 470296
-	s7 += s17 * 654183
-	s8 -= s17 * 997805
-	s9 += s17 * 136657
-	s10 -= s17 * 683901
-	s17 = 0
-
-	s4 += s16 * 666643
-	s5 += s16 * 470296
-	s6 += s16 * 654183
-	s7 -= s16 * 997805
-	s8 += s16 * 136657
-	s9 -= s16 * 683901
-	s16 = 0
-
-	s3 += s15 * 666643
-	s4 += s15 * 470296
-	s5 += s15 * 654183
-	s6 -= s15 * 997805
-	s7 += s15 * 136657
-	s8 -= s15 * 683901
-	s15 = 0
-
-	s2 += s14 * 666643
-	s3 += s14 * 470296
-	s4 += s14 * 654183
-	s5 -= s14 * 997805
-	s6 += s14 * 136657
-	s7 -= s14 * 683901
-	s14 = 0
-
-	s1 += s13 * 666643
-	s2 += s13 * 470296
-	s3 += s13 * 654183
-	s4 -= s13 * 997805
-	s5 += s13 * 136657
-	s6 -= s13 * 683901
-	s13 = 0
-
-	s0 += s12 * 666643
-	s1 += s12 * 470296
-	s2 += s12 * 654183
-	s3 -= s12 * 997805
-	s4 += s12 * 136657
-	s5 -= s12 * 683901
-	s12 = 0
-
-	carry[0] = (s0 + (1 << 20)) >> 21
-	s1 += carry[0]
-	s0 -= carry[0] << 21
-	carry[2] = (s2 + (1 << 20)) >> 21
-	s3 += carry[2]
-	s2 -= carry[2] << 21
-	carry[4] = (s4 + (1 << 20)) >> 21
-	s5 += carry[4]
-	s4 -= carry[4] << 21
-	carry[6] = (s6 + (1 << 20)) >> 21
-	s7 += carry[6]
-	s6 -= carry[6] << 21
-	carry[8] = (s8 + (1 << 20)) >> 21
-	s9 += carry[8]
-	s8 -= carry[8] << 21
-	carry[10] = (s10 + (1 << 20)) >> 21
-	s11 += carry[10]
-	s10 -= carry[10] << 21
-
-	carry[1] = (s1 + (1 << 20)) >> 21
-	s2 += carry[1]
-	s1 -= carry[1] << 21
-	carry[3] = (s3 + (1 << 20)) >> 21
-	s4 += carry[3]
-	s3 -= carry[3] << 21
-	carry[5] = (s5 + (1 << 20)) >> 21
-	s6 += carry[5]
-	s5 -= carry[5] << 21
-	carry[7] = (s7 + (1 << 20)) >> 21
-	s8 += carry[7]
-	s7 -= carry[7] << 21
-	carry[9] = (s9 + (1 << 20)) >> 21
-	s10 += carry[9]
-	s9 -= carry[9] << 21
-	carry[11] = (s11 + (1 << 20)) >> 21
-	s12 += carry[11]
-	s11 -= carry[11] << 21
-
-	s0 += s12 * 666643
-	s1 += s12 * 470296
-	s2 += s12 * 654183
-	s3 -= s12 * 997805
-	s4 += s12 * 136657
-	s5 -= s12 * 683901
-	s12 = 0
-
-	carry[0] = s0 >> 21
-	s1 += carry[0]
-	s0 -= carry[0] << 21
-	carry[1] = s1 >> 21
-	s2 += carry[1]
-	s1 -= carry[1] << 21
-	carry[2] = s2 >> 21
-	s3 += carry[2]
-	s2 -= carry[2] << 21
-	carry[3] = s3 >> 21
-	s4 += carry[3]
-	s3 -= carry[3] << 21
-	carry[4] = s4 >> 21
-	s5 += carry[4]
-	s4 -= carry[4] << 21
-	carry[5] = s5 >> 21
-	s6 += carry[5]
-	s5 -= carry[5] << 21
-	carry[6] = s6 >> 21
-	s7 += carry[6]
-	s6 -= carry[6] << 21
-	carry[7] = s7 >> 21
-	s8 += carry[7]
-	s7 -= carry[7] << 21
-	carry[8] = s8 >> 21
-	s9 += carry[8]
-	s8 -= carry[8] << 21
-	carry[9] = s9 >> 21
-	s10 += carry[9]
-	s9 -= carry[9] << 21
-	carry[10] = s10 >> 21
-	s11 += carry[10]
-	s10 -= carry[10] << 21
-	carry[11] = s11 >> 21
-	s12 += carry[11]
-	s11 -= carry[11] << 21
-
-	s0 += s12 * 666643
-	s1 += s12 * 470296
-	s2 += s12 * 654183
-	s3 -= s12 * 997805
-	s4 += s12 * 136657
-	s5 -= s12 * 683901
-	s12 = 0
-
-	carry[0] = s0 >> 21
-	s1 += carry[0]
-	s0 -= carry[0] << 21
-	carry[1] = s1 >> 21
-	s2 += carry[1]
-	s1 -= carry[1] << 21
-	carry[2] = s2 >> 21
-	s3 += carry[2]
-	s2 -= carry[2] << 21
-	carry[3] = s3 >> 21
-	s4 += carry[3]
-	s3 -= carry[3] << 21
-	carry[4] = s4 >> 21
-	s5 += carry[4]
-	s4 -= carry[4] << 21
-	carry[5] = s5 >> 21
-	s6 += carry[5]
-	s5 -= carry[5] << 21
-	carry[6] = s6 >> 21
-	s7 += carry[6]
-	s6 -= carry[6] << 21
-	carry[7] = s7 >> 21
-	s8 += carry[7]
-	s7 -= carry[7] << 21
-	carry[8] = s8 >> 21
-	s9 += carry[8]
-	s8 -= carry[8] << 21
-	carry[9] = s9 >> 21
-	s10 += carry[9]
-	s9 -= carry[9] << 21
-	carry[10] = s10 >> 21
-	s11 += carry[10]
-	s10 -= carry[10] << 21
-
-	s[0] = byte(s0 >> 0)
-	s[1] = byte(s0 >> 8)
-	s[2] = byte((s0 >> 16) | (s1 << 5))
-	s[3] = byte(s1 >> 3)
-	s[4] = byte(s1 >> 11)
-	s[5] = byte((s1 >> 19) | (s2 << 2))
-	s[6] = byte(s2 >> 6)
-	s[7] = byte((s2 >> 14) | (s3 << 7))
-	s[8] = byte(s3 >> 1)
-	s[9] = byte(s3 >> 9)
-	s[10] = byte((s3 >> 17) | (s4 << 4))
-	s[11] = byte(s4 >> 4)
-	s[12] = byte(s4 >> 12)
-	s[13] = byte((s4 >> 20) | (s5 << 1))
-	s[14] = byte(s5 >> 7)
-	s[15] = byte((s5 >> 15) | (s6 << 6))
-	s[16] = byte(s6 >> 2)
-	s[17] = byte(s6 >> 10)
-	s[18] = byte((s6 >> 18) | (s7 << 3))
-	s[19] = byte(s7 >> 5)
-	s[20] = byte(s7 >> 13)
-	s[21] = byte(s8 >> 0)
-	s[22] = byte(s8 >> 8)
-	s[23] = byte((s8 >> 16) | (s9 << 5))
-	s[24] = byte(s9 >> 3)
-	s[25] = byte(s9 >> 11)
-	s[26] = byte((s9 >> 19) | (s10 << 2))
-	s[27] = byte(s10 >> 6)
-	s[28] = byte((s10 >> 14) | (s11 << 7))
-	s[29] = byte(s11 >> 1)
-	s[30] = byte(s11 >> 9)
-	s[31] = byte(s11 >> 17)
-}
-
-// Input:
-//   s[0]+256*s[1]+...+256^63*s[63] = s
-//
-// Output:
-//   s[0]+256*s[1]+...+256^31*s[31] = s mod l
-//   where l = 2^252 + 27742317777372353535851937790883648493.
-func ScReduce(out *[32]byte, s *[64]byte) {
-	s0 := 2097151 & load3(s[:])
-	s1 := 2097151 & (load4(s[2:]) >> 5)
-	s2 := 2097151 & (load3(s[5:]) >> 2)
-	s3 := 2097151 & (load4(s[7:]) >> 7)
-	s4 := 2097151 & (load4(s[10:]) >> 4)
-	s5 := 2097151 & (load3(s[13:]) >> 1)
-	s6 := 2097151 & (load4(s[15:]) >> 6)
-	s7 := 2097151 & (load3(s[18:]) >> 3)
-	s8 := 2097151 & load3(s[21:])
-	s9 := 2097151 & (load4(s[23:]) >> 5)
-	s10 := 2097151 & (load3(s[26:]) >> 2)
-	s11 := 2097151 & (load4(s[28:]) >> 7)
-	s12 := 2097151 & (load4(s[31:]) >> 4)
-	s13 := 2097151 & (load3(s[34:]) >> 1)
-	s14 := 2097151 & (load4(s[36:]) >> 6)
-	s15 := 2097151 & (load3(s[39:]) >> 3)
-	s16 := 2097151 & load3(s[42:])
-	s17 := 2097151 & (load4(s[44:]) >> 5)
-	s18 := 2097151 & (load3(s[47:]) >> 2)
-	s19 := 2097151 & (load4(s[49:]) >> 7)
-	s20 := 2097151 & (load4(s[52:]) >> 4)
-	s21 := 2097151 & (load3(s[55:]) >> 1)
-	s22 := 2097151 & (load4(s[57:]) >> 6)
-	s23 := (load4(s[60:]) >> 3)
-
-	s11 += s23 * 666643
-	s12 += s23 * 470296
-	s13 += s23 * 654183
-	s14 -= s23 * 997805
-	s15 += s23 * 136657
-	s16 -= s23 * 683901
-	s23 = 0
-
-	s10 += s22 * 666643
-	s11 += s22 * 470296
-	s12 += s22 * 654183
-	s13 -= s22 * 997805
-	s14 += s22 * 136657
-	s15 -= s22 * 683901
-	s22 = 0
-
-	s9 += s21 * 666643
-	s10 += s21 * 470296
-	s11 += s21 * 654183
-	s12 -= s21 * 997805
-	s13 += s21 * 136657
-	s14 -= s21 * 683901
-	s21 = 0
-
-	s8 += s20 * 666643
-	s9 += s20 * 470296
-	s10 += s20 * 654183
-	s11 -= s20 * 997805
-	s12 += s20 * 136657
-	s13 -= s20 * 683901
-	s20 = 0
-
-	s7 += s19 * 666643
-	s8 += s19 * 470296
-	s9 += s19 * 654183
-	s10 -= s19 * 997805
-	s11 += s19 * 136657
-	s12 -= s19 * 683901
-	s19 = 0
-
-	s6 += s18 * 666643
-	s7 += s18 * 470296
-	s8 += s18 * 654183
-	s9 -= s18 * 997805
-	s10 += s18 * 136657
-	s11 -= s18 * 683901
-	s18 = 0
-
-	var carry [17]int64
-
-	carry[6] = (s6 + (1 << 20)) >> 21
-	s7 += carry[6]
-	s6 -= carry[6] << 21
-	carry[8] = (s8 + (1 << 20)) >> 21
-	s9 += carry[8]
-	s8 -= carry[8] << 21
-	carry[10] = (s10 + (1 << 20)) >> 21
-	s11 += carry[10]
-	s10 -= carry[10] << 21
-	carry[12] = (s12 + (1 << 20)) >> 21
-	s13 += carry[12]
-	s12 -= carry[12] << 21
-	carry[14] = (s14 + (1 << 20)) >> 21
-	s15 += carry[14]
-	s14 -= carry[14] << 21
-	carry[16] = (s16 + (1 << 20)) >> 21
-	s17 += carry[16]
-	s16 -= carry[16] << 21
-
-	carry[7] = (s7 + (1 << 20)) >> 21
-	s8 += carry[7]
-	s7 -= carry[7] << 21
-	carry[9] = (s9 + (1 << 20)) >> 21
-	s10 += carry[9]
-	s9 -= carry[9] << 21
-	carry[11] = (s11 + (1 << 20)) >> 21
-	s12 += carry[11]
-	s11 -= carry[11] << 21
-	carry[13] = (s13 + (1 << 20)) >> 21
-	s14 += carry[13]
-	s13 -= carry[13] << 21
-	carry[15] = (s15 + (1 << 20)) >> 21
-	s16 += carry[15]
-	s15 -= carry[15] << 21
-
-	s5 += s17 * 666643
-	s6 += s17 * 470296
-	s7 += s17 * 654183
-	s8 -= s17 * 997805
-	s9 += s17 * 136657
-	s10 -= s17 * 683901
-	s17 = 0
-
-	s4 += s16 * 666643
-	s5 += s16 * 470296
-	s6 += s16 * 654183
-	s7 -= s16 * 997805
-	s8 += s16 * 136657
-	s9 -= s16 * 683901
-	s16 = 0
-
-	s3 += s15 * 666643
-	s4 += s15 * 470296
-	s5 += s15 * 654183
-	s6 -= s15 * 997805
-	s7 += s15 * 136657
-	s8 -= s15 * 683901
-	s15 = 0
-
-	s2 += s14 * 666643
-	s3 += s14 * 470296
-	s4 += s14 * 654183
-	s5 -= s14 * 997805
-	s6 += s14 * 136657
-	s7 -= s14 * 683901
-	s14 = 0
-
-	s1 += s13 * 666643
-	s2 += s13 * 470296
-	s3 += s13 * 654183
-	s4 -= s13 * 997805
-	s5 += s13 * 136657
-	s6 -= s13 * 683901
-	s13 = 0
-
-	s0 += s12 * 666643
-	s1 += s12 * 470296
-	s2 += s12 * 654183
-	s3 -= s12 * 997805
-	s4 += s12 * 136657
-	s5 -= s12 * 683901
-	s12 = 0
-
-	carry[0] = (s0 + (1 << 20)) >> 21
-	s1 += carry[0]
-	s0 -= carry[0] << 21
-	carry[2] = (s2 + (1 << 20)) >> 21
-	s3 += carry[2]
-	s2 -= carry[2] << 21
-	carry[4] = (s4 + (1 << 20)) >> 21
-	s5 += carry[4]
-	s4 -= carry[4] << 21
-	carry[6] = (s6 + (1 << 20)) >> 21
-	s7 += carry[6]
-	s6 -= carry[6] << 21
-	carry[8] = (s8 + (1 << 20)) >> 21
-	s9 += carry[8]
-	s8 -= carry[8] << 21
-	carry[10] = (s10 + (1 << 20)) >> 21
-	s11 += carry[10]
-	s10 -= carry[10] << 21
-
-	carry[1] = (s1 + (1 << 20)) >> 21
-	s2 += carry[1]
-	s1 -= carry[1] << 21
-	carry[3] = (s3 + (1 << 20)) >> 21
-	s4 += carry[3]
-	s3 -= carry[3] << 21
-	carry[5] = (s5 + (1 << 20)) >> 21
-	s6 += carry[5]
-	s5 -= carry[5] << 21
-	carry[7] = (s7 + (1 << 20)) >> 21
-	s8 += carry[7]
-	s7 -= carry[7] << 21
-	carry[9] = (s9 + (1 << 20)) >> 21
-	s10 += carry[9]
-	s9 -= carry[9] << 21
-	carry[11] = (s11 + (1 << 20)) >> 21
-	s12 += carry[11]
-	s11 -= carry[11] << 21
-
-	s0 += s12 * 666643
-	s1 += s12 * 470296
-	s2 += s12 * 654183
-	s3 -= s12 * 997805
-	s4 += s12 * 136657
-	s5 -= s12 * 683901
-	s12 = 0
-
-	carry[0] = s0 >> 21
-	s1 += carry[0]
-	s0 -= carry[0] << 21
-	carry[1] = s1 >> 21
-	s2 += carry[1]
-	s1 -= carry[1] << 21
-	carry[2] = s2 >> 21
-	s3 += carry[2]
-	s2 -= carry[2] << 21
-	carry[3] = s3 >> 21
-	s4 += carry[3]
-	s3 -= carry[3] << 21
-	carry[4] = s4 >> 21
-	s5 += carry[4]
-	s4 -= carry[4] << 21
-	carry[5] = s5 >> 21
-	s6 += carry[5]
-	s5 -= carry[5] << 21
-	carry[6] = s6 >> 21
-	s7 += carry[6]
-	s6 -= carry[6] << 21
-	carry[7] = s7 >> 21
-	s8 += carry[7]
-	s7 -= carry[7] << 21
-	carry[8] = s8 >> 21
-	s9 += carry[8]
-	s8 -= carry[8] << 21
-	carry[9] = s9 >> 21
-	s10 += carry[9]
-	s9 -= carry[9] << 21
-	carry[10] = s10 >> 21
-	s11 += carry[10]
-	s10 -= carry[10] << 21
-	carry[11] = s11 >> 21
-	s12 += carry[11]
-	s11 -= carry[11] << 21
-
-	s0 += s12 * 666643
-	s1 += s12 * 470296
-	s2 += s12 * 654183
-	s3 -= s12 * 997805
-	s4 += s12 * 136657
-	s5 -= s12 * 683901
-	s12 = 0
-
-	carry[0] = s0 >> 21
-	s1 += carry[0]
-	s0 -= carry[0] << 21
-	carry[1] = s1 >> 21
-	s2 += carry[1]
-	s1 -= carry[1] << 21
-	carry[2] = s2 >> 21
-	s3 += carry[2]
-	s2 -= carry[2] << 21
-	carry[3] = s3 >> 21
-	s4 += carry[3]
-	s3 -= carry[3] << 21
-	carry[4] = s4 >> 21
-	s5 += carry[4]
-	s4 -= carry[4] << 21
-	carry[5] = s5 >> 21
-	s6 += carry[5]
-	s5 -= carry[5] << 21
-	carry[6] = s6 >> 21
-	s7 += carry[6]
-	s6 -= carry[6] << 21
-	carry[7] = s7 >> 21
-	s8 += carry[7]
-	s7 -= carry[7] << 21
-	carry[8] = s8 >> 21
-	s9 += carry[8]
-	s8 -= carry[8] << 21
-	carry[9] = s9 >> 21
-	s10 += carry[9]
-	s9 -= carry[9] << 21
-	carry[10] = s10 >> 21
-	s11 += carry[10]
-	s10 -= carry[10] << 21
-
-	out[0] = byte(s0 >> 0)
-	out[1] = byte(s0 >> 8)
-	out[2] = byte((s0 >> 16) | (s1 << 5))
-	out[3] = byte(s1 >> 3)
-	out[4] = byte(s1 >> 11)
-	out[5] = byte((s1 >> 19) | (s2 << 2))
-	out[6] = byte(s2 >> 6)
-	out[7] = byte((s2 >> 14) | (s3 << 7))
-	out[8] = byte(s3 >> 1)
-	out[9] = byte(s3 >> 9)
-	out[10] = byte((s3 >> 17) | (s4 << 4))
-	out[11] = byte(s4 >> 4)
-	out[12] = byte(s4 >> 12)
-	out[13] = byte((s4 >> 20) | (s5 << 1))
-	out[14] = byte(s5 >> 7)
-	out[15] = byte((s5 >> 15) | (s6 << 6))
-	out[16] = byte(s6 >> 2)
-	out[17] = byte(s6 >> 10)
-	out[18] = byte((s6 >> 18) | (s7 << 3))
-	out[19] = byte(s7 >> 5)
-	out[20] = byte(s7 >> 13)
-	out[21] = byte(s8 >> 0)
-	out[22] = byte(s8 >> 8)
-	out[23] = byte((s8 >> 16) | (s9 << 5))
-	out[24] = byte(s9 >> 3)
-	out[25] = byte(s9 >> 11)
-	out[26] = byte((s9 >> 19) | (s10 << 2))
-	out[27] = byte(s10 >> 6)
-	out[28] = byte((s10 >> 14) | (s11 << 7))
-	out[29] = byte(s11 >> 1)
-	out[30] = byte(s11 >> 9)
-	out[31] = byte(s11 >> 17)
-}
-
-// order is the order of Curve25519 in little-endian form.
-var order = [4]uint64{0x5812631a5cf5d3ed, 0x14def9dea2f79cd6, 0, 0x1000000000000000}
-
-// ScMinimal returns true if the given scalar is less than the order of the
-// curve.
-func ScMinimal(scalar *[32]byte) bool {
-	for i := 3; ; i-- {
-		v := binary.LittleEndian.Uint64(scalar[i*8:])
-		if v > order[i] {
-			return false
-		} else if v < order[i] {
-			break
-		} else if i == 0 {
-			return false
-		}
-	}
-
-	return true
-}
diff --git a/vendor/golang.org/x/crypto/go.mod b/vendor/golang.org/x/crypto/go.mod
index b8e07279f0..525ffa6a94 100644
--- a/vendor/golang.org/x/crypto/go.mod
+++ b/vendor/golang.org/x/crypto/go.mod
@@ -1,9 +1,11 @@
 module golang.org/x/crypto
 
-go 1.11
+go 1.17
 
 require (
-	golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3
-	golang.org/x/sys v0.0.0-20191026070338-33540a1f6037
-	golang.org/x/term v0.0.0-20201117132131-f5c789dd3221
+	golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2
+	golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1
+	golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1
 )
+
+require golang.org/x/text v0.3.6 // indirect
diff --git a/vendor/golang.org/x/crypto/go.sum b/vendor/golang.org/x/crypto/go.sum
new file mode 100644
index 0000000000..cccfa807ac
--- /dev/null
+++ b/vendor/golang.org/x/crypto/go.sum
@@ -0,0 +1,11 @@
+golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE=
+golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 h1:SrN+KX8Art/Sf4HNj6Zcz06G7VEz+7w9tdXTPOZ7+l4=
+golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
+golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
+golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
+golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
diff --git a/vendor/golang.org/x/crypto/hkdf/hkdf.go b/vendor/golang.org/x/crypto/hkdf/hkdf.go
new file mode 100644
index 0000000000..dda3f143be
--- /dev/null
+++ b/vendor/golang.org/x/crypto/hkdf/hkdf.go
@@ -0,0 +1,93 @@
+// Copyright 2014 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 hkdf implements the HMAC-based Extract-and-Expand Key Derivation
+// Function (HKDF) as defined in RFC 5869.
+//
+// HKDF is a cryptographic key derivation function (KDF) with the goal of
+// expanding limited input keying material into one or more cryptographically
+// strong secret keys.
+package hkdf // import "golang.org/x/crypto/hkdf"
+
+import (
+	"crypto/hmac"
+	"errors"
+	"hash"
+	"io"
+)
+
+// Extract generates a pseudorandom key for use with Expand from an input secret
+// and an optional independent salt.
+//
+// Only use this function if you need to reuse the extracted key with multiple
+// Expand invocations and different context values. Most common scenarios,
+// including the generation of multiple keys, should use New instead.
+func Extract(hash func() hash.Hash, secret, salt []byte) []byte {
+	if salt == nil {
+		salt = make([]byte, hash().Size())
+	}
+	extractor := hmac.New(hash, salt)
+	extractor.Write(secret)
+	return extractor.Sum(nil)
+}
+
+type hkdf struct {
+	expander hash.Hash
+	size     int
+
+	info    []byte
+	counter byte
+
+	prev []byte
+	buf  []byte
+}
+
+func (f *hkdf) Read(p []byte) (int, error) {
+	// Check whether enough data can be generated
+	need := len(p)
+	remains := len(f.buf) + int(255-f.counter+1)*f.size
+	if remains < need {
+		return 0, errors.New("hkdf: entropy limit reached")
+	}
+	// Read any leftover from the buffer
+	n := copy(p, f.buf)
+	p = p[n:]
+
+	// Fill the rest of the buffer
+	for len(p) > 0 {
+		f.expander.Reset()
+		f.expander.Write(f.prev)
+		f.expander.Write(f.info)
+		f.expander.Write([]byte{f.counter})
+		f.prev = f.expander.Sum(f.prev[:0])
+		f.counter++
+
+		// Copy the new batch into p
+		f.buf = f.prev
+		n = copy(p, f.buf)
+		p = p[n:]
+	}
+	// Save leftovers for next run
+	f.buf = f.buf[n:]
+
+	return need, nil
+}
+
+// Expand returns a Reader, from which keys can be read, using the given
+// pseudorandom key and optional context info, skipping the extraction step.
+//
+// The pseudorandomKey should have been generated by Extract, or be a uniformly
+// random or pseudorandom cryptographically strong key. See RFC 5869, Section
+// 3.3. Most common scenarios will want to use New instead.
+func Expand(hash func() hash.Hash, pseudorandomKey, info []byte) io.Reader {
+	expander := hmac.New(hash, pseudorandomKey)
+	return &hkdf{expander, expander.Size(), info, 1, nil, nil}
+}
+
+// New returns a Reader, from which keys can be read, using the given hash,
+// secret, salt and context info. Salt and info can be nil.
+func New(hash func() hash.Hash, secret, salt, info []byte) io.Reader {
+	prk := Extract(hash, secret, salt)
+	return Expand(hash, prk, info)
+}
diff --git a/vendor/golang.org/x/crypto/poly1305/bits_compat.go b/vendor/golang.org/x/crypto/internal/poly1305/bits_compat.go
similarity index 98%
rename from vendor/golang.org/x/crypto/poly1305/bits_compat.go
rename to vendor/golang.org/x/crypto/internal/poly1305/bits_compat.go
index 157a69f61b..45b5c966b2 100644
--- a/vendor/golang.org/x/crypto/poly1305/bits_compat.go
+++ b/vendor/golang.org/x/crypto/internal/poly1305/bits_compat.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !go1.13
 // +build !go1.13
 
 package poly1305
diff --git a/vendor/golang.org/x/crypto/poly1305/bits_go1.13.go b/vendor/golang.org/x/crypto/internal/poly1305/bits_go1.13.go
similarity index 96%
rename from vendor/golang.org/x/crypto/poly1305/bits_go1.13.go
rename to vendor/golang.org/x/crypto/internal/poly1305/bits_go1.13.go
index a0a185f0fc..ed52b3418a 100644
--- a/vendor/golang.org/x/crypto/poly1305/bits_go1.13.go
+++ b/vendor/golang.org/x/crypto/internal/poly1305/bits_go1.13.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build go1.13
 // +build go1.13
 
 package poly1305
diff --git a/vendor/golang.org/x/crypto/poly1305/mac_noasm.go b/vendor/golang.org/x/crypto/internal/poly1305/mac_noasm.go
similarity index 66%
rename from vendor/golang.org/x/crypto/poly1305/mac_noasm.go
rename to vendor/golang.org/x/crypto/internal/poly1305/mac_noasm.go
index d118f30ed5..f184b67d98 100644
--- a/vendor/golang.org/x/crypto/poly1305/mac_noasm.go
+++ b/vendor/golang.org/x/crypto/internal/poly1305/mac_noasm.go
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build !amd64,!ppc64le,!s390x gccgo purego
+//go:build (!amd64 && !ppc64le && !s390x) || !gc || purego
+// +build !amd64,!ppc64le,!s390x !gc purego
 
 package poly1305
 
diff --git a/vendor/golang.org/x/crypto/poly1305/poly1305.go b/vendor/golang.org/x/crypto/internal/poly1305/poly1305.go
similarity index 98%
rename from vendor/golang.org/x/crypto/poly1305/poly1305.go
rename to vendor/golang.org/x/crypto/internal/poly1305/poly1305.go
index 9d7a6af09f..4aaea810a2 100644
--- a/vendor/golang.org/x/crypto/poly1305/poly1305.go
+++ b/vendor/golang.org/x/crypto/internal/poly1305/poly1305.go
@@ -15,7 +15,7 @@
 // used with a fixed key in order to generate one-time keys from an nonce.
 // However, in this package AES isn't used and the one-time key is specified
 // directly.
-package poly1305 // import "golang.org/x/crypto/poly1305"
+package poly1305
 
 import "crypto/subtle"
 
diff --git a/vendor/golang.org/x/crypto/poly1305/sum_amd64.go b/vendor/golang.org/x/crypto/internal/poly1305/sum_amd64.go
similarity index 95%
rename from vendor/golang.org/x/crypto/poly1305/sum_amd64.go
rename to vendor/golang.org/x/crypto/internal/poly1305/sum_amd64.go
index 99e5a1d50e..6d522333f2 100644
--- a/vendor/golang.org/x/crypto/poly1305/sum_amd64.go
+++ b/vendor/golang.org/x/crypto/internal/poly1305/sum_amd64.go
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build !gccgo,!purego
+//go:build gc && !purego
+// +build gc,!purego
 
 package poly1305
 
diff --git a/vendor/golang.org/x/crypto/poly1305/sum_amd64.s b/vendor/golang.org/x/crypto/internal/poly1305/sum_amd64.s
similarity index 98%
rename from vendor/golang.org/x/crypto/poly1305/sum_amd64.s
rename to vendor/golang.org/x/crypto/internal/poly1305/sum_amd64.s
index 8d394a212e..1d74f0f881 100644
--- a/vendor/golang.org/x/crypto/poly1305/sum_amd64.s
+++ b/vendor/golang.org/x/crypto/internal/poly1305/sum_amd64.s
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build !gccgo,!purego
+//go:build gc && !purego
+// +build gc,!purego
 
 #include "textflag.h"
 
diff --git a/vendor/golang.org/x/crypto/poly1305/sum_generic.go b/vendor/golang.org/x/crypto/internal/poly1305/sum_generic.go
similarity index 100%
rename from vendor/golang.org/x/crypto/poly1305/sum_generic.go
rename to vendor/golang.org/x/crypto/internal/poly1305/sum_generic.go
diff --git a/vendor/golang.org/x/crypto/poly1305/sum_ppc64le.go b/vendor/golang.org/x/crypto/internal/poly1305/sum_ppc64le.go
similarity index 95%
rename from vendor/golang.org/x/crypto/poly1305/sum_ppc64le.go
rename to vendor/golang.org/x/crypto/internal/poly1305/sum_ppc64le.go
index 2e7a120b19..4a069941a6 100644
--- a/vendor/golang.org/x/crypto/poly1305/sum_ppc64le.go
+++ b/vendor/golang.org/x/crypto/internal/poly1305/sum_ppc64le.go
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build !gccgo,!purego
+//go:build gc && !purego
+// +build gc,!purego
 
 package poly1305
 
diff --git a/vendor/golang.org/x/crypto/poly1305/sum_ppc64le.s b/vendor/golang.org/x/crypto/internal/poly1305/sum_ppc64le.s
similarity index 94%
rename from vendor/golang.org/x/crypto/poly1305/sum_ppc64le.s
rename to vendor/golang.org/x/crypto/internal/poly1305/sum_ppc64le.s
index 4e02813879..58422aad23 100644
--- a/vendor/golang.org/x/crypto/poly1305/sum_ppc64le.s
+++ b/vendor/golang.org/x/crypto/internal/poly1305/sum_ppc64le.s
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build !gccgo,!purego
+//go:build gc && !purego
+// +build gc,!purego
 
 #include "textflag.h"
 
@@ -82,7 +83,7 @@ multiply:
 	BGE loop
 
 bytes_between_0_and_15:
-	CMP  $0, R5
+	CMP  R5, $0
 	BEQ  done
 	MOVD $0, R16 // h0
 	MOVD $0, R17 // h1
@@ -122,7 +123,7 @@ just1:
 	// Exactly 8
 	MOVD (R4), R16
 
-	CMP $0, R17
+	CMP R17, $0
 
 	// Check if we've already set R17; if not
 	// set 1 to indicate end of msg.
@@ -151,7 +152,7 @@ less4:
 	ADD   $2, R4
 
 less2:
-	CMP   $0, R5
+	CMP   R5, $0
 	BEQ   insert1
 	MOVBZ (R4), R21
 	SLD   R22, R21, R21
@@ -166,12 +167,12 @@ insert1:
 
 carry:
 	// Add new values to h0, h1, h2
-	ADDC R16, R8
-	ADDE R17, R9
-	ADDE $0, R10
-	MOVD $16, R5
-	ADD  R5, R4
-	BR   multiply
+	ADDC  R16, R8
+	ADDE  R17, R9
+	ADDZE R10, R10
+	MOVD  $16, R5
+	ADD   R5, R4
+	BR    multiply
 
 done:
 	// Save h0, h1, h2 in state
diff --git a/vendor/golang.org/x/crypto/poly1305/sum_s390x.go b/vendor/golang.org/x/crypto/internal/poly1305/sum_s390x.go
similarity index 97%
rename from vendor/golang.org/x/crypto/poly1305/sum_s390x.go
rename to vendor/golang.org/x/crypto/internal/poly1305/sum_s390x.go
index 958fedc079..62cc9f8470 100644
--- a/vendor/golang.org/x/crypto/poly1305/sum_s390x.go
+++ b/vendor/golang.org/x/crypto/internal/poly1305/sum_s390x.go
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build !gccgo,!purego
+//go:build gc && !purego
+// +build gc,!purego
 
 package poly1305
 
diff --git a/vendor/golang.org/x/crypto/poly1305/sum_s390x.s b/vendor/golang.org/x/crypto/internal/poly1305/sum_s390x.s
similarity index 99%
rename from vendor/golang.org/x/crypto/poly1305/sum_s390x.s
rename to vendor/golang.org/x/crypto/internal/poly1305/sum_s390x.s
index 0fa9ee6e0b..aa9e0494c9 100644
--- a/vendor/golang.org/x/crypto/poly1305/sum_s390x.s
+++ b/vendor/golang.org/x/crypto/internal/poly1305/sum_s390x.s
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build !gccgo,!purego
+//go:build gc && !purego
+// +build gc,!purego
 
 #include "textflag.h"
 
@@ -17,7 +18,7 @@
 // value. These limbs are, for the most part, zero extended and
 // placed into 64-bit vector register elements. Each vector
 // register is 128-bits wide and so holds 2 of these elements.
-// Using 26-bit limbs allows us plenty of headroom to accomodate
+// Using 26-bit limbs allows us plenty of headroom to accommodate
 // accumulations before and after multiplication without
 // overflowing either 32-bits (before multiplication) or 64-bits
 // (after multiplication).
diff --git a/vendor/golang.org/x/crypto/internal/subtle/aliasing.go b/vendor/golang.org/x/crypto/internal/subtle/aliasing.go
index f38797bfa1..4fad24f8dc 100644
--- a/vendor/golang.org/x/crypto/internal/subtle/aliasing.go
+++ b/vendor/golang.org/x/crypto/internal/subtle/aliasing.go
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build !appengine
+//go:build !purego
+// +build !purego
 
 // Package subtle implements functions that are often useful in cryptographic
 // code but require careful thought to use correctly.
diff --git a/vendor/golang.org/x/crypto/internal/subtle/aliasing_appengine.go b/vendor/golang.org/x/crypto/internal/subtle/aliasing_purego.go
similarity index 97%
rename from vendor/golang.org/x/crypto/internal/subtle/aliasing_appengine.go
rename to vendor/golang.org/x/crypto/internal/subtle/aliasing_purego.go
index 0cc4a8a642..80ccbed2c0 100644
--- a/vendor/golang.org/x/crypto/internal/subtle/aliasing_appengine.go
+++ b/vendor/golang.org/x/crypto/internal/subtle/aliasing_purego.go
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build appengine
+//go:build purego
+// +build purego
 
 // Package subtle implements functions that are often useful in cryptographic
 // code but require careful thought to use correctly.
diff --git a/vendor/golang.org/x/crypto/internal/wycheproof/README.md b/vendor/golang.org/x/crypto/internal/wycheproof/README.md
new file mode 100644
index 0000000000..8ae6c6c3d5
--- /dev/null
+++ b/vendor/golang.org/x/crypto/internal/wycheproof/README.md
@@ -0,0 +1,12 @@
+This package runs a set of the Wycheproof tests provided by
+https://github.com/google/wycheproof.
+
+The JSON test files live in
+https://github.com/google/wycheproof/tree/master/testvectors
+and are being fetched and cached at a pinned version every time
+these tests are run. To change the version of the wycheproof
+repository that is being used for testing, update wycheproofModVer.
+
+The structs for these tests are generated from the
+schemas provided in https://github.com/google/wycheproof/tree/master/schemas
+using https://github.com/a-h/generate.
\ No newline at end of file
diff --git a/vendor/golang.org/x/crypto/internal/wycheproof/internal/dsa/dsa.go b/vendor/golang.org/x/crypto/internal/wycheproof/internal/dsa/dsa.go
new file mode 100644
index 0000000000..3101dfc1c2
--- /dev/null
+++ b/vendor/golang.org/x/crypto/internal/wycheproof/internal/dsa/dsa.go
@@ -0,0 +1,33 @@
+// Copyright 2019 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 dsa provides an internal version of dsa.Verify
+// that is used for the Wycheproof tests.
+package dsa
+
+import (
+	"crypto/dsa"
+	"math/big"
+
+	"golang.org/x/crypto/cryptobyte"
+	"golang.org/x/crypto/cryptobyte/asn1"
+)
+
+// VerifyASN1 verifies the ASN1 encoded signature, sig, of hash using the
+// public key, pub. Its return value records whether the signature is valid.
+func VerifyASN1(pub *dsa.PublicKey, hash, sig []byte) bool {
+	var (
+		r, s  = &big.Int{}, &big.Int{}
+		inner cryptobyte.String
+	)
+	input := cryptobyte.String(sig)
+	if !input.ReadASN1(&inner, asn1.SEQUENCE) ||
+		!input.Empty() ||
+		!inner.ReadASN1Integer(r) ||
+		!inner.ReadASN1Integer(s) ||
+		!inner.Empty() {
+		return false
+	}
+	return dsa.Verify(pub, hash, r, s)
+}
diff --git a/vendor/golang.org/x/crypto/md4/md4.go b/vendor/golang.org/x/crypto/md4/md4.go
new file mode 100644
index 0000000000..59d3480693
--- /dev/null
+++ b/vendor/golang.org/x/crypto/md4/md4.go
@@ -0,0 +1,122 @@
+// Copyright 2009 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 md4 implements the MD4 hash algorithm as defined in RFC 1320.
+//
+// Deprecated: MD4 is cryptographically broken and should should only be used
+// where compatibility with legacy systems, not security, is the goal. Instead,
+// use a secure hash like SHA-256 (from crypto/sha256).
+package md4 // import "golang.org/x/crypto/md4"
+
+import (
+	"crypto"
+	"hash"
+)
+
+func init() {
+	crypto.RegisterHash(crypto.MD4, New)
+}
+
+// The size of an MD4 checksum in bytes.
+const Size = 16
+
+// The blocksize of MD4 in bytes.
+const BlockSize = 64
+
+const (
+	_Chunk = 64
+	_Init0 = 0x67452301
+	_Init1 = 0xEFCDAB89
+	_Init2 = 0x98BADCFE
+	_Init3 = 0x10325476
+)
+
+// digest represents the partial evaluation of a checksum.
+type digest struct {
+	s   [4]uint32
+	x   [_Chunk]byte
+	nx  int
+	len uint64
+}
+
+func (d *digest) Reset() {
+	d.s[0] = _Init0
+	d.s[1] = _Init1
+	d.s[2] = _Init2
+	d.s[3] = _Init3
+	d.nx = 0
+	d.len = 0
+}
+
+// New returns a new hash.Hash computing the MD4 checksum.
+func New() hash.Hash {
+	d := new(digest)
+	d.Reset()
+	return d
+}
+
+func (d *digest) Size() int { return Size }
+
+func (d *digest) BlockSize() int { return BlockSize }
+
+func (d *digest) Write(p []byte) (nn int, err error) {
+	nn = len(p)
+	d.len += uint64(nn)
+	if d.nx > 0 {
+		n := len(p)
+		if n > _Chunk-d.nx {
+			n = _Chunk - d.nx
+		}
+		for i := 0; i < n; i++ {
+			d.x[d.nx+i] = p[i]
+		}
+		d.nx += n
+		if d.nx == _Chunk {
+			_Block(d, d.x[0:])
+			d.nx = 0
+		}
+		p = p[n:]
+	}
+	n := _Block(d, p)
+	p = p[n:]
+	if len(p) > 0 {
+		d.nx = copy(d.x[:], p)
+	}
+	return
+}
+
+func (d0 *digest) Sum(in []byte) []byte {
+	// Make a copy of d0, so that caller can keep writing and summing.
+	d := new(digest)
+	*d = *d0
+
+	// Padding.  Add a 1 bit and 0 bits until 56 bytes mod 64.
+	len := d.len
+	var tmp [64]byte
+	tmp[0] = 0x80
+	if len%64 < 56 {
+		d.Write(tmp[0 : 56-len%64])
+	} else {
+		d.Write(tmp[0 : 64+56-len%64])
+	}
+
+	// Length in bits.
+	len <<= 3
+	for i := uint(0); i < 8; i++ {
+		tmp[i] = byte(len >> (8 * i))
+	}
+	d.Write(tmp[0:8])
+
+	if d.nx != 0 {
+		panic("d.nx != 0")
+	}
+
+	for _, s := range d.s {
+		in = append(in, byte(s>>0))
+		in = append(in, byte(s>>8))
+		in = append(in, byte(s>>16))
+		in = append(in, byte(s>>24))
+	}
+	return in
+}
diff --git a/vendor/golang.org/x/crypto/md4/md4block.go b/vendor/golang.org/x/crypto/md4/md4block.go
new file mode 100644
index 0000000000..3fed475f3f
--- /dev/null
+++ b/vendor/golang.org/x/crypto/md4/md4block.go
@@ -0,0 +1,89 @@
+// Copyright 2009 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.
+
+// MD4 block step.
+// In its own file so that a faster assembly or C version
+// can be substituted easily.
+
+package md4
+
+var shift1 = []uint{3, 7, 11, 19}
+var shift2 = []uint{3, 5, 9, 13}
+var shift3 = []uint{3, 9, 11, 15}
+
+var xIndex2 = []uint{0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15}
+var xIndex3 = []uint{0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15}
+
+func _Block(dig *digest, p []byte) int {
+	a := dig.s[0]
+	b := dig.s[1]
+	c := dig.s[2]
+	d := dig.s[3]
+	n := 0
+	var X [16]uint32
+	for len(p) >= _Chunk {
+		aa, bb, cc, dd := a, b, c, d
+
+		j := 0
+		for i := 0; i < 16; i++ {
+			X[i] = uint32(p[j]) | uint32(p[j+1])<<8 | uint32(p[j+2])<<16 | uint32(p[j+3])<<24
+			j += 4
+		}
+
+		// If this needs to be made faster in the future,
+		// the usual trick is to unroll each of these
+		// loops by a factor of 4; that lets you replace
+		// the shift[] lookups with constants and,
+		// with suitable variable renaming in each
+		// unrolled body, delete the a, b, c, d = d, a, b, c
+		// (or you can let the optimizer do the renaming).
+		//
+		// The index variables are uint so that % by a power
+		// of two can be optimized easily by a compiler.
+
+		// Round 1.
+		for i := uint(0); i < 16; i++ {
+			x := i
+			s := shift1[i%4]
+			f := ((c ^ d) & b) ^ d
+			a += f + X[x]
+			a = a<<s | a>>(32-s)
+			a, b, c, d = d, a, b, c
+		}
+
+		// Round 2.
+		for i := uint(0); i < 16; i++ {
+			x := xIndex2[i]
+			s := shift2[i%4]
+			g := (b & c) | (b & d) | (c & d)
+			a += g + X[x] + 0x5a827999
+			a = a<<s | a>>(32-s)
+			a, b, c, d = d, a, b, c
+		}
+
+		// Round 3.
+		for i := uint(0); i < 16; i++ {
+			x := xIndex3[i]
+			s := shift3[i%4]
+			h := b ^ c ^ d
+			a += h + X[x] + 0x6ed9eba1
+			a = a<<s | a>>(32-s)
+			a, b, c, d = d, a, b, c
+		}
+
+		a += aa
+		b += bb
+		c += cc
+		d += dd
+
+		p = p[_Chunk:]
+		n += _Chunk
+	}
+
+	dig.s[0] = a
+	dig.s[1] = b
+	dig.s[2] = c
+	dig.s[3] = d
+	return n
+}
diff --git a/vendor/golang.org/x/crypto/nacl/auth/auth.go b/vendor/golang.org/x/crypto/nacl/auth/auth.go
new file mode 100644
index 0000000000..1d588d5c1c
--- /dev/null
+++ b/vendor/golang.org/x/crypto/nacl/auth/auth.go
@@ -0,0 +1,58 @@
+// Copyright 2017 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 auth authenticates a message using a secret key.
+
+The Sum function, viewed as a function of the message for a uniform random
+key, is designed to meet the standard notion of unforgeability. This means
+that an attacker cannot find authenticators for any messages not authenticated
+by the sender, even if the attacker has adaptively influenced the messages
+authenticated by the sender. For a formal definition see, e.g., Section 2.4
+of Bellare, Kilian, and Rogaway, "The security of the cipher block chaining
+message authentication code," Journal of Computer and System Sciences 61 (2000),
+362–399; http://www-cse.ucsd.edu/~mihir/papers/cbc.html.
+
+auth does not make any promises regarding "strong" unforgeability; perhaps
+one valid authenticator can be converted into another valid authenticator for
+the same message. NaCl also does not make any promises regarding "truncated
+unforgeability."
+
+This package is interoperable with NaCl: https://nacl.cr.yp.to/auth.html.
+*/
+package auth
+
+import (
+	"crypto/hmac"
+	"crypto/sha512"
+)
+
+const (
+	// Size is the size, in bytes, of an authenticated digest.
+	Size = 32
+	// KeySize is the size, in bytes, of an authentication key.
+	KeySize = 32
+)
+
+// Sum generates an authenticator for m using a secret key and returns the
+// 32-byte digest.
+func Sum(m []byte, key *[KeySize]byte) *[Size]byte {
+	mac := hmac.New(sha512.New, key[:])
+	mac.Write(m)
+	out := new([Size]byte)
+	copy(out[:], mac.Sum(nil)[:Size])
+	return out
+}
+
+// Verify checks that digest is a valid authenticator of message m under the
+// given secret key. Verify does not leak timing information.
+func Verify(digest []byte, m []byte, key *[KeySize]byte) bool {
+	if len(digest) != Size {
+		return false
+	}
+	mac := hmac.New(sha512.New, key[:])
+	mac.Write(m)
+	expectedMAC := mac.Sum(nil) // first 256 bits of 512-bit sum
+	return hmac.Equal(digest, expectedMAC[:Size])
+}
diff --git a/vendor/golang.org/x/crypto/nacl/box/box.go b/vendor/golang.org/x/crypto/nacl/box/box.go
new file mode 100644
index 0000000000..7f3b830ee2
--- /dev/null
+++ b/vendor/golang.org/x/crypto/nacl/box/box.go
@@ -0,0 +1,182 @@
+// 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 box authenticates and encrypts small messages using public-key cryptography.
+
+Box uses Curve25519, XSalsa20 and Poly1305 to encrypt and authenticate
+messages. The length of messages is not hidden.
+
+It is the caller's responsibility to ensure the uniqueness of nonces—for
+example, by using nonce 1 for the first message, nonce 2 for the second
+message, etc. Nonces are long enough that randomly generated nonces have
+negligible risk of collision.
+
+Messages should be small because:
+
+1. The whole message needs to be held in memory to be processed.
+
+2. Using large messages pressures implementations on small machines to decrypt
+and process plaintext before authenticating it. This is very dangerous, and
+this API does not allow it, but a protocol that uses excessive message sizes
+might present some implementations with no other choice.
+
+3. Fixed overheads will be sufficiently amortised by messages as small as 8KB.
+
+4. Performance may be improved by working with messages that fit into data caches.
+
+Thus large amounts of data should be chunked so that each message is small.
+(Each message still needs a unique nonce.) If in doubt, 16KB is a reasonable
+chunk size.
+
+This package is interoperable with NaCl: https://nacl.cr.yp.to/box.html.
+Anonymous sealing/opening is an extension of NaCl defined by and interoperable
+with libsodium:
+https://libsodium.gitbook.io/doc/public-key_cryptography/sealed_boxes.
+*/
+package box // import "golang.org/x/crypto/nacl/box"
+
+import (
+	cryptorand "crypto/rand"
+	"io"
+
+	"golang.org/x/crypto/blake2b"
+	"golang.org/x/crypto/curve25519"
+	"golang.org/x/crypto/nacl/secretbox"
+	"golang.org/x/crypto/salsa20/salsa"
+)
+
+const (
+	// Overhead is the number of bytes of overhead when boxing a message.
+	Overhead = secretbox.Overhead
+
+	// AnonymousOverhead is the number of bytes of overhead when using anonymous
+	// sealed boxes.
+	AnonymousOverhead = Overhead + 32
+)
+
+// GenerateKey generates a new public/private key pair suitable for use with
+// Seal and Open.
+func GenerateKey(rand io.Reader) (publicKey, privateKey *[32]byte, err error) {
+	publicKey = new([32]byte)
+	privateKey = new([32]byte)
+	_, err = io.ReadFull(rand, privateKey[:])
+	if err != nil {
+		publicKey = nil
+		privateKey = nil
+		return
+	}
+
+	curve25519.ScalarBaseMult(publicKey, privateKey)
+	return
+}
+
+var zeros [16]byte
+
+// Precompute calculates the shared key between peersPublicKey and privateKey
+// and writes it to sharedKey. The shared key can be used with
+// OpenAfterPrecomputation and SealAfterPrecomputation to speed up processing
+// when using the same pair of keys repeatedly.
+func Precompute(sharedKey, peersPublicKey, privateKey *[32]byte) {
+	curve25519.ScalarMult(sharedKey, privateKey, peersPublicKey)
+	salsa.HSalsa20(sharedKey, &zeros, sharedKey, &salsa.Sigma)
+}
+
+// Seal appends an encrypted and authenticated copy of message to out, which
+// will be Overhead bytes longer than the original and must not overlap it. The
+// nonce must be unique for each distinct message for a given pair of keys.
+func Seal(out, message []byte, nonce *[24]byte, peersPublicKey, privateKey *[32]byte) []byte {
+	var sharedKey [32]byte
+	Precompute(&sharedKey, peersPublicKey, privateKey)
+	return secretbox.Seal(out, message, nonce, &sharedKey)
+}
+
+// SealAfterPrecomputation performs the same actions as Seal, but takes a
+// shared key as generated by Precompute.
+func SealAfterPrecomputation(out, message []byte, nonce *[24]byte, sharedKey *[32]byte) []byte {
+	return secretbox.Seal(out, message, nonce, sharedKey)
+}
+
+// Open authenticates and decrypts a box produced by Seal and appends the
+// message to out, which must not overlap box. The output will be Overhead
+// bytes smaller than box.
+func Open(out, box []byte, nonce *[24]byte, peersPublicKey, privateKey *[32]byte) ([]byte, bool) {
+	var sharedKey [32]byte
+	Precompute(&sharedKey, peersPublicKey, privateKey)
+	return secretbox.Open(out, box, nonce, &sharedKey)
+}
+
+// OpenAfterPrecomputation performs the same actions as Open, but takes a
+// shared key as generated by Precompute.
+func OpenAfterPrecomputation(out, box []byte, nonce *[24]byte, sharedKey *[32]byte) ([]byte, bool) {
+	return secretbox.Open(out, box, nonce, sharedKey)
+}
+
+// SealAnonymous appends an encrypted and authenticated copy of message to out,
+// which will be AnonymousOverhead bytes longer than the original and must not
+// overlap it. This differs from Seal in that the sender is not required to
+// provide a private key.
+func SealAnonymous(out, message []byte, recipient *[32]byte, rand io.Reader) ([]byte, error) {
+	if rand == nil {
+		rand = cryptorand.Reader
+	}
+	ephemeralPub, ephemeralPriv, err := GenerateKey(rand)
+	if err != nil {
+		return nil, err
+	}
+
+	var nonce [24]byte
+	if err := sealNonce(ephemeralPub, recipient, &nonce); err != nil {
+		return nil, err
+	}
+
+	if total := len(out) + AnonymousOverhead + len(message); cap(out) < total {
+		original := out
+		out = make([]byte, 0, total)
+		out = append(out, original...)
+	}
+	out = append(out, ephemeralPub[:]...)
+
+	return Seal(out, message, &nonce, recipient, ephemeralPriv), nil
+}
+
+// OpenAnonymous authenticates and decrypts a box produced by SealAnonymous and
+// appends the message to out, which must not overlap box. The output will be
+// AnonymousOverhead bytes smaller than box.
+func OpenAnonymous(out, box []byte, publicKey, privateKey *[32]byte) (message []byte, ok bool) {
+	if len(box) < AnonymousOverhead {
+		return nil, false
+	}
+
+	var ephemeralPub [32]byte
+	copy(ephemeralPub[:], box[:32])
+
+	var nonce [24]byte
+	if err := sealNonce(&ephemeralPub, publicKey, &nonce); err != nil {
+		return nil, false
+	}
+
+	return Open(out, box[32:], &nonce, &ephemeralPub, privateKey)
+}
+
+// sealNonce generates a 24 byte nonce that is a blake2b digest of the
+// ephemeral public key and the receiver's public key.
+func sealNonce(ephemeralPub, peersPublicKey *[32]byte, nonce *[24]byte) error {
+	h, err := blake2b.New(24, nil)
+	if err != nil {
+		return err
+	}
+
+	if _, err = h.Write(ephemeralPub[:]); err != nil {
+		return err
+	}
+
+	if _, err = h.Write(peersPublicKey[:]); err != nil {
+		return err
+	}
+
+	h.Sum(nonce[:0])
+
+	return nil
+}
diff --git a/vendor/golang.org/x/crypto/nacl/secretbox/secretbox.go b/vendor/golang.org/x/crypto/nacl/secretbox/secretbox.go
index a98d1bd45c..a2973e626f 100644
--- a/vendor/golang.org/x/crypto/nacl/secretbox/secretbox.go
+++ b/vendor/golang.org/x/crypto/nacl/secretbox/secretbox.go
@@ -35,8 +35,8 @@ This package is interoperable with NaCl: https://nacl.cr.yp.to/secretbox.html.
 package secretbox // import "golang.org/x/crypto/nacl/secretbox"
 
 import (
+	"golang.org/x/crypto/internal/poly1305"
 	"golang.org/x/crypto/internal/subtle"
-	"golang.org/x/crypto/poly1305"
 	"golang.org/x/crypto/salsa20/salsa"
 )
 
diff --git a/vendor/golang.org/x/crypto/ocsp/ocsp.go b/vendor/golang.org/x/crypto/ocsp/ocsp.go
index 9d3fffa8fe..96972aeaba 100644
--- a/vendor/golang.org/x/crypto/ocsp/ocsp.go
+++ b/vendor/golang.org/x/crypto/ocsp/ocsp.go
@@ -668,7 +668,7 @@ func CreateRequest(cert, issuer *x509.Certificate, opts *RequestOptions) ([]byte
 // The responder cert is used to populate the responder's name field, and the
 // certificate itself is provided alongside the OCSP response signature.
 //
-// The issuer cert is used to puplate the IssuerNameHash and IssuerKeyHash fields.
+// The issuer cert is used to populate the IssuerNameHash and IssuerKeyHash fields.
 //
 // The template is used to populate the SerialNumber, Status, RevokedAt,
 // RevocationReason, ThisUpdate, and NextUpdate fields.
diff --git a/vendor/golang.org/x/crypto/openpgp/armor/armor.go b/vendor/golang.org/x/crypto/openpgp/armor/armor.go
new file mode 100644
index 0000000000..ebc87876e6
--- /dev/null
+++ b/vendor/golang.org/x/crypto/openpgp/armor/armor.go
@@ -0,0 +1,230 @@
+// Copyright 2010 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 armor implements OpenPGP ASCII Armor, see RFC 4880. OpenPGP Armor is
+// very similar to PEM except that it has an additional CRC checksum.
+//
+// Deprecated: this package is unmaintained except for security fixes. New
+// applications should consider a more focused, modern alternative to OpenPGP
+// for their specific task. If you are required to interoperate with OpenPGP
+// systems and need a maintained package, consider a community fork.
+// See https://golang.org/issue/44226.
+package armor // import "golang.org/x/crypto/openpgp/armor"
+
+import (
+	"bufio"
+	"bytes"
+	"encoding/base64"
+	"golang.org/x/crypto/openpgp/errors"
+	"io"
+)
+
+// A Block represents an OpenPGP armored structure.
+//
+// The encoded form is:
+//    -----BEGIN Type-----
+//    Headers
+//
+//    base64-encoded Bytes
+//    '=' base64 encoded checksum
+//    -----END Type-----
+// where Headers is a possibly empty sequence of Key: Value lines.
+//
+// Since the armored data can be very large, this package presents a streaming
+// interface.
+type Block struct {
+	Type    string            // The type, taken from the preamble (i.e. "PGP SIGNATURE").
+	Header  map[string]string // Optional headers.
+	Body    io.Reader         // A Reader from which the contents can be read
+	lReader lineReader
+	oReader openpgpReader
+}
+
+var ArmorCorrupt error = errors.StructuralError("armor invalid")
+
+const crc24Init = 0xb704ce
+const crc24Poly = 0x1864cfb
+const crc24Mask = 0xffffff
+
+// crc24 calculates the OpenPGP checksum as specified in RFC 4880, section 6.1
+func crc24(crc uint32, d []byte) uint32 {
+	for _, b := range d {
+		crc ^= uint32(b) << 16
+		for i := 0; i < 8; i++ {
+			crc <<= 1
+			if crc&0x1000000 != 0 {
+				crc ^= crc24Poly
+			}
+		}
+	}
+	return crc
+}
+
+var armorStart = []byte("-----BEGIN ")
+var armorEnd = []byte("-----END ")
+var armorEndOfLine = []byte("-----")
+
+// lineReader wraps a line based reader. It watches for the end of an armor
+// block and records the expected CRC value.
+type lineReader struct {
+	in     *bufio.Reader
+	buf    []byte
+	eof    bool
+	crc    uint32
+	crcSet bool
+}
+
+func (l *lineReader) Read(p []byte) (n int, err error) {
+	if l.eof {
+		return 0, io.EOF
+	}
+
+	if len(l.buf) > 0 {
+		n = copy(p, l.buf)
+		l.buf = l.buf[n:]
+		return
+	}
+
+	line, isPrefix, err := l.in.ReadLine()
+	if err != nil {
+		return
+	}
+	if isPrefix {
+		return 0, ArmorCorrupt
+	}
+
+	if bytes.HasPrefix(line, armorEnd) {
+		l.eof = true
+		return 0, io.EOF
+	}
+
+	if len(line) == 5 && line[0] == '=' {
+		// This is the checksum line
+		var expectedBytes [3]byte
+		var m int
+		m, err = base64.StdEncoding.Decode(expectedBytes[0:], line[1:])
+		if m != 3 || err != nil {
+			return
+		}
+		l.crc = uint32(expectedBytes[0])<<16 |
+			uint32(expectedBytes[1])<<8 |
+			uint32(expectedBytes[2])
+
+		line, _, err = l.in.ReadLine()
+		if err != nil && err != io.EOF {
+			return
+		}
+		if !bytes.HasPrefix(line, armorEnd) {
+			return 0, ArmorCorrupt
+		}
+
+		l.eof = true
+		l.crcSet = true
+		return 0, io.EOF
+	}
+
+	if len(line) > 96 {
+		return 0, ArmorCorrupt
+	}
+
+	n = copy(p, line)
+	bytesToSave := len(line) - n
+	if bytesToSave > 0 {
+		if cap(l.buf) < bytesToSave {
+			l.buf = make([]byte, 0, bytesToSave)
+		}
+		l.buf = l.buf[0:bytesToSave]
+		copy(l.buf, line[n:])
+	}
+
+	return
+}
+
+// openpgpReader passes Read calls to the underlying base64 decoder, but keeps
+// a running CRC of the resulting data and checks the CRC against the value
+// found by the lineReader at EOF.
+type openpgpReader struct {
+	lReader    *lineReader
+	b64Reader  io.Reader
+	currentCRC uint32
+}
+
+func (r *openpgpReader) Read(p []byte) (n int, err error) {
+	n, err = r.b64Reader.Read(p)
+	r.currentCRC = crc24(r.currentCRC, p[:n])
+
+	if err == io.EOF && r.lReader.crcSet && r.lReader.crc != uint32(r.currentCRC&crc24Mask) {
+		return 0, ArmorCorrupt
+	}
+
+	return
+}
+
+// Decode reads a PGP armored block from the given Reader. It will ignore
+// leading garbage. If it doesn't find a block, it will return nil, io.EOF. The
+// given Reader is not usable after calling this function: an arbitrary amount
+// of data may have been read past the end of the block.
+func Decode(in io.Reader) (p *Block, err error) {
+	r := bufio.NewReaderSize(in, 100)
+	var line []byte
+	ignoreNext := false
+
+TryNextBlock:
+	p = nil
+
+	// Skip leading garbage
+	for {
+		ignoreThis := ignoreNext
+		line, ignoreNext, err = r.ReadLine()
+		if err != nil {
+			return
+		}
+		if ignoreNext || ignoreThis {
+			continue
+		}
+		line = bytes.TrimSpace(line)
+		if len(line) > len(armorStart)+len(armorEndOfLine) && bytes.HasPrefix(line, armorStart) {
+			break
+		}
+	}
+
+	p = new(Block)
+	p.Type = string(line[len(armorStart) : len(line)-len(armorEndOfLine)])
+	p.Header = make(map[string]string)
+	nextIsContinuation := false
+	var lastKey string
+
+	// Read headers
+	for {
+		isContinuation := nextIsContinuation
+		line, nextIsContinuation, err = r.ReadLine()
+		if err != nil {
+			p = nil
+			return
+		}
+		if isContinuation {
+			p.Header[lastKey] += string(line)
+			continue
+		}
+		line = bytes.TrimSpace(line)
+		if len(line) == 0 {
+			break
+		}
+
+		i := bytes.Index(line, []byte(": "))
+		if i == -1 {
+			goto TryNextBlock
+		}
+		lastKey = string(line[:i])
+		p.Header[lastKey] = string(line[i+2:])
+	}
+
+	p.lReader.in = r
+	p.oReader.currentCRC = crc24Init
+	p.oReader.lReader = &p.lReader
+	p.oReader.b64Reader = base64.NewDecoder(base64.StdEncoding, &p.lReader)
+	p.Body = &p.oReader
+
+	return
+}
diff --git a/vendor/golang.org/x/crypto/openpgp/armor/encode.go b/vendor/golang.org/x/crypto/openpgp/armor/encode.go
new file mode 100644
index 0000000000..6f07582c37
--- /dev/null
+++ b/vendor/golang.org/x/crypto/openpgp/armor/encode.go
@@ -0,0 +1,160 @@
+// Copyright 2010 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 armor
+
+import (
+	"encoding/base64"
+	"io"
+)
+
+var armorHeaderSep = []byte(": ")
+var blockEnd = []byte("\n=")
+var newline = []byte("\n")
+var armorEndOfLineOut = []byte("-----\n")
+
+// writeSlices writes its arguments to the given Writer.
+func writeSlices(out io.Writer, slices ...[]byte) (err error) {
+	for _, s := range slices {
+		_, err = out.Write(s)
+		if err != nil {
+			return err
+		}
+	}
+	return
+}
+
+// lineBreaker breaks data across several lines, all of the same byte length
+// (except possibly the last). Lines are broken with a single '\n'.
+type lineBreaker struct {
+	lineLength  int
+	line        []byte
+	used        int
+	out         io.Writer
+	haveWritten bool
+}
+
+func newLineBreaker(out io.Writer, lineLength int) *lineBreaker {
+	return &lineBreaker{
+		lineLength: lineLength,
+		line:       make([]byte, lineLength),
+		used:       0,
+		out:        out,
+	}
+}
+
+func (l *lineBreaker) Write(b []byte) (n int, err error) {
+	n = len(b)
+
+	if n == 0 {
+		return
+	}
+
+	if l.used == 0 && l.haveWritten {
+		_, err = l.out.Write([]byte{'\n'})
+		if err != nil {
+			return
+		}
+	}
+
+	if l.used+len(b) < l.lineLength {
+		l.used += copy(l.line[l.used:], b)
+		return
+	}
+
+	l.haveWritten = true
+	_, err = l.out.Write(l.line[0:l.used])
+	if err != nil {
+		return
+	}
+	excess := l.lineLength - l.used
+	l.used = 0
+
+	_, err = l.out.Write(b[0:excess])
+	if err != nil {
+		return
+	}
+
+	_, err = l.Write(b[excess:])
+	return
+}
+
+func (l *lineBreaker) Close() (err error) {
+	if l.used > 0 {
+		_, err = l.out.Write(l.line[0:l.used])
+		if err != nil {
+			return
+		}
+	}
+
+	return
+}
+
+// encoding keeps track of a running CRC24 over the data which has been written
+// to it and outputs a OpenPGP checksum when closed, followed by an armor
+// trailer.
+//
+// It's built into a stack of io.Writers:
+//    encoding -> base64 encoder -> lineBreaker -> out
+type encoding struct {
+	out       io.Writer
+	breaker   *lineBreaker
+	b64       io.WriteCloser
+	crc       uint32
+	blockType []byte
+}
+
+func (e *encoding) Write(data []byte) (n int, err error) {
+	e.crc = crc24(e.crc, data)
+	return e.b64.Write(data)
+}
+
+func (e *encoding) Close() (err error) {
+	err = e.b64.Close()
+	if err != nil {
+		return
+	}
+	e.breaker.Close()
+
+	var checksumBytes [3]byte
+	checksumBytes[0] = byte(e.crc >> 16)
+	checksumBytes[1] = byte(e.crc >> 8)
+	checksumBytes[2] = byte(e.crc)
+
+	var b64ChecksumBytes [4]byte
+	base64.StdEncoding.Encode(b64ChecksumBytes[:], checksumBytes[:])
+
+	return writeSlices(e.out, blockEnd, b64ChecksumBytes[:], newline, armorEnd, e.blockType, armorEndOfLine)
+}
+
+// Encode returns a WriteCloser which will encode the data written to it in
+// OpenPGP armor.
+func Encode(out io.Writer, blockType string, headers map[string]string) (w io.WriteCloser, err error) {
+	bType := []byte(blockType)
+	err = writeSlices(out, armorStart, bType, armorEndOfLineOut)
+	if err != nil {
+		return
+	}
+
+	for k, v := range headers {
+		err = writeSlices(out, []byte(k), armorHeaderSep, []byte(v), newline)
+		if err != nil {
+			return
+		}
+	}
+
+	_, err = out.Write(newline)
+	if err != nil {
+		return
+	}
+
+	e := &encoding{
+		out:       out,
+		breaker:   newLineBreaker(out, 64),
+		crc:       crc24Init,
+		blockType: bType,
+	}
+	e.b64 = base64.NewEncoder(base64.StdEncoding, e.breaker)
+	return e, nil
+}
diff --git a/vendor/golang.org/x/crypto/openpgp/canonical_text.go b/vendor/golang.org/x/crypto/openpgp/canonical_text.go
new file mode 100644
index 0000000000..e601e389f1
--- /dev/null
+++ b/vendor/golang.org/x/crypto/openpgp/canonical_text.go
@@ -0,0 +1,59 @@
+// Copyright 2011 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 openpgp
+
+import "hash"
+
+// NewCanonicalTextHash reformats text written to it into the canonical
+// form and then applies the hash h.  See RFC 4880, section 5.2.1.
+func NewCanonicalTextHash(h hash.Hash) hash.Hash {
+	return &canonicalTextHash{h, 0}
+}
+
+type canonicalTextHash struct {
+	h hash.Hash
+	s int
+}
+
+var newline = []byte{'\r', '\n'}
+
+func (cth *canonicalTextHash) Write(buf []byte) (int, error) {
+	start := 0
+
+	for i, c := range buf {
+		switch cth.s {
+		case 0:
+			if c == '\r' {
+				cth.s = 1
+			} else if c == '\n' {
+				cth.h.Write(buf[start:i])
+				cth.h.Write(newline)
+				start = i + 1
+			}
+		case 1:
+			cth.s = 0
+		}
+	}
+
+	cth.h.Write(buf[start:])
+	return len(buf), nil
+}
+
+func (cth *canonicalTextHash) Sum(in []byte) []byte {
+	return cth.h.Sum(in)
+}
+
+func (cth *canonicalTextHash) Reset() {
+	cth.h.Reset()
+	cth.s = 0
+}
+
+func (cth *canonicalTextHash) Size() int {
+	return cth.h.Size()
+}
+
+func (cth *canonicalTextHash) BlockSize() int {
+	return cth.h.BlockSize()
+}
diff --git a/vendor/golang.org/x/crypto/openpgp/clearsign/clearsign.go b/vendor/golang.org/x/crypto/openpgp/clearsign/clearsign.go
new file mode 100644
index 0000000000..644b2e078b
--- /dev/null
+++ b/vendor/golang.org/x/crypto/openpgp/clearsign/clearsign.go
@@ -0,0 +1,424 @@
+// 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 clearsign generates and processes OpenPGP, clear-signed data. See
+// RFC 4880, section 7.
+//
+// Clearsigned messages are cryptographically signed, but the contents of the
+// message are kept in plaintext so that it can be read without special tools.
+//
+// Deprecated: this package is unmaintained except for security fixes. New
+// applications should consider a more focused, modern alternative to OpenPGP
+// for their specific task. If you are required to interoperate with OpenPGP
+// systems and need a maintained package, consider a community fork.
+// See https://golang.org/issue/44226.
+package clearsign // import "golang.org/x/crypto/openpgp/clearsign"
+
+import (
+	"bufio"
+	"bytes"
+	"crypto"
+	"fmt"
+	"hash"
+	"io"
+	"net/textproto"
+	"strconv"
+	"strings"
+
+	"golang.org/x/crypto/openpgp/armor"
+	"golang.org/x/crypto/openpgp/errors"
+	"golang.org/x/crypto/openpgp/packet"
+)
+
+// A Block represents a clearsigned message. A signature on a Block can
+// be checked by passing Bytes into openpgp.CheckDetachedSignature.
+type Block struct {
+	Headers          textproto.MIMEHeader // Optional unverified Hash headers
+	Plaintext        []byte               // The original message text
+	Bytes            []byte               // The signed message
+	ArmoredSignature *armor.Block         // The signature block
+}
+
+// start is the marker which denotes the beginning of a clearsigned message.
+var start = []byte("\n-----BEGIN PGP SIGNED MESSAGE-----")
+
+// dashEscape is prefixed to any lines that begin with a hyphen so that they
+// can't be confused with endText.
+var dashEscape = []byte("- ")
+
+// endText is a marker which denotes the end of the message and the start of
+// an armored signature.
+var endText = []byte("-----BEGIN PGP SIGNATURE-----")
+
+// end is a marker which denotes the end of the armored signature.
+var end = []byte("\n-----END PGP SIGNATURE-----")
+
+var crlf = []byte("\r\n")
+var lf = byte('\n')
+
+// getLine returns the first \r\n or \n delineated line from the given byte
+// array. The line does not include the \r\n or \n. The remainder of the byte
+// array (also not including the new line bytes) is also returned and this will
+// always be smaller than the original argument.
+func getLine(data []byte) (line, rest []byte) {
+	i := bytes.Index(data, []byte{'\n'})
+	var j int
+	if i < 0 {
+		i = len(data)
+		j = i
+	} else {
+		j = i + 1
+		if i > 0 && data[i-1] == '\r' {
+			i--
+		}
+	}
+	return data[0:i], data[j:]
+}
+
+// Decode finds the first clearsigned message in data and returns it, as well as
+// the suffix of data which remains after the message. Any prefix data is
+// discarded.
+//
+// If no message is found, or if the message is invalid, Decode returns nil and
+// the whole data slice. The only allowed header type is Hash, and it is not
+// verified against the signature hash.
+func Decode(data []byte) (b *Block, rest []byte) {
+	// start begins with a newline. However, at the very beginning of
+	// the byte array, we'll accept the start string without it.
+	rest = data
+	if bytes.HasPrefix(data, start[1:]) {
+		rest = rest[len(start)-1:]
+	} else if i := bytes.Index(data, start); i >= 0 {
+		rest = rest[i+len(start):]
+	} else {
+		return nil, data
+	}
+
+	// Consume the start line and check it does not have a suffix.
+	suffix, rest := getLine(rest)
+	if len(suffix) != 0 {
+		return nil, data
+	}
+
+	var line []byte
+	b = &Block{
+		Headers: make(textproto.MIMEHeader),
+	}
+
+	// Next come a series of header lines.
+	for {
+		// This loop terminates because getLine's second result is
+		// always smaller than its argument.
+		if len(rest) == 0 {
+			return nil, data
+		}
+		// An empty line marks the end of the headers.
+		if line, rest = getLine(rest); len(line) == 0 {
+			break
+		}
+
+		// Reject headers with control or Unicode characters.
+		if i := bytes.IndexFunc(line, func(r rune) bool {
+			return r < 0x20 || r > 0x7e
+		}); i != -1 {
+			return nil, data
+		}
+
+		i := bytes.Index(line, []byte{':'})
+		if i == -1 {
+			return nil, data
+		}
+
+		key, val := string(line[0:i]), string(line[i+1:])
+		key = strings.TrimSpace(key)
+		if key != "Hash" {
+			return nil, data
+		}
+		val = strings.TrimSpace(val)
+		b.Headers.Add(key, val)
+	}
+
+	firstLine := true
+	for {
+		start := rest
+
+		line, rest = getLine(rest)
+		if len(line) == 0 && len(rest) == 0 {
+			// No armored data was found, so this isn't a complete message.
+			return nil, data
+		}
+		if bytes.Equal(line, endText) {
+			// Back up to the start of the line because armor expects to see the
+			// header line.
+			rest = start
+			break
+		}
+
+		// The final CRLF isn't included in the hash so we don't write it until
+		// we've seen the next line.
+		if firstLine {
+			firstLine = false
+		} else {
+			b.Bytes = append(b.Bytes, crlf...)
+		}
+
+		if bytes.HasPrefix(line, dashEscape) {
+			line = line[2:]
+		}
+		line = bytes.TrimRight(line, " \t")
+		b.Bytes = append(b.Bytes, line...)
+
+		b.Plaintext = append(b.Plaintext, line...)
+		b.Plaintext = append(b.Plaintext, lf)
+	}
+
+	// We want to find the extent of the armored data (including any newlines at
+	// the end).
+	i := bytes.Index(rest, end)
+	if i == -1 {
+		return nil, data
+	}
+	i += len(end)
+	for i < len(rest) && (rest[i] == '\r' || rest[i] == '\n') {
+		i++
+	}
+	armored := rest[:i]
+	rest = rest[i:]
+
+	var err error
+	b.ArmoredSignature, err = armor.Decode(bytes.NewBuffer(armored))
+	if err != nil {
+		return nil, data
+	}
+
+	return b, rest
+}
+
+// A dashEscaper is an io.WriteCloser which processes the body of a clear-signed
+// message. The clear-signed message is written to buffered and a hash, suitable
+// for signing, is maintained in h.
+//
+// When closed, an armored signature is created and written to complete the
+// message.
+type dashEscaper struct {
+	buffered *bufio.Writer
+	hashers  []hash.Hash // one per key in privateKeys
+	hashType crypto.Hash
+	toHash   io.Writer // writes to all the hashes in hashers
+
+	atBeginningOfLine bool
+	isFirstLine       bool
+
+	whitespace []byte
+	byteBuf    []byte // a one byte buffer to save allocations
+
+	privateKeys []*packet.PrivateKey
+	config      *packet.Config
+}
+
+func (d *dashEscaper) Write(data []byte) (n int, err error) {
+	for _, b := range data {
+		d.byteBuf[0] = b
+
+		if d.atBeginningOfLine {
+			// The final CRLF isn't included in the hash so we have to wait
+			// until this point (the start of the next line) before writing it.
+			if !d.isFirstLine {
+				d.toHash.Write(crlf)
+			}
+			d.isFirstLine = false
+		}
+
+		// Any whitespace at the end of the line has to be removed so we
+		// buffer it until we find out whether there's more on this line.
+		if b == ' ' || b == '\t' || b == '\r' {
+			d.whitespace = append(d.whitespace, b)
+			d.atBeginningOfLine = false
+			continue
+		}
+
+		if d.atBeginningOfLine {
+			// At the beginning of a line, hyphens have to be escaped.
+			if b == '-' {
+				// The signature isn't calculated over the dash-escaped text so
+				// the escape is only written to buffered.
+				if _, err = d.buffered.Write(dashEscape); err != nil {
+					return
+				}
+				d.toHash.Write(d.byteBuf)
+				d.atBeginningOfLine = false
+			} else if b == '\n' {
+				// Nothing to do because we delay writing CRLF to the hash.
+			} else {
+				d.toHash.Write(d.byteBuf)
+				d.atBeginningOfLine = false
+			}
+			if err = d.buffered.WriteByte(b); err != nil {
+				return
+			}
+		} else {
+			if b == '\n' {
+				// We got a raw \n. Drop any trailing whitespace and write a
+				// CRLF.
+				d.whitespace = d.whitespace[:0]
+				// We delay writing CRLF to the hash until the start of the
+				// next line.
+				if err = d.buffered.WriteByte(b); err != nil {
+					return
+				}
+				d.atBeginningOfLine = true
+			} else {
+				// Any buffered whitespace wasn't at the end of the line so
+				// we need to write it out.
+				if len(d.whitespace) > 0 {
+					d.toHash.Write(d.whitespace)
+					if _, err = d.buffered.Write(d.whitespace); err != nil {
+						return
+					}
+					d.whitespace = d.whitespace[:0]
+				}
+				d.toHash.Write(d.byteBuf)
+				if err = d.buffered.WriteByte(b); err != nil {
+					return
+				}
+			}
+		}
+	}
+
+	n = len(data)
+	return
+}
+
+func (d *dashEscaper) Close() (err error) {
+	if !d.atBeginningOfLine {
+		if err = d.buffered.WriteByte(lf); err != nil {
+			return
+		}
+	}
+
+	out, err := armor.Encode(d.buffered, "PGP SIGNATURE", nil)
+	if err != nil {
+		return
+	}
+
+	t := d.config.Now()
+	for i, k := range d.privateKeys {
+		sig := new(packet.Signature)
+		sig.SigType = packet.SigTypeText
+		sig.PubKeyAlgo = k.PubKeyAlgo
+		sig.Hash = d.hashType
+		sig.CreationTime = t
+		sig.IssuerKeyId = &k.KeyId
+
+		if err = sig.Sign(d.hashers[i], k, d.config); err != nil {
+			return
+		}
+		if err = sig.Serialize(out); err != nil {
+			return
+		}
+	}
+
+	if err = out.Close(); err != nil {
+		return
+	}
+	if err = d.buffered.Flush(); err != nil {
+		return
+	}
+	return
+}
+
+// Encode returns a WriteCloser which will clear-sign a message with privateKey
+// and write it to w. If config is nil, sensible defaults are used.
+func Encode(w io.Writer, privateKey *packet.PrivateKey, config *packet.Config) (plaintext io.WriteCloser, err error) {
+	return EncodeMulti(w, []*packet.PrivateKey{privateKey}, config)
+}
+
+// EncodeMulti returns a WriteCloser which will clear-sign a message with all the
+// private keys indicated and write it to w. If config is nil, sensible defaults
+// are used.
+func EncodeMulti(w io.Writer, privateKeys []*packet.PrivateKey, config *packet.Config) (plaintext io.WriteCloser, err error) {
+	for _, k := range privateKeys {
+		if k.Encrypted {
+			return nil, errors.InvalidArgumentError(fmt.Sprintf("signing key %s is encrypted", k.KeyIdString()))
+		}
+	}
+
+	hashType := config.Hash()
+	name := nameOfHash(hashType)
+	if len(name) == 0 {
+		return nil, errors.UnsupportedError("unknown hash type: " + strconv.Itoa(int(hashType)))
+	}
+
+	if !hashType.Available() {
+		return nil, errors.UnsupportedError("unsupported hash type: " + strconv.Itoa(int(hashType)))
+	}
+	var hashers []hash.Hash
+	var ws []io.Writer
+	for range privateKeys {
+		h := hashType.New()
+		hashers = append(hashers, h)
+		ws = append(ws, h)
+	}
+	toHash := io.MultiWriter(ws...)
+
+	buffered := bufio.NewWriter(w)
+	// start has a \n at the beginning that we don't want here.
+	if _, err = buffered.Write(start[1:]); err != nil {
+		return
+	}
+	if err = buffered.WriteByte(lf); err != nil {
+		return
+	}
+	if _, err = buffered.WriteString("Hash: "); err != nil {
+		return
+	}
+	if _, err = buffered.WriteString(name); err != nil {
+		return
+	}
+	if err = buffered.WriteByte(lf); err != nil {
+		return
+	}
+	if err = buffered.WriteByte(lf); err != nil {
+		return
+	}
+
+	plaintext = &dashEscaper{
+		buffered: buffered,
+		hashers:  hashers,
+		hashType: hashType,
+		toHash:   toHash,
+
+		atBeginningOfLine: true,
+		isFirstLine:       true,
+
+		byteBuf: make([]byte, 1),
+
+		privateKeys: privateKeys,
+		config:      config,
+	}
+
+	return
+}
+
+// nameOfHash returns the OpenPGP name for the given hash, or the empty string
+// if the name isn't known. See RFC 4880, section 9.4.
+func nameOfHash(h crypto.Hash) string {
+	switch h {
+	case crypto.MD5:
+		return "MD5"
+	case crypto.SHA1:
+		return "SHA1"
+	case crypto.RIPEMD160:
+		return "RIPEMD160"
+	case crypto.SHA224:
+		return "SHA224"
+	case crypto.SHA256:
+		return "SHA256"
+	case crypto.SHA384:
+		return "SHA384"
+	case crypto.SHA512:
+		return "SHA512"
+	}
+	return ""
+}
diff --git a/vendor/golang.org/x/crypto/openpgp/elgamal/elgamal.go b/vendor/golang.org/x/crypto/openpgp/elgamal/elgamal.go
new file mode 100644
index 0000000000..84396a0896
--- /dev/null
+++ b/vendor/golang.org/x/crypto/openpgp/elgamal/elgamal.go
@@ -0,0 +1,130 @@
+// Copyright 2011 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 elgamal implements ElGamal encryption, suitable for OpenPGP,
+// as specified in "A Public-Key Cryptosystem and a Signature Scheme Based on
+// Discrete Logarithms," IEEE Transactions on Information Theory, v. IT-31,
+// n. 4, 1985, pp. 469-472.
+//
+// This form of ElGamal embeds PKCS#1 v1.5 padding, which may make it
+// unsuitable for other protocols. RSA should be used in preference in any
+// case.
+//
+// Deprecated: this package was only provided to support ElGamal encryption in
+// OpenPGP. The golang.org/x/crypto/openpgp package is now deprecated (see
+// https://golang.org/issue/44226), and ElGamal in the OpenPGP ecosystem has
+// compatibility and security issues (see https://eprint.iacr.org/2021/923).
+// Moreover, this package doesn't protect against side-channel attacks.
+package elgamal // import "golang.org/x/crypto/openpgp/elgamal"
+
+import (
+	"crypto/rand"
+	"crypto/subtle"
+	"errors"
+	"io"
+	"math/big"
+)
+
+// PublicKey represents an ElGamal public key.
+type PublicKey struct {
+	G, P, Y *big.Int
+}
+
+// PrivateKey represents an ElGamal private key.
+type PrivateKey struct {
+	PublicKey
+	X *big.Int
+}
+
+// Encrypt encrypts the given message to the given public key. The result is a
+// pair of integers. Errors can result from reading random, or because msg is
+// too large to be encrypted to the public key.
+func Encrypt(random io.Reader, pub *PublicKey, msg []byte) (c1, c2 *big.Int, err error) {
+	pLen := (pub.P.BitLen() + 7) / 8
+	if len(msg) > pLen-11 {
+		err = errors.New("elgamal: message too long")
+		return
+	}
+
+	// EM = 0x02 || PS || 0x00 || M
+	em := make([]byte, pLen-1)
+	em[0] = 2
+	ps, mm := em[1:len(em)-len(msg)-1], em[len(em)-len(msg):]
+	err = nonZeroRandomBytes(ps, random)
+	if err != nil {
+		return
+	}
+	em[len(em)-len(msg)-1] = 0
+	copy(mm, msg)
+
+	m := new(big.Int).SetBytes(em)
+
+	k, err := rand.Int(random, pub.P)
+	if err != nil {
+		return
+	}
+
+	c1 = new(big.Int).Exp(pub.G, k, pub.P)
+	s := new(big.Int).Exp(pub.Y, k, pub.P)
+	c2 = s.Mul(s, m)
+	c2.Mod(c2, pub.P)
+
+	return
+}
+
+// Decrypt takes two integers, resulting from an ElGamal encryption, and
+// returns the plaintext of the message. An error can result only if the
+// ciphertext is invalid. Users should keep in mind that this is a padding
+// oracle and thus, if exposed to an adaptive chosen ciphertext attack, can
+// be used to break the cryptosystem.  See ``Chosen Ciphertext Attacks
+// Against Protocols Based on the RSA Encryption Standard PKCS #1'', Daniel
+// Bleichenbacher, Advances in Cryptology (Crypto '98),
+func Decrypt(priv *PrivateKey, c1, c2 *big.Int) (msg []byte, err error) {
+	s := new(big.Int).Exp(c1, priv.X, priv.P)
+	if s.ModInverse(s, priv.P) == nil {
+		return nil, errors.New("elgamal: invalid private key")
+	}
+	s.Mul(s, c2)
+	s.Mod(s, priv.P)
+	em := s.Bytes()
+
+	firstByteIsTwo := subtle.ConstantTimeByteEq(em[0], 2)
+
+	// The remainder of the plaintext must be a string of non-zero random
+	// octets, followed by a 0, followed by the message.
+	//   lookingForIndex: 1 iff we are still looking for the zero.
+	//   index: the offset of the first zero byte.
+	var lookingForIndex, index int
+	lookingForIndex = 1
+
+	for i := 1; i < len(em); i++ {
+		equals0 := subtle.ConstantTimeByteEq(em[i], 0)
+		index = subtle.ConstantTimeSelect(lookingForIndex&equals0, i, index)
+		lookingForIndex = subtle.ConstantTimeSelect(equals0, 0, lookingForIndex)
+	}
+
+	if firstByteIsTwo != 1 || lookingForIndex != 0 || index < 9 {
+		return nil, errors.New("elgamal: decryption error")
+	}
+	return em[index+1:], nil
+}
+
+// nonZeroRandomBytes fills the given slice with non-zero random octets.
+func nonZeroRandomBytes(s []byte, rand io.Reader) (err error) {
+	_, err = io.ReadFull(rand, s)
+	if err != nil {
+		return
+	}
+
+	for i := 0; i < len(s); i++ {
+		for s[i] == 0 {
+			_, err = io.ReadFull(rand, s[i:i+1])
+			if err != nil {
+				return
+			}
+		}
+	}
+
+	return
+}
diff --git a/vendor/golang.org/x/crypto/openpgp/errors/errors.go b/vendor/golang.org/x/crypto/openpgp/errors/errors.go
new file mode 100644
index 0000000000..1d7a0ea05a
--- /dev/null
+++ b/vendor/golang.org/x/crypto/openpgp/errors/errors.go
@@ -0,0 +1,78 @@
+// Copyright 2010 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 errors contains common error types for the OpenPGP packages.
+//
+// Deprecated: this package is unmaintained except for security fixes. New
+// applications should consider a more focused, modern alternative to OpenPGP
+// for their specific task. If you are required to interoperate with OpenPGP
+// systems and need a maintained package, consider a community fork.
+// See https://golang.org/issue/44226.
+package errors // import "golang.org/x/crypto/openpgp/errors"
+
+import (
+	"strconv"
+)
+
+// A StructuralError is returned when OpenPGP data is found to be syntactically
+// invalid.
+type StructuralError string
+
+func (s StructuralError) Error() string {
+	return "openpgp: invalid data: " + string(s)
+}
+
+// UnsupportedError indicates that, although the OpenPGP data is valid, it
+// makes use of currently unimplemented features.
+type UnsupportedError string
+
+func (s UnsupportedError) Error() string {
+	return "openpgp: unsupported feature: " + string(s)
+}
+
+// InvalidArgumentError indicates that the caller is in error and passed an
+// incorrect value.
+type InvalidArgumentError string
+
+func (i InvalidArgumentError) Error() string {
+	return "openpgp: invalid argument: " + string(i)
+}
+
+// SignatureError indicates that a syntactically valid signature failed to
+// validate.
+type SignatureError string
+
+func (b SignatureError) Error() string {
+	return "openpgp: invalid signature: " + string(b)
+}
+
+type keyIncorrectError int
+
+func (ki keyIncorrectError) Error() string {
+	return "openpgp: incorrect key"
+}
+
+var ErrKeyIncorrect error = keyIncorrectError(0)
+
+type unknownIssuerError int
+
+func (unknownIssuerError) Error() string {
+	return "openpgp: signature made by unknown entity"
+}
+
+var ErrUnknownIssuer error = unknownIssuerError(0)
+
+type keyRevokedError int
+
+func (keyRevokedError) Error() string {
+	return "openpgp: signature made by revoked key"
+}
+
+var ErrKeyRevoked error = keyRevokedError(0)
+
+type UnknownPacketTypeError uint8
+
+func (upte UnknownPacketTypeError) Error() string {
+	return "openpgp: unknown packet type: " + strconv.Itoa(int(upte))
+}
diff --git a/vendor/golang.org/x/crypto/openpgp/keys.go b/vendor/golang.org/x/crypto/openpgp/keys.go
new file mode 100644
index 0000000000..faa2fb3693
--- /dev/null
+++ b/vendor/golang.org/x/crypto/openpgp/keys.go
@@ -0,0 +1,693 @@
+// Copyright 2011 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 openpgp
+
+import (
+	"crypto/rsa"
+	"io"
+	"time"
+
+	"golang.org/x/crypto/openpgp/armor"
+	"golang.org/x/crypto/openpgp/errors"
+	"golang.org/x/crypto/openpgp/packet"
+)
+
+// PublicKeyType is the armor type for a PGP public key.
+var PublicKeyType = "PGP PUBLIC KEY BLOCK"
+
+// PrivateKeyType is the armor type for a PGP private key.
+var PrivateKeyType = "PGP PRIVATE KEY BLOCK"
+
+// An Entity represents the components of an OpenPGP key: a primary public key
+// (which must be a signing key), one or more identities claimed by that key,
+// and zero or more subkeys, which may be encryption keys.
+type Entity struct {
+	PrimaryKey  *packet.PublicKey
+	PrivateKey  *packet.PrivateKey
+	Identities  map[string]*Identity // indexed by Identity.Name
+	Revocations []*packet.Signature
+	Subkeys     []Subkey
+}
+
+// An Identity represents an identity claimed by an Entity and zero or more
+// assertions by other entities about that claim.
+type Identity struct {
+	Name          string // by convention, has the form "Full Name (comment) <email@example.com>"
+	UserId        *packet.UserId
+	SelfSignature *packet.Signature
+	Signatures    []*packet.Signature
+}
+
+// A Subkey is an additional public key in an Entity. Subkeys can be used for
+// encryption.
+type Subkey struct {
+	PublicKey  *packet.PublicKey
+	PrivateKey *packet.PrivateKey
+	Sig        *packet.Signature
+}
+
+// A Key identifies a specific public key in an Entity. This is either the
+// Entity's primary key or a subkey.
+type Key struct {
+	Entity        *Entity
+	PublicKey     *packet.PublicKey
+	PrivateKey    *packet.PrivateKey
+	SelfSignature *packet.Signature
+}
+
+// A KeyRing provides access to public and private keys.
+type KeyRing interface {
+	// KeysById returns the set of keys that have the given key id.
+	KeysById(id uint64) []Key
+	// KeysByIdAndUsage returns the set of keys with the given id
+	// that also meet the key usage given by requiredUsage.
+	// The requiredUsage is expressed as the bitwise-OR of
+	// packet.KeyFlag* values.
+	KeysByIdUsage(id uint64, requiredUsage byte) []Key
+	// DecryptionKeys returns all private keys that are valid for
+	// decryption.
+	DecryptionKeys() []Key
+}
+
+// primaryIdentity returns the Identity marked as primary or the first identity
+// if none are so marked.
+func (e *Entity) primaryIdentity() *Identity {
+	var firstIdentity *Identity
+	for _, ident := range e.Identities {
+		if firstIdentity == nil {
+			firstIdentity = ident
+		}
+		if ident.SelfSignature.IsPrimaryId != nil && *ident.SelfSignature.IsPrimaryId {
+			return ident
+		}
+	}
+	return firstIdentity
+}
+
+// encryptionKey returns the best candidate Key for encrypting a message to the
+// given Entity.
+func (e *Entity) encryptionKey(now time.Time) (Key, bool) {
+	candidateSubkey := -1
+
+	// Iterate the keys to find the newest key
+	var maxTime time.Time
+	for i, subkey := range e.Subkeys {
+		if subkey.Sig.FlagsValid &&
+			subkey.Sig.FlagEncryptCommunications &&
+			subkey.PublicKey.PubKeyAlgo.CanEncrypt() &&
+			!subkey.Sig.KeyExpired(now) &&
+			(maxTime.IsZero() || subkey.Sig.CreationTime.After(maxTime)) {
+			candidateSubkey = i
+			maxTime = subkey.Sig.CreationTime
+		}
+	}
+
+	if candidateSubkey != -1 {
+		subkey := e.Subkeys[candidateSubkey]
+		return Key{e, subkey.PublicKey, subkey.PrivateKey, subkey.Sig}, true
+	}
+
+	// If we don't have any candidate subkeys for encryption and
+	// the primary key doesn't have any usage metadata then we
+	// assume that the primary key is ok. Or, if the primary key is
+	// marked as ok to encrypt to, then we can obviously use it.
+	i := e.primaryIdentity()
+	if !i.SelfSignature.FlagsValid || i.SelfSignature.FlagEncryptCommunications &&
+		e.PrimaryKey.PubKeyAlgo.CanEncrypt() &&
+		!i.SelfSignature.KeyExpired(now) {
+		return Key{e, e.PrimaryKey, e.PrivateKey, i.SelfSignature}, true
+	}
+
+	// This Entity appears to be signing only.
+	return Key{}, false
+}
+
+// signingKey return the best candidate Key for signing a message with this
+// Entity.
+func (e *Entity) signingKey(now time.Time) (Key, bool) {
+	candidateSubkey := -1
+
+	for i, subkey := range e.Subkeys {
+		if subkey.Sig.FlagsValid &&
+			subkey.Sig.FlagSign &&
+			subkey.PublicKey.PubKeyAlgo.CanSign() &&
+			!subkey.Sig.KeyExpired(now) {
+			candidateSubkey = i
+			break
+		}
+	}
+
+	if candidateSubkey != -1 {
+		subkey := e.Subkeys[candidateSubkey]
+		return Key{e, subkey.PublicKey, subkey.PrivateKey, subkey.Sig}, true
+	}
+
+	// If we have no candidate subkey then we assume that it's ok to sign
+	// with the primary key.
+	i := e.primaryIdentity()
+	if !i.SelfSignature.FlagsValid || i.SelfSignature.FlagSign &&
+		!i.SelfSignature.KeyExpired(now) {
+		return Key{e, e.PrimaryKey, e.PrivateKey, i.SelfSignature}, true
+	}
+
+	return Key{}, false
+}
+
+// An EntityList contains one or more Entities.
+type EntityList []*Entity
+
+// KeysById returns the set of keys that have the given key id.
+func (el EntityList) KeysById(id uint64) (keys []Key) {
+	for _, e := range el {
+		if e.PrimaryKey.KeyId == id {
+			var selfSig *packet.Signature
+			for _, ident := range e.Identities {
+				if selfSig == nil {
+					selfSig = ident.SelfSignature
+				} else if ident.SelfSignature.IsPrimaryId != nil && *ident.SelfSignature.IsPrimaryId {
+					selfSig = ident.SelfSignature
+					break
+				}
+			}
+			keys = append(keys, Key{e, e.PrimaryKey, e.PrivateKey, selfSig})
+		}
+
+		for _, subKey := range e.Subkeys {
+			if subKey.PublicKey.KeyId == id {
+				keys = append(keys, Key{e, subKey.PublicKey, subKey.PrivateKey, subKey.Sig})
+			}
+		}
+	}
+	return
+}
+
+// KeysByIdAndUsage returns the set of keys with the given id that also meet
+// the key usage given by requiredUsage.  The requiredUsage is expressed as
+// the bitwise-OR of packet.KeyFlag* values.
+func (el EntityList) KeysByIdUsage(id uint64, requiredUsage byte) (keys []Key) {
+	for _, key := range el.KeysById(id) {
+		if len(key.Entity.Revocations) > 0 {
+			continue
+		}
+
+		if key.SelfSignature.RevocationReason != nil {
+			continue
+		}
+
+		if key.SelfSignature.FlagsValid && requiredUsage != 0 {
+			var usage byte
+			if key.SelfSignature.FlagCertify {
+				usage |= packet.KeyFlagCertify
+			}
+			if key.SelfSignature.FlagSign {
+				usage |= packet.KeyFlagSign
+			}
+			if key.SelfSignature.FlagEncryptCommunications {
+				usage |= packet.KeyFlagEncryptCommunications
+			}
+			if key.SelfSignature.FlagEncryptStorage {
+				usage |= packet.KeyFlagEncryptStorage
+			}
+			if usage&requiredUsage != requiredUsage {
+				continue
+			}
+		}
+
+		keys = append(keys, key)
+	}
+	return
+}
+
+// DecryptionKeys returns all private keys that are valid for decryption.
+func (el EntityList) DecryptionKeys() (keys []Key) {
+	for _, e := range el {
+		for _, subKey := range e.Subkeys {
+			if subKey.PrivateKey != nil && (!subKey.Sig.FlagsValid || subKey.Sig.FlagEncryptStorage || subKey.Sig.FlagEncryptCommunications) {
+				keys = append(keys, Key{e, subKey.PublicKey, subKey.PrivateKey, subKey.Sig})
+			}
+		}
+	}
+	return
+}
+
+// ReadArmoredKeyRing reads one or more public/private keys from an armor keyring file.
+func ReadArmoredKeyRing(r io.Reader) (EntityList, error) {
+	block, err := armor.Decode(r)
+	if err == io.EOF {
+		return nil, errors.InvalidArgumentError("no armored data found")
+	}
+	if err != nil {
+		return nil, err
+	}
+	if block.Type != PublicKeyType && block.Type != PrivateKeyType {
+		return nil, errors.InvalidArgumentError("expected public or private key block, got: " + block.Type)
+	}
+
+	return ReadKeyRing(block.Body)
+}
+
+// ReadKeyRing reads one or more public/private keys. Unsupported keys are
+// ignored as long as at least a single valid key is found.
+func ReadKeyRing(r io.Reader) (el EntityList, err error) {
+	packets := packet.NewReader(r)
+	var lastUnsupportedError error
+
+	for {
+		var e *Entity
+		e, err = ReadEntity(packets)
+		if err != nil {
+			// TODO: warn about skipped unsupported/unreadable keys
+			if _, ok := err.(errors.UnsupportedError); ok {
+				lastUnsupportedError = err
+				err = readToNextPublicKey(packets)
+			} else if _, ok := err.(errors.StructuralError); ok {
+				// Skip unreadable, badly-formatted keys
+				lastUnsupportedError = err
+				err = readToNextPublicKey(packets)
+			}
+			if err == io.EOF {
+				err = nil
+				break
+			}
+			if err != nil {
+				el = nil
+				break
+			}
+		} else {
+			el = append(el, e)
+		}
+	}
+
+	if len(el) == 0 && err == nil {
+		err = lastUnsupportedError
+	}
+	return
+}
+
+// readToNextPublicKey reads packets until the start of the entity and leaves
+// the first packet of the new entity in the Reader.
+func readToNextPublicKey(packets *packet.Reader) (err error) {
+	var p packet.Packet
+	for {
+		p, err = packets.Next()
+		if err == io.EOF {
+			return
+		} else if err != nil {
+			if _, ok := err.(errors.UnsupportedError); ok {
+				err = nil
+				continue
+			}
+			return
+		}
+
+		if pk, ok := p.(*packet.PublicKey); ok && !pk.IsSubkey {
+			packets.Unread(p)
+			return
+		}
+	}
+}
+
+// ReadEntity reads an entity (public key, identities, subkeys etc) from the
+// given Reader.
+func ReadEntity(packets *packet.Reader) (*Entity, error) {
+	e := new(Entity)
+	e.Identities = make(map[string]*Identity)
+
+	p, err := packets.Next()
+	if err != nil {
+		return nil, err
+	}
+
+	var ok bool
+	if e.PrimaryKey, ok = p.(*packet.PublicKey); !ok {
+		if e.PrivateKey, ok = p.(*packet.PrivateKey); !ok {
+			packets.Unread(p)
+			return nil, errors.StructuralError("first packet was not a public/private key")
+		}
+		e.PrimaryKey = &e.PrivateKey.PublicKey
+	}
+
+	if !e.PrimaryKey.PubKeyAlgo.CanSign() {
+		return nil, errors.StructuralError("primary key cannot be used for signatures")
+	}
+
+	var revocations []*packet.Signature
+EachPacket:
+	for {
+		p, err := packets.Next()
+		if err == io.EOF {
+			break
+		} else if err != nil {
+			return nil, err
+		}
+
+		switch pkt := p.(type) {
+		case *packet.UserId:
+			if err := addUserID(e, packets, pkt); err != nil {
+				return nil, err
+			}
+		case *packet.Signature:
+			if pkt.SigType == packet.SigTypeKeyRevocation {
+				revocations = append(revocations, pkt)
+			} else if pkt.SigType == packet.SigTypeDirectSignature {
+				// TODO: RFC4880 5.2.1 permits signatures
+				// directly on keys (eg. to bind additional
+				// revocation keys).
+			}
+			// Else, ignoring the signature as it does not follow anything
+			// we would know to attach it to.
+		case *packet.PrivateKey:
+			if pkt.IsSubkey == false {
+				packets.Unread(p)
+				break EachPacket
+			}
+			err = addSubkey(e, packets, &pkt.PublicKey, pkt)
+			if err != nil {
+				return nil, err
+			}
+		case *packet.PublicKey:
+			if pkt.IsSubkey == false {
+				packets.Unread(p)
+				break EachPacket
+			}
+			err = addSubkey(e, packets, pkt, nil)
+			if err != nil {
+				return nil, err
+			}
+		default:
+			// we ignore unknown packets
+		}
+	}
+
+	if len(e.Identities) == 0 {
+		return nil, errors.StructuralError("entity without any identities")
+	}
+
+	for _, revocation := range revocations {
+		err = e.PrimaryKey.VerifyRevocationSignature(revocation)
+		if err == nil {
+			e.Revocations = append(e.Revocations, revocation)
+		} else {
+			// TODO: RFC 4880 5.2.3.15 defines revocation keys.
+			return nil, errors.StructuralError("revocation signature signed by alternate key")
+		}
+	}
+
+	return e, nil
+}
+
+func addUserID(e *Entity, packets *packet.Reader, pkt *packet.UserId) error {
+	// Make a new Identity object, that we might wind up throwing away.
+	// We'll only add it if we get a valid self-signature over this
+	// userID.
+	identity := new(Identity)
+	identity.Name = pkt.Id
+	identity.UserId = pkt
+
+	for {
+		p, err := packets.Next()
+		if err == io.EOF {
+			break
+		} else if err != nil {
+			return err
+		}
+
+		sig, ok := p.(*packet.Signature)
+		if !ok {
+			packets.Unread(p)
+			break
+		}
+
+		if (sig.SigType == packet.SigTypePositiveCert || sig.SigType == packet.SigTypeGenericCert) && sig.IssuerKeyId != nil && *sig.IssuerKeyId == e.PrimaryKey.KeyId {
+			if err = e.PrimaryKey.VerifyUserIdSignature(pkt.Id, e.PrimaryKey, sig); err != nil {
+				return errors.StructuralError("user ID self-signature invalid: " + err.Error())
+			}
+			identity.SelfSignature = sig
+			e.Identities[pkt.Id] = identity
+		} else {
+			identity.Signatures = append(identity.Signatures, sig)
+		}
+	}
+
+	return nil
+}
+
+func addSubkey(e *Entity, packets *packet.Reader, pub *packet.PublicKey, priv *packet.PrivateKey) error {
+	var subKey Subkey
+	subKey.PublicKey = pub
+	subKey.PrivateKey = priv
+
+	for {
+		p, err := packets.Next()
+		if err == io.EOF {
+			break
+		} else if err != nil {
+			return errors.StructuralError("subkey signature invalid: " + err.Error())
+		}
+
+		sig, ok := p.(*packet.Signature)
+		if !ok {
+			packets.Unread(p)
+			break
+		}
+
+		if sig.SigType != packet.SigTypeSubkeyBinding && sig.SigType != packet.SigTypeSubkeyRevocation {
+			return errors.StructuralError("subkey signature with wrong type")
+		}
+
+		if err := e.PrimaryKey.VerifyKeySignature(subKey.PublicKey, sig); err != nil {
+			return errors.StructuralError("subkey signature invalid: " + err.Error())
+		}
+
+		switch sig.SigType {
+		case packet.SigTypeSubkeyRevocation:
+			subKey.Sig = sig
+		case packet.SigTypeSubkeyBinding:
+
+			if shouldReplaceSubkeySig(subKey.Sig, sig) {
+				subKey.Sig = sig
+			}
+		}
+	}
+
+	if subKey.Sig == nil {
+		return errors.StructuralError("subkey packet not followed by signature")
+	}
+
+	e.Subkeys = append(e.Subkeys, subKey)
+
+	return nil
+}
+
+func shouldReplaceSubkeySig(existingSig, potentialNewSig *packet.Signature) bool {
+	if potentialNewSig == nil {
+		return false
+	}
+
+	if existingSig == nil {
+		return true
+	}
+
+	if existingSig.SigType == packet.SigTypeSubkeyRevocation {
+		return false // never override a revocation signature
+	}
+
+	return potentialNewSig.CreationTime.After(existingSig.CreationTime)
+}
+
+const defaultRSAKeyBits = 2048
+
+// NewEntity returns an Entity that contains a fresh RSA/RSA keypair with a
+// single identity composed of the given full name, comment and email, any of
+// which may be empty but must not contain any of "()<>\x00".
+// If config is nil, sensible defaults will be used.
+func NewEntity(name, comment, email string, config *packet.Config) (*Entity, error) {
+	creationTime := config.Now()
+
+	bits := defaultRSAKeyBits
+	if config != nil && config.RSABits != 0 {
+		bits = config.RSABits
+	}
+
+	uid := packet.NewUserId(name, comment, email)
+	if uid == nil {
+		return nil, errors.InvalidArgumentError("user id field contained invalid characters")
+	}
+	signingPriv, err := rsa.GenerateKey(config.Random(), bits)
+	if err != nil {
+		return nil, err
+	}
+	encryptingPriv, err := rsa.GenerateKey(config.Random(), bits)
+	if err != nil {
+		return nil, err
+	}
+
+	e := &Entity{
+		PrimaryKey: packet.NewRSAPublicKey(creationTime, &signingPriv.PublicKey),
+		PrivateKey: packet.NewRSAPrivateKey(creationTime, signingPriv),
+		Identities: make(map[string]*Identity),
+	}
+	isPrimaryId := true
+	e.Identities[uid.Id] = &Identity{
+		Name:   uid.Id,
+		UserId: uid,
+		SelfSignature: &packet.Signature{
+			CreationTime: creationTime,
+			SigType:      packet.SigTypePositiveCert,
+			PubKeyAlgo:   packet.PubKeyAlgoRSA,
+			Hash:         config.Hash(),
+			IsPrimaryId:  &isPrimaryId,
+			FlagsValid:   true,
+			FlagSign:     true,
+			FlagCertify:  true,
+			IssuerKeyId:  &e.PrimaryKey.KeyId,
+		},
+	}
+	err = e.Identities[uid.Id].SelfSignature.SignUserId(uid.Id, e.PrimaryKey, e.PrivateKey, config)
+	if err != nil {
+		return nil, err
+	}
+
+	// If the user passes in a DefaultHash via packet.Config,
+	// set the PreferredHash for the SelfSignature.
+	if config != nil && config.DefaultHash != 0 {
+		e.Identities[uid.Id].SelfSignature.PreferredHash = []uint8{hashToHashId(config.DefaultHash)}
+	}
+
+	// Likewise for DefaultCipher.
+	if config != nil && config.DefaultCipher != 0 {
+		e.Identities[uid.Id].SelfSignature.PreferredSymmetric = []uint8{uint8(config.DefaultCipher)}
+	}
+
+	e.Subkeys = make([]Subkey, 1)
+	e.Subkeys[0] = Subkey{
+		PublicKey:  packet.NewRSAPublicKey(creationTime, &encryptingPriv.PublicKey),
+		PrivateKey: packet.NewRSAPrivateKey(creationTime, encryptingPriv),
+		Sig: &packet.Signature{
+			CreationTime:              creationTime,
+			SigType:                   packet.SigTypeSubkeyBinding,
+			PubKeyAlgo:                packet.PubKeyAlgoRSA,
+			Hash:                      config.Hash(),
+			FlagsValid:                true,
+			FlagEncryptStorage:        true,
+			FlagEncryptCommunications: true,
+			IssuerKeyId:               &e.PrimaryKey.KeyId,
+		},
+	}
+	e.Subkeys[0].PublicKey.IsSubkey = true
+	e.Subkeys[0].PrivateKey.IsSubkey = true
+	err = e.Subkeys[0].Sig.SignKey(e.Subkeys[0].PublicKey, e.PrivateKey, config)
+	if err != nil {
+		return nil, err
+	}
+	return e, nil
+}
+
+// SerializePrivate serializes an Entity, including private key material, but
+// excluding signatures from other entities, to the given Writer.
+// Identities and subkeys are re-signed in case they changed since NewEntry.
+// If config is nil, sensible defaults will be used.
+func (e *Entity) SerializePrivate(w io.Writer, config *packet.Config) (err error) {
+	err = e.PrivateKey.Serialize(w)
+	if err != nil {
+		return
+	}
+	for _, ident := range e.Identities {
+		err = ident.UserId.Serialize(w)
+		if err != nil {
+			return
+		}
+		err = ident.SelfSignature.SignUserId(ident.UserId.Id, e.PrimaryKey, e.PrivateKey, config)
+		if err != nil {
+			return
+		}
+		err = ident.SelfSignature.Serialize(w)
+		if err != nil {
+			return
+		}
+	}
+	for _, subkey := range e.Subkeys {
+		err = subkey.PrivateKey.Serialize(w)
+		if err != nil {
+			return
+		}
+		err = subkey.Sig.SignKey(subkey.PublicKey, e.PrivateKey, config)
+		if err != nil {
+			return
+		}
+		err = subkey.Sig.Serialize(w)
+		if err != nil {
+			return
+		}
+	}
+	return nil
+}
+
+// Serialize writes the public part of the given Entity to w, including
+// signatures from other entities. No private key material will be output.
+func (e *Entity) Serialize(w io.Writer) error {
+	err := e.PrimaryKey.Serialize(w)
+	if err != nil {
+		return err
+	}
+	for _, ident := range e.Identities {
+		err = ident.UserId.Serialize(w)
+		if err != nil {
+			return err
+		}
+		err = ident.SelfSignature.Serialize(w)
+		if err != nil {
+			return err
+		}
+		for _, sig := range ident.Signatures {
+			err = sig.Serialize(w)
+			if err != nil {
+				return err
+			}
+		}
+	}
+	for _, subkey := range e.Subkeys {
+		err = subkey.PublicKey.Serialize(w)
+		if err != nil {
+			return err
+		}
+		err = subkey.Sig.Serialize(w)
+		if err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+// SignIdentity adds a signature to e, from signer, attesting that identity is
+// associated with e. The provided identity must already be an element of
+// e.Identities and the private key of signer must have been decrypted if
+// necessary.
+// If config is nil, sensible defaults will be used.
+func (e *Entity) SignIdentity(identity string, signer *Entity, config *packet.Config) error {
+	if signer.PrivateKey == nil {
+		return errors.InvalidArgumentError("signing Entity must have a private key")
+	}
+	if signer.PrivateKey.Encrypted {
+		return errors.InvalidArgumentError("signing Entity's private key must be decrypted")
+	}
+	ident, ok := e.Identities[identity]
+	if !ok {
+		return errors.InvalidArgumentError("given identity string not found in Entity")
+	}
+
+	sig := &packet.Signature{
+		SigType:      packet.SigTypeGenericCert,
+		PubKeyAlgo:   signer.PrivateKey.PubKeyAlgo,
+		Hash:         config.Hash(),
+		CreationTime: config.Now(),
+		IssuerKeyId:  &signer.PrivateKey.KeyId,
+	}
+	if err := sig.SignUserId(identity, e.PrimaryKey, signer.PrivateKey, config); err != nil {
+		return err
+	}
+	ident.Signatures = append(ident.Signatures, sig)
+	return nil
+}
diff --git a/vendor/golang.org/x/crypto/openpgp/packet/compressed.go b/vendor/golang.org/x/crypto/openpgp/packet/compressed.go
new file mode 100644
index 0000000000..e8f0b5caa7
--- /dev/null
+++ b/vendor/golang.org/x/crypto/openpgp/packet/compressed.go
@@ -0,0 +1,123 @@
+// Copyright 2011 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 packet
+
+import (
+	"compress/bzip2"
+	"compress/flate"
+	"compress/zlib"
+	"golang.org/x/crypto/openpgp/errors"
+	"io"
+	"strconv"
+)
+
+// Compressed represents a compressed OpenPGP packet. The decompressed contents
+// will contain more OpenPGP packets. See RFC 4880, section 5.6.
+type Compressed struct {
+	Body io.Reader
+}
+
+const (
+	NoCompression      = flate.NoCompression
+	BestSpeed          = flate.BestSpeed
+	BestCompression    = flate.BestCompression
+	DefaultCompression = flate.DefaultCompression
+)
+
+// CompressionConfig contains compressor configuration settings.
+type CompressionConfig struct {
+	// Level is the compression level to use. It must be set to
+	// between -1 and 9, with -1 causing the compressor to use the
+	// default compression level, 0 causing the compressor to use
+	// no compression and 1 to 9 representing increasing (better,
+	// slower) compression levels. If Level is less than -1 or
+	// more then 9, a non-nil error will be returned during
+	// encryption. See the constants above for convenient common
+	// settings for Level.
+	Level int
+}
+
+func (c *Compressed) parse(r io.Reader) error {
+	var buf [1]byte
+	_, err := readFull(r, buf[:])
+	if err != nil {
+		return err
+	}
+
+	switch buf[0] {
+	case 1:
+		c.Body = flate.NewReader(r)
+	case 2:
+		c.Body, err = zlib.NewReader(r)
+	case 3:
+		c.Body = bzip2.NewReader(r)
+	default:
+		err = errors.UnsupportedError("unknown compression algorithm: " + strconv.Itoa(int(buf[0])))
+	}
+
+	return err
+}
+
+// compressedWriterCloser represents the serialized compression stream
+// header and the compressor. Its Close() method ensures that both the
+// compressor and serialized stream header are closed. Its Write()
+// method writes to the compressor.
+type compressedWriteCloser struct {
+	sh io.Closer      // Stream Header
+	c  io.WriteCloser // Compressor
+}
+
+func (cwc compressedWriteCloser) Write(p []byte) (int, error) {
+	return cwc.c.Write(p)
+}
+
+func (cwc compressedWriteCloser) Close() (err error) {
+	err = cwc.c.Close()
+	if err != nil {
+		return err
+	}
+
+	return cwc.sh.Close()
+}
+
+// SerializeCompressed serializes a compressed data packet to w and
+// returns a WriteCloser to which the literal data packets themselves
+// can be written and which MUST be closed on completion. If cc is
+// nil, sensible defaults will be used to configure the compression
+// algorithm.
+func SerializeCompressed(w io.WriteCloser, algo CompressionAlgo, cc *CompressionConfig) (literaldata io.WriteCloser, err error) {
+	compressed, err := serializeStreamHeader(w, packetTypeCompressed)
+	if err != nil {
+		return
+	}
+
+	_, err = compressed.Write([]byte{uint8(algo)})
+	if err != nil {
+		return
+	}
+
+	level := DefaultCompression
+	if cc != nil {
+		level = cc.Level
+	}
+
+	var compressor io.WriteCloser
+	switch algo {
+	case CompressionZIP:
+		compressor, err = flate.NewWriter(compressed, level)
+	case CompressionZLIB:
+		compressor, err = zlib.NewWriterLevel(compressed, level)
+	default:
+		s := strconv.Itoa(int(algo))
+		err = errors.UnsupportedError("Unsupported compression algorithm: " + s)
+	}
+	if err != nil {
+		return
+	}
+
+	literaldata = compressedWriteCloser{compressed, compressor}
+
+	return
+}
diff --git a/vendor/golang.org/x/crypto/openpgp/packet/config.go b/vendor/golang.org/x/crypto/openpgp/packet/config.go
new file mode 100644
index 0000000000..c76eecc963
--- /dev/null
+++ b/vendor/golang.org/x/crypto/openpgp/packet/config.go
@@ -0,0 +1,91 @@
+// 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 packet
+
+import (
+	"crypto"
+	"crypto/rand"
+	"io"
+	"time"
+)
+
+// Config collects a number of parameters along with sensible defaults.
+// A nil *Config is valid and results in all default values.
+type Config struct {
+	// Rand provides the source of entropy.
+	// If nil, the crypto/rand Reader is used.
+	Rand io.Reader
+	// DefaultHash is the default hash function to be used.
+	// If zero, SHA-256 is used.
+	DefaultHash crypto.Hash
+	// DefaultCipher is the cipher to be used.
+	// If zero, AES-128 is used.
+	DefaultCipher CipherFunction
+	// Time returns the current time as the number of seconds since the
+	// epoch. If Time is nil, time.Now is used.
+	Time func() time.Time
+	// DefaultCompressionAlgo is the compression algorithm to be
+	// applied to the plaintext before encryption. If zero, no
+	// compression is done.
+	DefaultCompressionAlgo CompressionAlgo
+	// CompressionConfig configures the compression settings.
+	CompressionConfig *CompressionConfig
+	// S2KCount is only used for symmetric encryption. It
+	// determines the strength of the passphrase stretching when
+	// the said passphrase is hashed to produce a key. S2KCount
+	// should be between 1024 and 65011712, inclusive. If Config
+	// is nil or S2KCount is 0, the value 65536 used. Not all
+	// values in the above range can be represented. S2KCount will
+	// be rounded up to the next representable value if it cannot
+	// be encoded exactly. When set, it is strongly encrouraged to
+	// use a value that is at least 65536. See RFC 4880 Section
+	// 3.7.1.3.
+	S2KCount int
+	// RSABits is the number of bits in new RSA keys made with NewEntity.
+	// If zero, then 2048 bit keys are created.
+	RSABits int
+}
+
+func (c *Config) Random() io.Reader {
+	if c == nil || c.Rand == nil {
+		return rand.Reader
+	}
+	return c.Rand
+}
+
+func (c *Config) Hash() crypto.Hash {
+	if c == nil || uint(c.DefaultHash) == 0 {
+		return crypto.SHA256
+	}
+	return c.DefaultHash
+}
+
+func (c *Config) Cipher() CipherFunction {
+	if c == nil || uint8(c.DefaultCipher) == 0 {
+		return CipherAES128
+	}
+	return c.DefaultCipher
+}
+
+func (c *Config) Now() time.Time {
+	if c == nil || c.Time == nil {
+		return time.Now()
+	}
+	return c.Time()
+}
+
+func (c *Config) Compression() CompressionAlgo {
+	if c == nil {
+		return CompressionNone
+	}
+	return c.DefaultCompressionAlgo
+}
+
+func (c *Config) PasswordHashIterations() int {
+	if c == nil || c.S2KCount == 0 {
+		return 0
+	}
+	return c.S2KCount
+}
diff --git a/vendor/golang.org/x/crypto/openpgp/packet/encrypted_key.go b/vendor/golang.org/x/crypto/openpgp/packet/encrypted_key.go
new file mode 100644
index 0000000000..6d7639722c
--- /dev/null
+++ b/vendor/golang.org/x/crypto/openpgp/packet/encrypted_key.go
@@ -0,0 +1,208 @@
+// Copyright 2011 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 packet
+
+import (
+	"crypto"
+	"crypto/rsa"
+	"encoding/binary"
+	"io"
+	"math/big"
+	"strconv"
+
+	"golang.org/x/crypto/openpgp/elgamal"
+	"golang.org/x/crypto/openpgp/errors"
+)
+
+const encryptedKeyVersion = 3
+
+// EncryptedKey represents a public-key encrypted session key. See RFC 4880,
+// section 5.1.
+type EncryptedKey struct {
+	KeyId      uint64
+	Algo       PublicKeyAlgorithm
+	CipherFunc CipherFunction // only valid after a successful Decrypt
+	Key        []byte         // only valid after a successful Decrypt
+
+	encryptedMPI1, encryptedMPI2 parsedMPI
+}
+
+func (e *EncryptedKey) parse(r io.Reader) (err error) {
+	var buf [10]byte
+	_, err = readFull(r, buf[:])
+	if err != nil {
+		return
+	}
+	if buf[0] != encryptedKeyVersion {
+		return errors.UnsupportedError("unknown EncryptedKey version " + strconv.Itoa(int(buf[0])))
+	}
+	e.KeyId = binary.BigEndian.Uint64(buf[1:9])
+	e.Algo = PublicKeyAlgorithm(buf[9])
+	switch e.Algo {
+	case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly:
+		e.encryptedMPI1.bytes, e.encryptedMPI1.bitLength, err = readMPI(r)
+		if err != nil {
+			return
+		}
+	case PubKeyAlgoElGamal:
+		e.encryptedMPI1.bytes, e.encryptedMPI1.bitLength, err = readMPI(r)
+		if err != nil {
+			return
+		}
+		e.encryptedMPI2.bytes, e.encryptedMPI2.bitLength, err = readMPI(r)
+		if err != nil {
+			return
+		}
+	}
+	_, err = consumeAll(r)
+	return
+}
+
+func checksumKeyMaterial(key []byte) uint16 {
+	var checksum uint16
+	for _, v := range key {
+		checksum += uint16(v)
+	}
+	return checksum
+}
+
+// Decrypt decrypts an encrypted session key with the given private key. The
+// private key must have been decrypted first.
+// If config is nil, sensible defaults will be used.
+func (e *EncryptedKey) Decrypt(priv *PrivateKey, config *Config) error {
+	var err error
+	var b []byte
+
+	// TODO(agl): use session key decryption routines here to avoid
+	// padding oracle attacks.
+	switch priv.PubKeyAlgo {
+	case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly:
+		// Supports both *rsa.PrivateKey and crypto.Decrypter
+		k := priv.PrivateKey.(crypto.Decrypter)
+		b, err = k.Decrypt(config.Random(), padToKeySize(k.Public().(*rsa.PublicKey), e.encryptedMPI1.bytes), nil)
+	case PubKeyAlgoElGamal:
+		c1 := new(big.Int).SetBytes(e.encryptedMPI1.bytes)
+		c2 := new(big.Int).SetBytes(e.encryptedMPI2.bytes)
+		b, err = elgamal.Decrypt(priv.PrivateKey.(*elgamal.PrivateKey), c1, c2)
+	default:
+		err = errors.InvalidArgumentError("cannot decrypted encrypted session key with private key of type " + strconv.Itoa(int(priv.PubKeyAlgo)))
+	}
+
+	if err != nil {
+		return err
+	}
+
+	e.CipherFunc = CipherFunction(b[0])
+	e.Key = b[1 : len(b)-2]
+	expectedChecksum := uint16(b[len(b)-2])<<8 | uint16(b[len(b)-1])
+	checksum := checksumKeyMaterial(e.Key)
+	if checksum != expectedChecksum {
+		return errors.StructuralError("EncryptedKey checksum incorrect")
+	}
+
+	return nil
+}
+
+// Serialize writes the encrypted key packet, e, to w.
+func (e *EncryptedKey) Serialize(w io.Writer) error {
+	var mpiLen int
+	switch e.Algo {
+	case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly:
+		mpiLen = 2 + len(e.encryptedMPI1.bytes)
+	case PubKeyAlgoElGamal:
+		mpiLen = 2 + len(e.encryptedMPI1.bytes) + 2 + len(e.encryptedMPI2.bytes)
+	default:
+		return errors.InvalidArgumentError("don't know how to serialize encrypted key type " + strconv.Itoa(int(e.Algo)))
+	}
+
+	serializeHeader(w, packetTypeEncryptedKey, 1 /* version */ +8 /* key id */ +1 /* algo */ +mpiLen)
+
+	w.Write([]byte{encryptedKeyVersion})
+	binary.Write(w, binary.BigEndian, e.KeyId)
+	w.Write([]byte{byte(e.Algo)})
+
+	switch e.Algo {
+	case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly:
+		writeMPIs(w, e.encryptedMPI1)
+	case PubKeyAlgoElGamal:
+		writeMPIs(w, e.encryptedMPI1, e.encryptedMPI2)
+	default:
+		panic("internal error")
+	}
+
+	return nil
+}
+
+// SerializeEncryptedKey serializes an encrypted key packet to w that contains
+// key, encrypted to pub.
+// If config is nil, sensible defaults will be used.
+func SerializeEncryptedKey(w io.Writer, pub *PublicKey, cipherFunc CipherFunction, key []byte, config *Config) error {
+	var buf [10]byte
+	buf[0] = encryptedKeyVersion
+	binary.BigEndian.PutUint64(buf[1:9], pub.KeyId)
+	buf[9] = byte(pub.PubKeyAlgo)
+
+	keyBlock := make([]byte, 1 /* cipher type */ +len(key)+2 /* checksum */)
+	keyBlock[0] = byte(cipherFunc)
+	copy(keyBlock[1:], key)
+	checksum := checksumKeyMaterial(key)
+	keyBlock[1+len(key)] = byte(checksum >> 8)
+	keyBlock[1+len(key)+1] = byte(checksum)
+
+	switch pub.PubKeyAlgo {
+	case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly:
+		return serializeEncryptedKeyRSA(w, config.Random(), buf, pub.PublicKey.(*rsa.PublicKey), keyBlock)
+	case PubKeyAlgoElGamal:
+		return serializeEncryptedKeyElGamal(w, config.Random(), buf, pub.PublicKey.(*elgamal.PublicKey), keyBlock)
+	case PubKeyAlgoDSA, PubKeyAlgoRSASignOnly:
+		return errors.InvalidArgumentError("cannot encrypt to public key of type " + strconv.Itoa(int(pub.PubKeyAlgo)))
+	}
+
+	return errors.UnsupportedError("encrypting a key to public key of type " + strconv.Itoa(int(pub.PubKeyAlgo)))
+}
+
+func serializeEncryptedKeyRSA(w io.Writer, rand io.Reader, header [10]byte, pub *rsa.PublicKey, keyBlock []byte) error {
+	cipherText, err := rsa.EncryptPKCS1v15(rand, pub, keyBlock)
+	if err != nil {
+		return errors.InvalidArgumentError("RSA encryption failed: " + err.Error())
+	}
+
+	packetLen := 10 /* header length */ + 2 /* mpi size */ + len(cipherText)
+
+	err = serializeHeader(w, packetTypeEncryptedKey, packetLen)
+	if err != nil {
+		return err
+	}
+	_, err = w.Write(header[:])
+	if err != nil {
+		return err
+	}
+	return writeMPI(w, 8*uint16(len(cipherText)), cipherText)
+}
+
+func serializeEncryptedKeyElGamal(w io.Writer, rand io.Reader, header [10]byte, pub *elgamal.PublicKey, keyBlock []byte) error {
+	c1, c2, err := elgamal.Encrypt(rand, pub, keyBlock)
+	if err != nil {
+		return errors.InvalidArgumentError("ElGamal encryption failed: " + err.Error())
+	}
+
+	packetLen := 10 /* header length */
+	packetLen += 2 /* mpi size */ + (c1.BitLen()+7)/8
+	packetLen += 2 /* mpi size */ + (c2.BitLen()+7)/8
+
+	err = serializeHeader(w, packetTypeEncryptedKey, packetLen)
+	if err != nil {
+		return err
+	}
+	_, err = w.Write(header[:])
+	if err != nil {
+		return err
+	}
+	err = writeBig(w, c1)
+	if err != nil {
+		return err
+	}
+	return writeBig(w, c2)
+}
diff --git a/vendor/golang.org/x/crypto/openpgp/packet/literal.go b/vendor/golang.org/x/crypto/openpgp/packet/literal.go
new file mode 100644
index 0000000000..1a9ec6e51e
--- /dev/null
+++ b/vendor/golang.org/x/crypto/openpgp/packet/literal.go
@@ -0,0 +1,89 @@
+// Copyright 2011 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 packet
+
+import (
+	"encoding/binary"
+	"io"
+)
+
+// LiteralData represents an encrypted file. See RFC 4880, section 5.9.
+type LiteralData struct {
+	IsBinary bool
+	FileName string
+	Time     uint32 // Unix epoch time. Either creation time or modification time. 0 means undefined.
+	Body     io.Reader
+}
+
+// ForEyesOnly returns whether the contents of the LiteralData have been marked
+// as especially sensitive.
+func (l *LiteralData) ForEyesOnly() bool {
+	return l.FileName == "_CONSOLE"
+}
+
+func (l *LiteralData) parse(r io.Reader) (err error) {
+	var buf [256]byte
+
+	_, err = readFull(r, buf[:2])
+	if err != nil {
+		return
+	}
+
+	l.IsBinary = buf[0] == 'b'
+	fileNameLen := int(buf[1])
+
+	_, err = readFull(r, buf[:fileNameLen])
+	if err != nil {
+		return
+	}
+
+	l.FileName = string(buf[:fileNameLen])
+
+	_, err = readFull(r, buf[:4])
+	if err != nil {
+		return
+	}
+
+	l.Time = binary.BigEndian.Uint32(buf[:4])
+	l.Body = r
+	return
+}
+
+// SerializeLiteral serializes a literal data packet to w and returns a
+// WriteCloser to which the data itself can be written and which MUST be closed
+// on completion. The fileName is truncated to 255 bytes.
+func SerializeLiteral(w io.WriteCloser, isBinary bool, fileName string, time uint32) (plaintext io.WriteCloser, err error) {
+	var buf [4]byte
+	buf[0] = 't'
+	if isBinary {
+		buf[0] = 'b'
+	}
+	if len(fileName) > 255 {
+		fileName = fileName[:255]
+	}
+	buf[1] = byte(len(fileName))
+
+	inner, err := serializeStreamHeader(w, packetTypeLiteralData)
+	if err != nil {
+		return
+	}
+
+	_, err = inner.Write(buf[:2])
+	if err != nil {
+		return
+	}
+	_, err = inner.Write([]byte(fileName))
+	if err != nil {
+		return
+	}
+	binary.BigEndian.PutUint32(buf[:], time)
+	_, err = inner.Write(buf[:])
+	if err != nil {
+		return
+	}
+
+	plaintext = inner
+	return
+}
diff --git a/vendor/golang.org/x/crypto/openpgp/packet/ocfb.go b/vendor/golang.org/x/crypto/openpgp/packet/ocfb.go
new file mode 100644
index 0000000000..ce2a33a547
--- /dev/null
+++ b/vendor/golang.org/x/crypto/openpgp/packet/ocfb.go
@@ -0,0 +1,143 @@
+// Copyright 2010 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.
+
+// OpenPGP CFB Mode. http://tools.ietf.org/html/rfc4880#section-13.9
+
+package packet
+
+import (
+	"crypto/cipher"
+)
+
+type ocfbEncrypter struct {
+	b       cipher.Block
+	fre     []byte
+	outUsed int
+}
+
+// An OCFBResyncOption determines if the "resynchronization step" of OCFB is
+// performed.
+type OCFBResyncOption bool
+
+const (
+	OCFBResync   OCFBResyncOption = true
+	OCFBNoResync OCFBResyncOption = false
+)
+
+// NewOCFBEncrypter returns a cipher.Stream which encrypts data with OpenPGP's
+// cipher feedback mode using the given cipher.Block, and an initial amount of
+// ciphertext.  randData must be random bytes and be the same length as the
+// cipher.Block's block size. Resync determines if the "resynchronization step"
+// from RFC 4880, 13.9 step 7 is performed. Different parts of OpenPGP vary on
+// this point.
+func NewOCFBEncrypter(block cipher.Block, randData []byte, resync OCFBResyncOption) (cipher.Stream, []byte) {
+	blockSize := block.BlockSize()
+	if len(randData) != blockSize {
+		return nil, nil
+	}
+
+	x := &ocfbEncrypter{
+		b:       block,
+		fre:     make([]byte, blockSize),
+		outUsed: 0,
+	}
+	prefix := make([]byte, blockSize+2)
+
+	block.Encrypt(x.fre, x.fre)
+	for i := 0; i < blockSize; i++ {
+		prefix[i] = randData[i] ^ x.fre[i]
+	}
+
+	block.Encrypt(x.fre, prefix[:blockSize])
+	prefix[blockSize] = x.fre[0] ^ randData[blockSize-2]
+	prefix[blockSize+1] = x.fre[1] ^ randData[blockSize-1]
+
+	if resync {
+		block.Encrypt(x.fre, prefix[2:])
+	} else {
+		x.fre[0] = prefix[blockSize]
+		x.fre[1] = prefix[blockSize+1]
+		x.outUsed = 2
+	}
+	return x, prefix
+}
+
+func (x *ocfbEncrypter) XORKeyStream(dst, src []byte) {
+	for i := 0; i < len(src); i++ {
+		if x.outUsed == len(x.fre) {
+			x.b.Encrypt(x.fre, x.fre)
+			x.outUsed = 0
+		}
+
+		x.fre[x.outUsed] ^= src[i]
+		dst[i] = x.fre[x.outUsed]
+		x.outUsed++
+	}
+}
+
+type ocfbDecrypter struct {
+	b       cipher.Block
+	fre     []byte
+	outUsed int
+}
+
+// NewOCFBDecrypter returns a cipher.Stream which decrypts data with OpenPGP's
+// cipher feedback mode using the given cipher.Block. Prefix must be the first
+// blockSize + 2 bytes of the ciphertext, where blockSize is the cipher.Block's
+// block size. If an incorrect key is detected then nil is returned. On
+// successful exit, blockSize+2 bytes of decrypted data are written into
+// prefix. Resync determines if the "resynchronization step" from RFC 4880,
+// 13.9 step 7 is performed. Different parts of OpenPGP vary on this point.
+func NewOCFBDecrypter(block cipher.Block, prefix []byte, resync OCFBResyncOption) cipher.Stream {
+	blockSize := block.BlockSize()
+	if len(prefix) != blockSize+2 {
+		return nil
+	}
+
+	x := &ocfbDecrypter{
+		b:       block,
+		fre:     make([]byte, blockSize),
+		outUsed: 0,
+	}
+	prefixCopy := make([]byte, len(prefix))
+	copy(prefixCopy, prefix)
+
+	block.Encrypt(x.fre, x.fre)
+	for i := 0; i < blockSize; i++ {
+		prefixCopy[i] ^= x.fre[i]
+	}
+
+	block.Encrypt(x.fre, prefix[:blockSize])
+	prefixCopy[blockSize] ^= x.fre[0]
+	prefixCopy[blockSize+1] ^= x.fre[1]
+
+	if prefixCopy[blockSize-2] != prefixCopy[blockSize] ||
+		prefixCopy[blockSize-1] != prefixCopy[blockSize+1] {
+		return nil
+	}
+
+	if resync {
+		block.Encrypt(x.fre, prefix[2:])
+	} else {
+		x.fre[0] = prefix[blockSize]
+		x.fre[1] = prefix[blockSize+1]
+		x.outUsed = 2
+	}
+	copy(prefix, prefixCopy)
+	return x
+}
+
+func (x *ocfbDecrypter) XORKeyStream(dst, src []byte) {
+	for i := 0; i < len(src); i++ {
+		if x.outUsed == len(x.fre) {
+			x.b.Encrypt(x.fre, x.fre)
+			x.outUsed = 0
+		}
+
+		c := src[i]
+		dst[i] = x.fre[x.outUsed] ^ src[i]
+		x.fre[x.outUsed] = c
+		x.outUsed++
+	}
+}
diff --git a/vendor/golang.org/x/crypto/openpgp/packet/one_pass_signature.go b/vendor/golang.org/x/crypto/openpgp/packet/one_pass_signature.go
new file mode 100644
index 0000000000..1713503395
--- /dev/null
+++ b/vendor/golang.org/x/crypto/openpgp/packet/one_pass_signature.go
@@ -0,0 +1,73 @@
+// Copyright 2011 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 packet
+
+import (
+	"crypto"
+	"encoding/binary"
+	"golang.org/x/crypto/openpgp/errors"
+	"golang.org/x/crypto/openpgp/s2k"
+	"io"
+	"strconv"
+)
+
+// OnePassSignature represents a one-pass signature packet. See RFC 4880,
+// section 5.4.
+type OnePassSignature struct {
+	SigType    SignatureType
+	Hash       crypto.Hash
+	PubKeyAlgo PublicKeyAlgorithm
+	KeyId      uint64
+	IsLast     bool
+}
+
+const onePassSignatureVersion = 3
+
+func (ops *OnePassSignature) parse(r io.Reader) (err error) {
+	var buf [13]byte
+
+	_, err = readFull(r, buf[:])
+	if err != nil {
+		return
+	}
+	if buf[0] != onePassSignatureVersion {
+		err = errors.UnsupportedError("one-pass-signature packet version " + strconv.Itoa(int(buf[0])))
+	}
+
+	var ok bool
+	ops.Hash, ok = s2k.HashIdToHash(buf[2])
+	if !ok {
+		return errors.UnsupportedError("hash function: " + strconv.Itoa(int(buf[2])))
+	}
+
+	ops.SigType = SignatureType(buf[1])
+	ops.PubKeyAlgo = PublicKeyAlgorithm(buf[3])
+	ops.KeyId = binary.BigEndian.Uint64(buf[4:12])
+	ops.IsLast = buf[12] != 0
+	return
+}
+
+// Serialize marshals the given OnePassSignature to w.
+func (ops *OnePassSignature) Serialize(w io.Writer) error {
+	var buf [13]byte
+	buf[0] = onePassSignatureVersion
+	buf[1] = uint8(ops.SigType)
+	var ok bool
+	buf[2], ok = s2k.HashToHashId(ops.Hash)
+	if !ok {
+		return errors.UnsupportedError("hash type: " + strconv.Itoa(int(ops.Hash)))
+	}
+	buf[3] = uint8(ops.PubKeyAlgo)
+	binary.BigEndian.PutUint64(buf[4:12], ops.KeyId)
+	if ops.IsLast {
+		buf[12] = 1
+	}
+
+	if err := serializeHeader(w, packetTypeOnePassSignature, len(buf)); err != nil {
+		return err
+	}
+	_, err := w.Write(buf[:])
+	return err
+}
diff --git a/vendor/golang.org/x/crypto/openpgp/packet/opaque.go b/vendor/golang.org/x/crypto/openpgp/packet/opaque.go
new file mode 100644
index 0000000000..456d807f25
--- /dev/null
+++ b/vendor/golang.org/x/crypto/openpgp/packet/opaque.go
@@ -0,0 +1,162 @@
+// 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 packet
+
+import (
+	"bytes"
+	"io"
+	"io/ioutil"
+
+	"golang.org/x/crypto/openpgp/errors"
+)
+
+// OpaquePacket represents an OpenPGP packet as raw, unparsed data. This is
+// useful for splitting and storing the original packet contents separately,
+// handling unsupported packet types or accessing parts of the packet not yet
+// implemented by this package.
+type OpaquePacket struct {
+	// Packet type
+	Tag uint8
+	// Reason why the packet was parsed opaquely
+	Reason error
+	// Binary contents of the packet data
+	Contents []byte
+}
+
+func (op *OpaquePacket) parse(r io.Reader) (err error) {
+	op.Contents, err = ioutil.ReadAll(r)
+	return
+}
+
+// Serialize marshals the packet to a writer in its original form, including
+// the packet header.
+func (op *OpaquePacket) Serialize(w io.Writer) (err error) {
+	err = serializeHeader(w, packetType(op.Tag), len(op.Contents))
+	if err == nil {
+		_, err = w.Write(op.Contents)
+	}
+	return
+}
+
+// Parse attempts to parse the opaque contents into a structure supported by
+// this package. If the packet is not known then the result will be another
+// OpaquePacket.
+func (op *OpaquePacket) Parse() (p Packet, err error) {
+	hdr := bytes.NewBuffer(nil)
+	err = serializeHeader(hdr, packetType(op.Tag), len(op.Contents))
+	if err != nil {
+		op.Reason = err
+		return op, err
+	}
+	p, err = Read(io.MultiReader(hdr, bytes.NewBuffer(op.Contents)))
+	if err != nil {
+		op.Reason = err
+		p = op
+	}
+	return
+}
+
+// OpaqueReader reads OpaquePackets from an io.Reader.
+type OpaqueReader struct {
+	r io.Reader
+}
+
+func NewOpaqueReader(r io.Reader) *OpaqueReader {
+	return &OpaqueReader{r: r}
+}
+
+// Read the next OpaquePacket.
+func (or *OpaqueReader) Next() (op *OpaquePacket, err error) {
+	tag, _, contents, err := readHeader(or.r)
+	if err != nil {
+		return
+	}
+	op = &OpaquePacket{Tag: uint8(tag), Reason: err}
+	err = op.parse(contents)
+	if err != nil {
+		consumeAll(contents)
+	}
+	return
+}
+
+// OpaqueSubpacket represents an unparsed OpenPGP subpacket,
+// as found in signature and user attribute packets.
+type OpaqueSubpacket struct {
+	SubType  uint8
+	Contents []byte
+}
+
+// OpaqueSubpackets extracts opaque, unparsed OpenPGP subpackets from
+// their byte representation.
+func OpaqueSubpackets(contents []byte) (result []*OpaqueSubpacket, err error) {
+	var (
+		subHeaderLen int
+		subPacket    *OpaqueSubpacket
+	)
+	for len(contents) > 0 {
+		subHeaderLen, subPacket, err = nextSubpacket(contents)
+		if err != nil {
+			break
+		}
+		result = append(result, subPacket)
+		contents = contents[subHeaderLen+len(subPacket.Contents):]
+	}
+	return
+}
+
+func nextSubpacket(contents []byte) (subHeaderLen int, subPacket *OpaqueSubpacket, err error) {
+	// RFC 4880, section 5.2.3.1
+	var subLen uint32
+	if len(contents) < 1 {
+		goto Truncated
+	}
+	subPacket = &OpaqueSubpacket{}
+	switch {
+	case contents[0] < 192:
+		subHeaderLen = 2 // 1 length byte, 1 subtype byte
+		if len(contents) < subHeaderLen {
+			goto Truncated
+		}
+		subLen = uint32(contents[0])
+		contents = contents[1:]
+	case contents[0] < 255:
+		subHeaderLen = 3 // 2 length bytes, 1 subtype
+		if len(contents) < subHeaderLen {
+			goto Truncated
+		}
+		subLen = uint32(contents[0]-192)<<8 + uint32(contents[1]) + 192
+		contents = contents[2:]
+	default:
+		subHeaderLen = 6 // 5 length bytes, 1 subtype
+		if len(contents) < subHeaderLen {
+			goto Truncated
+		}
+		subLen = uint32(contents[1])<<24 |
+			uint32(contents[2])<<16 |
+			uint32(contents[3])<<8 |
+			uint32(contents[4])
+		contents = contents[5:]
+	}
+	if subLen > uint32(len(contents)) || subLen == 0 {
+		goto Truncated
+	}
+	subPacket.SubType = contents[0]
+	subPacket.Contents = contents[1:subLen]
+	return
+Truncated:
+	err = errors.StructuralError("subpacket truncated")
+	return
+}
+
+func (osp *OpaqueSubpacket) Serialize(w io.Writer) (err error) {
+	buf := make([]byte, 6)
+	n := serializeSubpacketLength(buf, len(osp.Contents)+1)
+	buf[n] = osp.SubType
+	if _, err = w.Write(buf[:n+1]); err != nil {
+		return
+	}
+	_, err = w.Write(osp.Contents)
+	return
+}
diff --git a/vendor/golang.org/x/crypto/openpgp/packet/packet.go b/vendor/golang.org/x/crypto/openpgp/packet/packet.go
new file mode 100644
index 0000000000..0a19794a8e
--- /dev/null
+++ b/vendor/golang.org/x/crypto/openpgp/packet/packet.go
@@ -0,0 +1,590 @@
+// Copyright 2011 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 packet implements parsing and serialization of OpenPGP packets, as
+// specified in RFC 4880.
+//
+// Deprecated: this package is unmaintained except for security fixes. New
+// applications should consider a more focused, modern alternative to OpenPGP
+// for their specific task. If you are required to interoperate with OpenPGP
+// systems and need a maintained package, consider a community fork.
+// See https://golang.org/issue/44226.
+package packet // import "golang.org/x/crypto/openpgp/packet"
+
+import (
+	"bufio"
+	"crypto/aes"
+	"crypto/cipher"
+	"crypto/des"
+	"crypto/rsa"
+	"io"
+	"math/big"
+	"math/bits"
+
+	"golang.org/x/crypto/cast5"
+	"golang.org/x/crypto/openpgp/errors"
+)
+
+// readFull is the same as io.ReadFull except that reading zero bytes returns
+// ErrUnexpectedEOF rather than EOF.
+func readFull(r io.Reader, buf []byte) (n int, err error) {
+	n, err = io.ReadFull(r, buf)
+	if err == io.EOF {
+		err = io.ErrUnexpectedEOF
+	}
+	return
+}
+
+// readLength reads an OpenPGP length from r. See RFC 4880, section 4.2.2.
+func readLength(r io.Reader) (length int64, isPartial bool, err error) {
+	var buf [4]byte
+	_, err = readFull(r, buf[:1])
+	if err != nil {
+		return
+	}
+	switch {
+	case buf[0] < 192:
+		length = int64(buf[0])
+	case buf[0] < 224:
+		length = int64(buf[0]-192) << 8
+		_, err = readFull(r, buf[0:1])
+		if err != nil {
+			return
+		}
+		length += int64(buf[0]) + 192
+	case buf[0] < 255:
+		length = int64(1) << (buf[0] & 0x1f)
+		isPartial = true
+	default:
+		_, err = readFull(r, buf[0:4])
+		if err != nil {
+			return
+		}
+		length = int64(buf[0])<<24 |
+			int64(buf[1])<<16 |
+			int64(buf[2])<<8 |
+			int64(buf[3])
+	}
+	return
+}
+
+// partialLengthReader wraps an io.Reader and handles OpenPGP partial lengths.
+// The continuation lengths are parsed and removed from the stream and EOF is
+// returned at the end of the packet. See RFC 4880, section 4.2.2.4.
+type partialLengthReader struct {
+	r         io.Reader
+	remaining int64
+	isPartial bool
+}
+
+func (r *partialLengthReader) Read(p []byte) (n int, err error) {
+	for r.remaining == 0 {
+		if !r.isPartial {
+			return 0, io.EOF
+		}
+		r.remaining, r.isPartial, err = readLength(r.r)
+		if err != nil {
+			return 0, err
+		}
+	}
+
+	toRead := int64(len(p))
+	if toRead > r.remaining {
+		toRead = r.remaining
+	}
+
+	n, err = r.r.Read(p[:int(toRead)])
+	r.remaining -= int64(n)
+	if n < int(toRead) && err == io.EOF {
+		err = io.ErrUnexpectedEOF
+	}
+	return
+}
+
+// partialLengthWriter writes a stream of data using OpenPGP partial lengths.
+// See RFC 4880, section 4.2.2.4.
+type partialLengthWriter struct {
+	w          io.WriteCloser
+	lengthByte [1]byte
+	sentFirst  bool
+	buf        []byte
+}
+
+// RFC 4880 4.2.2.4: the first partial length MUST be at least 512 octets long.
+const minFirstPartialWrite = 512
+
+func (w *partialLengthWriter) Write(p []byte) (n int, err error) {
+	off := 0
+	if !w.sentFirst {
+		if len(w.buf) > 0 || len(p) < minFirstPartialWrite {
+			off = len(w.buf)
+			w.buf = append(w.buf, p...)
+			if len(w.buf) < minFirstPartialWrite {
+				return len(p), nil
+			}
+			p = w.buf
+			w.buf = nil
+		}
+		w.sentFirst = true
+	}
+
+	power := uint8(30)
+	for len(p) > 0 {
+		l := 1 << power
+		if len(p) < l {
+			power = uint8(bits.Len32(uint32(len(p)))) - 1
+			l = 1 << power
+		}
+		w.lengthByte[0] = 224 + power
+		_, err = w.w.Write(w.lengthByte[:])
+		if err == nil {
+			var m int
+			m, err = w.w.Write(p[:l])
+			n += m
+		}
+		if err != nil {
+			if n < off {
+				return 0, err
+			}
+			return n - off, err
+		}
+		p = p[l:]
+	}
+	return n - off, nil
+}
+
+func (w *partialLengthWriter) Close() error {
+	if len(w.buf) > 0 {
+		// In this case we can't send a 512 byte packet.
+		// Just send what we have.
+		p := w.buf
+		w.sentFirst = true
+		w.buf = nil
+		if _, err := w.Write(p); err != nil {
+			return err
+		}
+	}
+
+	w.lengthByte[0] = 0
+	_, err := w.w.Write(w.lengthByte[:])
+	if err != nil {
+		return err
+	}
+	return w.w.Close()
+}
+
+// A spanReader is an io.LimitReader, but it returns ErrUnexpectedEOF if the
+// underlying Reader returns EOF before the limit has been reached.
+type spanReader struct {
+	r io.Reader
+	n int64
+}
+
+func (l *spanReader) Read(p []byte) (n int, err error) {
+	if l.n <= 0 {
+		return 0, io.EOF
+	}
+	if int64(len(p)) > l.n {
+		p = p[0:l.n]
+	}
+	n, err = l.r.Read(p)
+	l.n -= int64(n)
+	if l.n > 0 && err == io.EOF {
+		err = io.ErrUnexpectedEOF
+	}
+	return
+}
+
+// readHeader parses a packet header and returns an io.Reader which will return
+// the contents of the packet. See RFC 4880, section 4.2.
+func readHeader(r io.Reader) (tag packetType, length int64, contents io.Reader, err error) {
+	var buf [4]byte
+	_, err = io.ReadFull(r, buf[:1])
+	if err != nil {
+		return
+	}
+	if buf[0]&0x80 == 0 {
+		err = errors.StructuralError("tag byte does not have MSB set")
+		return
+	}
+	if buf[0]&0x40 == 0 {
+		// Old format packet
+		tag = packetType((buf[0] & 0x3f) >> 2)
+		lengthType := buf[0] & 3
+		if lengthType == 3 {
+			length = -1
+			contents = r
+			return
+		}
+		lengthBytes := 1 << lengthType
+		_, err = readFull(r, buf[0:lengthBytes])
+		if err != nil {
+			return
+		}
+		for i := 0; i < lengthBytes; i++ {
+			length <<= 8
+			length |= int64(buf[i])
+		}
+		contents = &spanReader{r, length}
+		return
+	}
+
+	// New format packet
+	tag = packetType(buf[0] & 0x3f)
+	length, isPartial, err := readLength(r)
+	if err != nil {
+		return
+	}
+	if isPartial {
+		contents = &partialLengthReader{
+			remaining: length,
+			isPartial: true,
+			r:         r,
+		}
+		length = -1
+	} else {
+		contents = &spanReader{r, length}
+	}
+	return
+}
+
+// serializeHeader writes an OpenPGP packet header to w. See RFC 4880, section
+// 4.2.
+func serializeHeader(w io.Writer, ptype packetType, length int) (err error) {
+	var buf [6]byte
+	var n int
+
+	buf[0] = 0x80 | 0x40 | byte(ptype)
+	if length < 192 {
+		buf[1] = byte(length)
+		n = 2
+	} else if length < 8384 {
+		length -= 192
+		buf[1] = 192 + byte(length>>8)
+		buf[2] = byte(length)
+		n = 3
+	} else {
+		buf[1] = 255
+		buf[2] = byte(length >> 24)
+		buf[3] = byte(length >> 16)
+		buf[4] = byte(length >> 8)
+		buf[5] = byte(length)
+		n = 6
+	}
+
+	_, err = w.Write(buf[:n])
+	return
+}
+
+// serializeStreamHeader writes an OpenPGP packet header to w where the
+// length of the packet is unknown. It returns a io.WriteCloser which can be
+// used to write the contents of the packet. See RFC 4880, section 4.2.
+func serializeStreamHeader(w io.WriteCloser, ptype packetType) (out io.WriteCloser, err error) {
+	var buf [1]byte
+	buf[0] = 0x80 | 0x40 | byte(ptype)
+	_, err = w.Write(buf[:])
+	if err != nil {
+		return
+	}
+	out = &partialLengthWriter{w: w}
+	return
+}
+
+// Packet represents an OpenPGP packet. Users are expected to try casting
+// instances of this interface to specific packet types.
+type Packet interface {
+	parse(io.Reader) error
+}
+
+// consumeAll reads from the given Reader until error, returning the number of
+// bytes read.
+func consumeAll(r io.Reader) (n int64, err error) {
+	var m int
+	var buf [1024]byte
+
+	for {
+		m, err = r.Read(buf[:])
+		n += int64(m)
+		if err == io.EOF {
+			err = nil
+			return
+		}
+		if err != nil {
+			return
+		}
+	}
+}
+
+// packetType represents the numeric ids of the different OpenPGP packet types. See
+// http://www.iana.org/assignments/pgp-parameters/pgp-parameters.xhtml#pgp-parameters-2
+type packetType uint8
+
+const (
+	packetTypeEncryptedKey              packetType = 1
+	packetTypeSignature                 packetType = 2
+	packetTypeSymmetricKeyEncrypted     packetType = 3
+	packetTypeOnePassSignature          packetType = 4
+	packetTypePrivateKey                packetType = 5
+	packetTypePublicKey                 packetType = 6
+	packetTypePrivateSubkey             packetType = 7
+	packetTypeCompressed                packetType = 8
+	packetTypeSymmetricallyEncrypted    packetType = 9
+	packetTypeLiteralData               packetType = 11
+	packetTypeUserId                    packetType = 13
+	packetTypePublicSubkey              packetType = 14
+	packetTypeUserAttribute             packetType = 17
+	packetTypeSymmetricallyEncryptedMDC packetType = 18
+)
+
+// peekVersion detects the version of a public key packet about to
+// be read. A bufio.Reader at the original position of the io.Reader
+// is returned.
+func peekVersion(r io.Reader) (bufr *bufio.Reader, ver byte, err error) {
+	bufr = bufio.NewReader(r)
+	var verBuf []byte
+	if verBuf, err = bufr.Peek(1); err != nil {
+		return
+	}
+	ver = verBuf[0]
+	return
+}
+
+// Read reads a single OpenPGP packet from the given io.Reader. If there is an
+// error parsing a packet, the whole packet is consumed from the input.
+func Read(r io.Reader) (p Packet, err error) {
+	tag, _, contents, err := readHeader(r)
+	if err != nil {
+		return
+	}
+
+	switch tag {
+	case packetTypeEncryptedKey:
+		p = new(EncryptedKey)
+	case packetTypeSignature:
+		var version byte
+		// Detect signature version
+		if contents, version, err = peekVersion(contents); err != nil {
+			return
+		}
+		if version < 4 {
+			p = new(SignatureV3)
+		} else {
+			p = new(Signature)
+		}
+	case packetTypeSymmetricKeyEncrypted:
+		p = new(SymmetricKeyEncrypted)
+	case packetTypeOnePassSignature:
+		p = new(OnePassSignature)
+	case packetTypePrivateKey, packetTypePrivateSubkey:
+		pk := new(PrivateKey)
+		if tag == packetTypePrivateSubkey {
+			pk.IsSubkey = true
+		}
+		p = pk
+	case packetTypePublicKey, packetTypePublicSubkey:
+		var version byte
+		if contents, version, err = peekVersion(contents); err != nil {
+			return
+		}
+		isSubkey := tag == packetTypePublicSubkey
+		if version < 4 {
+			p = &PublicKeyV3{IsSubkey: isSubkey}
+		} else {
+			p = &PublicKey{IsSubkey: isSubkey}
+		}
+	case packetTypeCompressed:
+		p = new(Compressed)
+	case packetTypeSymmetricallyEncrypted:
+		p = new(SymmetricallyEncrypted)
+	case packetTypeLiteralData:
+		p = new(LiteralData)
+	case packetTypeUserId:
+		p = new(UserId)
+	case packetTypeUserAttribute:
+		p = new(UserAttribute)
+	case packetTypeSymmetricallyEncryptedMDC:
+		se := new(SymmetricallyEncrypted)
+		se.MDC = true
+		p = se
+	default:
+		err = errors.UnknownPacketTypeError(tag)
+	}
+	if p != nil {
+		err = p.parse(contents)
+	}
+	if err != nil {
+		consumeAll(contents)
+	}
+	return
+}
+
+// SignatureType represents the different semantic meanings of an OpenPGP
+// signature. See RFC 4880, section 5.2.1.
+type SignatureType uint8
+
+const (
+	SigTypeBinary            SignatureType = 0
+	SigTypeText                            = 1
+	SigTypeGenericCert                     = 0x10
+	SigTypePersonaCert                     = 0x11
+	SigTypeCasualCert                      = 0x12
+	SigTypePositiveCert                    = 0x13
+	SigTypeSubkeyBinding                   = 0x18
+	SigTypePrimaryKeyBinding               = 0x19
+	SigTypeDirectSignature                 = 0x1F
+	SigTypeKeyRevocation                   = 0x20
+	SigTypeSubkeyRevocation                = 0x28
+)
+
+// PublicKeyAlgorithm represents the different public key system specified for
+// OpenPGP. See
+// http://www.iana.org/assignments/pgp-parameters/pgp-parameters.xhtml#pgp-parameters-12
+type PublicKeyAlgorithm uint8
+
+const (
+	PubKeyAlgoRSA     PublicKeyAlgorithm = 1
+	PubKeyAlgoElGamal PublicKeyAlgorithm = 16
+	PubKeyAlgoDSA     PublicKeyAlgorithm = 17
+	// RFC 6637, Section 5.
+	PubKeyAlgoECDH  PublicKeyAlgorithm = 18
+	PubKeyAlgoECDSA PublicKeyAlgorithm = 19
+
+	// Deprecated in RFC 4880, Section 13.5. Use key flags instead.
+	PubKeyAlgoRSAEncryptOnly PublicKeyAlgorithm = 2
+	PubKeyAlgoRSASignOnly    PublicKeyAlgorithm = 3
+)
+
+// CanEncrypt returns true if it's possible to encrypt a message to a public
+// key of the given type.
+func (pka PublicKeyAlgorithm) CanEncrypt() bool {
+	switch pka {
+	case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoElGamal:
+		return true
+	}
+	return false
+}
+
+// CanSign returns true if it's possible for a public key of the given type to
+// sign a message.
+func (pka PublicKeyAlgorithm) CanSign() bool {
+	switch pka {
+	case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly, PubKeyAlgoDSA, PubKeyAlgoECDSA:
+		return true
+	}
+	return false
+}
+
+// CipherFunction represents the different block ciphers specified for OpenPGP. See
+// http://www.iana.org/assignments/pgp-parameters/pgp-parameters.xhtml#pgp-parameters-13
+type CipherFunction uint8
+
+const (
+	Cipher3DES   CipherFunction = 2
+	CipherCAST5  CipherFunction = 3
+	CipherAES128 CipherFunction = 7
+	CipherAES192 CipherFunction = 8
+	CipherAES256 CipherFunction = 9
+)
+
+// KeySize returns the key size, in bytes, of cipher.
+func (cipher CipherFunction) KeySize() int {
+	switch cipher {
+	case Cipher3DES:
+		return 24
+	case CipherCAST5:
+		return cast5.KeySize
+	case CipherAES128:
+		return 16
+	case CipherAES192:
+		return 24
+	case CipherAES256:
+		return 32
+	}
+	return 0
+}
+
+// blockSize returns the block size, in bytes, of cipher.
+func (cipher CipherFunction) blockSize() int {
+	switch cipher {
+	case Cipher3DES:
+		return des.BlockSize
+	case CipherCAST5:
+		return 8
+	case CipherAES128, CipherAES192, CipherAES256:
+		return 16
+	}
+	return 0
+}
+
+// new returns a fresh instance of the given cipher.
+func (cipher CipherFunction) new(key []byte) (block cipher.Block) {
+	switch cipher {
+	case Cipher3DES:
+		block, _ = des.NewTripleDESCipher(key)
+	case CipherCAST5:
+		block, _ = cast5.NewCipher(key)
+	case CipherAES128, CipherAES192, CipherAES256:
+		block, _ = aes.NewCipher(key)
+	}
+	return
+}
+
+// readMPI reads a big integer from r. The bit length returned is the bit
+// length that was specified in r. This is preserved so that the integer can be
+// reserialized exactly.
+func readMPI(r io.Reader) (mpi []byte, bitLength uint16, err error) {
+	var buf [2]byte
+	_, err = readFull(r, buf[0:])
+	if err != nil {
+		return
+	}
+	bitLength = uint16(buf[0])<<8 | uint16(buf[1])
+	numBytes := (int(bitLength) + 7) / 8
+	mpi = make([]byte, numBytes)
+	_, err = readFull(r, mpi)
+	// According to RFC 4880 3.2. we should check that the MPI has no leading
+	// zeroes (at least when not an encrypted MPI?), but this implementation
+	// does generate leading zeroes, so we keep accepting them.
+	return
+}
+
+// writeMPI serializes a big integer to w.
+func writeMPI(w io.Writer, bitLength uint16, mpiBytes []byte) (err error) {
+	// Note that we can produce leading zeroes, in violation of RFC 4880 3.2.
+	// Implementations seem to be tolerant of them, and stripping them would
+	// make it complex to guarantee matching re-serialization.
+	_, err = w.Write([]byte{byte(bitLength >> 8), byte(bitLength)})
+	if err == nil {
+		_, err = w.Write(mpiBytes)
+	}
+	return
+}
+
+// writeBig serializes a *big.Int to w.
+func writeBig(w io.Writer, i *big.Int) error {
+	return writeMPI(w, uint16(i.BitLen()), i.Bytes())
+}
+
+// padToKeySize left-pads a MPI with zeroes to match the length of the
+// specified RSA public.
+func padToKeySize(pub *rsa.PublicKey, b []byte) []byte {
+	k := (pub.N.BitLen() + 7) / 8
+	if len(b) >= k {
+		return b
+	}
+	bb := make([]byte, k)
+	copy(bb[len(bb)-len(b):], b)
+	return bb
+}
+
+// CompressionAlgo Represents the different compression algorithms
+// supported by OpenPGP (except for BZIP2, which is not currently
+// supported). See Section 9.3 of RFC 4880.
+type CompressionAlgo uint8
+
+const (
+	CompressionNone CompressionAlgo = 0
+	CompressionZIP  CompressionAlgo = 1
+	CompressionZLIB CompressionAlgo = 2
+)
diff --git a/vendor/golang.org/x/crypto/openpgp/packet/private_key.go b/vendor/golang.org/x/crypto/openpgp/packet/private_key.go
new file mode 100644
index 0000000000..81abb7cef9
--- /dev/null
+++ b/vendor/golang.org/x/crypto/openpgp/packet/private_key.go
@@ -0,0 +1,385 @@
+// Copyright 2011 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 packet
+
+import (
+	"bytes"
+	"crypto"
+	"crypto/cipher"
+	"crypto/dsa"
+	"crypto/ecdsa"
+	"crypto/rsa"
+	"crypto/sha1"
+	"io"
+	"io/ioutil"
+	"math/big"
+	"strconv"
+	"time"
+
+	"golang.org/x/crypto/openpgp/elgamal"
+	"golang.org/x/crypto/openpgp/errors"
+	"golang.org/x/crypto/openpgp/s2k"
+)
+
+// PrivateKey represents a possibly encrypted private key. See RFC 4880,
+// section 5.5.3.
+type PrivateKey struct {
+	PublicKey
+	Encrypted     bool // if true then the private key is unavailable until Decrypt has been called.
+	encryptedData []byte
+	cipher        CipherFunction
+	s2k           func(out, in []byte)
+	PrivateKey    interface{} // An *{rsa|dsa|ecdsa}.PrivateKey or crypto.Signer/crypto.Decrypter (Decryptor RSA only).
+	sha1Checksum  bool
+	iv            []byte
+}
+
+func NewRSAPrivateKey(creationTime time.Time, priv *rsa.PrivateKey) *PrivateKey {
+	pk := new(PrivateKey)
+	pk.PublicKey = *NewRSAPublicKey(creationTime, &priv.PublicKey)
+	pk.PrivateKey = priv
+	return pk
+}
+
+func NewDSAPrivateKey(creationTime time.Time, priv *dsa.PrivateKey) *PrivateKey {
+	pk := new(PrivateKey)
+	pk.PublicKey = *NewDSAPublicKey(creationTime, &priv.PublicKey)
+	pk.PrivateKey = priv
+	return pk
+}
+
+func NewElGamalPrivateKey(creationTime time.Time, priv *elgamal.PrivateKey) *PrivateKey {
+	pk := new(PrivateKey)
+	pk.PublicKey = *NewElGamalPublicKey(creationTime, &priv.PublicKey)
+	pk.PrivateKey = priv
+	return pk
+}
+
+func NewECDSAPrivateKey(creationTime time.Time, priv *ecdsa.PrivateKey) *PrivateKey {
+	pk := new(PrivateKey)
+	pk.PublicKey = *NewECDSAPublicKey(creationTime, &priv.PublicKey)
+	pk.PrivateKey = priv
+	return pk
+}
+
+// NewSignerPrivateKey creates a PrivateKey from a crypto.Signer that
+// implements RSA or ECDSA.
+func NewSignerPrivateKey(creationTime time.Time, signer crypto.Signer) *PrivateKey {
+	pk := new(PrivateKey)
+	// In general, the public Keys should be used as pointers. We still
+	// type-switch on the values, for backwards-compatibility.
+	switch pubkey := signer.Public().(type) {
+	case *rsa.PublicKey:
+		pk.PublicKey = *NewRSAPublicKey(creationTime, pubkey)
+	case rsa.PublicKey:
+		pk.PublicKey = *NewRSAPublicKey(creationTime, &pubkey)
+	case *ecdsa.PublicKey:
+		pk.PublicKey = *NewECDSAPublicKey(creationTime, pubkey)
+	case ecdsa.PublicKey:
+		pk.PublicKey = *NewECDSAPublicKey(creationTime, &pubkey)
+	default:
+		panic("openpgp: unknown crypto.Signer type in NewSignerPrivateKey")
+	}
+	pk.PrivateKey = signer
+	return pk
+}
+
+func (pk *PrivateKey) parse(r io.Reader) (err error) {
+	err = (&pk.PublicKey).parse(r)
+	if err != nil {
+		return
+	}
+	var buf [1]byte
+	_, err = readFull(r, buf[:])
+	if err != nil {
+		return
+	}
+
+	s2kType := buf[0]
+
+	switch s2kType {
+	case 0:
+		pk.s2k = nil
+		pk.Encrypted = false
+	case 254, 255:
+		_, err = readFull(r, buf[:])
+		if err != nil {
+			return
+		}
+		pk.cipher = CipherFunction(buf[0])
+		pk.Encrypted = true
+		pk.s2k, err = s2k.Parse(r)
+		if err != nil {
+			return
+		}
+		if s2kType == 254 {
+			pk.sha1Checksum = true
+		}
+	default:
+		return errors.UnsupportedError("deprecated s2k function in private key")
+	}
+
+	if pk.Encrypted {
+		blockSize := pk.cipher.blockSize()
+		if blockSize == 0 {
+			return errors.UnsupportedError("unsupported cipher in private key: " + strconv.Itoa(int(pk.cipher)))
+		}
+		pk.iv = make([]byte, blockSize)
+		_, err = readFull(r, pk.iv)
+		if err != nil {
+			return
+		}
+	}
+
+	pk.encryptedData, err = ioutil.ReadAll(r)
+	if err != nil {
+		return
+	}
+
+	if !pk.Encrypted {
+		return pk.parsePrivateKey(pk.encryptedData)
+	}
+
+	return
+}
+
+func mod64kHash(d []byte) uint16 {
+	var h uint16
+	for _, b := range d {
+		h += uint16(b)
+	}
+	return h
+}
+
+func (pk *PrivateKey) Serialize(w io.Writer) (err error) {
+	// TODO(agl): support encrypted private keys
+	buf := bytes.NewBuffer(nil)
+	err = pk.PublicKey.serializeWithoutHeaders(buf)
+	if err != nil {
+		return
+	}
+	buf.WriteByte(0 /* no encryption */)
+
+	privateKeyBuf := bytes.NewBuffer(nil)
+
+	switch priv := pk.PrivateKey.(type) {
+	case *rsa.PrivateKey:
+		err = serializeRSAPrivateKey(privateKeyBuf, priv)
+	case *dsa.PrivateKey:
+		err = serializeDSAPrivateKey(privateKeyBuf, priv)
+	case *elgamal.PrivateKey:
+		err = serializeElGamalPrivateKey(privateKeyBuf, priv)
+	case *ecdsa.PrivateKey:
+		err = serializeECDSAPrivateKey(privateKeyBuf, priv)
+	default:
+		err = errors.InvalidArgumentError("unknown private key type")
+	}
+	if err != nil {
+		return
+	}
+
+	ptype := packetTypePrivateKey
+	contents := buf.Bytes()
+	privateKeyBytes := privateKeyBuf.Bytes()
+	if pk.IsSubkey {
+		ptype = packetTypePrivateSubkey
+	}
+	err = serializeHeader(w, ptype, len(contents)+len(privateKeyBytes)+2)
+	if err != nil {
+		return
+	}
+	_, err = w.Write(contents)
+	if err != nil {
+		return
+	}
+	_, err = w.Write(privateKeyBytes)
+	if err != nil {
+		return
+	}
+
+	checksum := mod64kHash(privateKeyBytes)
+	var checksumBytes [2]byte
+	checksumBytes[0] = byte(checksum >> 8)
+	checksumBytes[1] = byte(checksum)
+	_, err = w.Write(checksumBytes[:])
+
+	return
+}
+
+func serializeRSAPrivateKey(w io.Writer, priv *rsa.PrivateKey) error {
+	err := writeBig(w, priv.D)
+	if err != nil {
+		return err
+	}
+	err = writeBig(w, priv.Primes[1])
+	if err != nil {
+		return err
+	}
+	err = writeBig(w, priv.Primes[0])
+	if err != nil {
+		return err
+	}
+	return writeBig(w, priv.Precomputed.Qinv)
+}
+
+func serializeDSAPrivateKey(w io.Writer, priv *dsa.PrivateKey) error {
+	return writeBig(w, priv.X)
+}
+
+func serializeElGamalPrivateKey(w io.Writer, priv *elgamal.PrivateKey) error {
+	return writeBig(w, priv.X)
+}
+
+func serializeECDSAPrivateKey(w io.Writer, priv *ecdsa.PrivateKey) error {
+	return writeBig(w, priv.D)
+}
+
+// Decrypt decrypts an encrypted private key using a passphrase.
+func (pk *PrivateKey) Decrypt(passphrase []byte) error {
+	if !pk.Encrypted {
+		return nil
+	}
+
+	key := make([]byte, pk.cipher.KeySize())
+	pk.s2k(key, passphrase)
+	block := pk.cipher.new(key)
+	cfb := cipher.NewCFBDecrypter(block, pk.iv)
+
+	data := make([]byte, len(pk.encryptedData))
+	cfb.XORKeyStream(data, pk.encryptedData)
+
+	if pk.sha1Checksum {
+		if len(data) < sha1.Size {
+			return errors.StructuralError("truncated private key data")
+		}
+		h := sha1.New()
+		h.Write(data[:len(data)-sha1.Size])
+		sum := h.Sum(nil)
+		if !bytes.Equal(sum, data[len(data)-sha1.Size:]) {
+			return errors.StructuralError("private key checksum failure")
+		}
+		data = data[:len(data)-sha1.Size]
+	} else {
+		if len(data) < 2 {
+			return errors.StructuralError("truncated private key data")
+		}
+		var sum uint16
+		for i := 0; i < len(data)-2; i++ {
+			sum += uint16(data[i])
+		}
+		if data[len(data)-2] != uint8(sum>>8) ||
+			data[len(data)-1] != uint8(sum) {
+			return errors.StructuralError("private key checksum failure")
+		}
+		data = data[:len(data)-2]
+	}
+
+	return pk.parsePrivateKey(data)
+}
+
+func (pk *PrivateKey) parsePrivateKey(data []byte) (err error) {
+	switch pk.PublicKey.PubKeyAlgo {
+	case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly, PubKeyAlgoRSAEncryptOnly:
+		return pk.parseRSAPrivateKey(data)
+	case PubKeyAlgoDSA:
+		return pk.parseDSAPrivateKey(data)
+	case PubKeyAlgoElGamal:
+		return pk.parseElGamalPrivateKey(data)
+	case PubKeyAlgoECDSA:
+		return pk.parseECDSAPrivateKey(data)
+	}
+	panic("impossible")
+}
+
+func (pk *PrivateKey) parseRSAPrivateKey(data []byte) (err error) {
+	rsaPub := pk.PublicKey.PublicKey.(*rsa.PublicKey)
+	rsaPriv := new(rsa.PrivateKey)
+	rsaPriv.PublicKey = *rsaPub
+
+	buf := bytes.NewBuffer(data)
+	d, _, err := readMPI(buf)
+	if err != nil {
+		return
+	}
+	p, _, err := readMPI(buf)
+	if err != nil {
+		return
+	}
+	q, _, err := readMPI(buf)
+	if err != nil {
+		return
+	}
+
+	rsaPriv.D = new(big.Int).SetBytes(d)
+	rsaPriv.Primes = make([]*big.Int, 2)
+	rsaPriv.Primes[0] = new(big.Int).SetBytes(p)
+	rsaPriv.Primes[1] = new(big.Int).SetBytes(q)
+	if err := rsaPriv.Validate(); err != nil {
+		return err
+	}
+	rsaPriv.Precompute()
+	pk.PrivateKey = rsaPriv
+	pk.Encrypted = false
+	pk.encryptedData = nil
+
+	return nil
+}
+
+func (pk *PrivateKey) parseDSAPrivateKey(data []byte) (err error) {
+	dsaPub := pk.PublicKey.PublicKey.(*dsa.PublicKey)
+	dsaPriv := new(dsa.PrivateKey)
+	dsaPriv.PublicKey = *dsaPub
+
+	buf := bytes.NewBuffer(data)
+	x, _, err := readMPI(buf)
+	if err != nil {
+		return
+	}
+
+	dsaPriv.X = new(big.Int).SetBytes(x)
+	pk.PrivateKey = dsaPriv
+	pk.Encrypted = false
+	pk.encryptedData = nil
+
+	return nil
+}
+
+func (pk *PrivateKey) parseElGamalPrivateKey(data []byte) (err error) {
+	pub := pk.PublicKey.PublicKey.(*elgamal.PublicKey)
+	priv := new(elgamal.PrivateKey)
+	priv.PublicKey = *pub
+
+	buf := bytes.NewBuffer(data)
+	x, _, err := readMPI(buf)
+	if err != nil {
+		return
+	}
+
+	priv.X = new(big.Int).SetBytes(x)
+	pk.PrivateKey = priv
+	pk.Encrypted = false
+	pk.encryptedData = nil
+
+	return nil
+}
+
+func (pk *PrivateKey) parseECDSAPrivateKey(data []byte) (err error) {
+	ecdsaPub := pk.PublicKey.PublicKey.(*ecdsa.PublicKey)
+
+	buf := bytes.NewBuffer(data)
+	d, _, err := readMPI(buf)
+	if err != nil {
+		return
+	}
+
+	pk.PrivateKey = &ecdsa.PrivateKey{
+		PublicKey: *ecdsaPub,
+		D:         new(big.Int).SetBytes(d),
+	}
+	pk.Encrypted = false
+	pk.encryptedData = nil
+
+	return nil
+}
diff --git a/vendor/golang.org/x/crypto/openpgp/packet/public_key.go b/vendor/golang.org/x/crypto/openpgp/packet/public_key.go
new file mode 100644
index 0000000000..fcd5f52519
--- /dev/null
+++ b/vendor/golang.org/x/crypto/openpgp/packet/public_key.go
@@ -0,0 +1,753 @@
+// Copyright 2011 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 packet
+
+import (
+	"bytes"
+	"crypto"
+	"crypto/dsa"
+	"crypto/ecdsa"
+	"crypto/elliptic"
+	"crypto/rsa"
+	"crypto/sha1"
+	_ "crypto/sha256"
+	_ "crypto/sha512"
+	"encoding/binary"
+	"fmt"
+	"hash"
+	"io"
+	"math/big"
+	"strconv"
+	"time"
+
+	"golang.org/x/crypto/openpgp/elgamal"
+	"golang.org/x/crypto/openpgp/errors"
+)
+
+var (
+	// NIST curve P-256
+	oidCurveP256 []byte = []byte{0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07}
+	// NIST curve P-384
+	oidCurveP384 []byte = []byte{0x2B, 0x81, 0x04, 0x00, 0x22}
+	// NIST curve P-521
+	oidCurveP521 []byte = []byte{0x2B, 0x81, 0x04, 0x00, 0x23}
+)
+
+const maxOIDLength = 8
+
+// ecdsaKey stores the algorithm-specific fields for ECDSA keys.
+// as defined in RFC 6637, Section 9.
+type ecdsaKey struct {
+	// oid contains the OID byte sequence identifying the elliptic curve used
+	oid []byte
+	// p contains the elliptic curve point that represents the public key
+	p parsedMPI
+}
+
+// parseOID reads the OID for the curve as defined in RFC 6637, Section 9.
+func parseOID(r io.Reader) (oid []byte, err error) {
+	buf := make([]byte, maxOIDLength)
+	if _, err = readFull(r, buf[:1]); err != nil {
+		return
+	}
+	oidLen := buf[0]
+	if int(oidLen) > len(buf) {
+		err = errors.UnsupportedError("invalid oid length: " + strconv.Itoa(int(oidLen)))
+		return
+	}
+	oid = buf[:oidLen]
+	_, err = readFull(r, oid)
+	return
+}
+
+func (f *ecdsaKey) parse(r io.Reader) (err error) {
+	if f.oid, err = parseOID(r); err != nil {
+		return err
+	}
+	f.p.bytes, f.p.bitLength, err = readMPI(r)
+	return
+}
+
+func (f *ecdsaKey) serialize(w io.Writer) (err error) {
+	buf := make([]byte, maxOIDLength+1)
+	buf[0] = byte(len(f.oid))
+	copy(buf[1:], f.oid)
+	if _, err = w.Write(buf[:len(f.oid)+1]); err != nil {
+		return
+	}
+	return writeMPIs(w, f.p)
+}
+
+func (f *ecdsaKey) newECDSA() (*ecdsa.PublicKey, error) {
+	var c elliptic.Curve
+	if bytes.Equal(f.oid, oidCurveP256) {
+		c = elliptic.P256()
+	} else if bytes.Equal(f.oid, oidCurveP384) {
+		c = elliptic.P384()
+	} else if bytes.Equal(f.oid, oidCurveP521) {
+		c = elliptic.P521()
+	} else {
+		return nil, errors.UnsupportedError(fmt.Sprintf("unsupported oid: %x", f.oid))
+	}
+	x, y := elliptic.Unmarshal(c, f.p.bytes)
+	if x == nil {
+		return nil, errors.UnsupportedError("failed to parse EC point")
+	}
+	return &ecdsa.PublicKey{Curve: c, X: x, Y: y}, nil
+}
+
+func (f *ecdsaKey) byteLen() int {
+	return 1 + len(f.oid) + 2 + len(f.p.bytes)
+}
+
+type kdfHashFunction byte
+type kdfAlgorithm byte
+
+// ecdhKdf stores key derivation function parameters
+// used for ECDH encryption. See RFC 6637, Section 9.
+type ecdhKdf struct {
+	KdfHash kdfHashFunction
+	KdfAlgo kdfAlgorithm
+}
+
+func (f *ecdhKdf) parse(r io.Reader) (err error) {
+	buf := make([]byte, 1)
+	if _, err = readFull(r, buf); err != nil {
+		return
+	}
+	kdfLen := int(buf[0])
+	if kdfLen < 3 {
+		return errors.UnsupportedError("Unsupported ECDH KDF length: " + strconv.Itoa(kdfLen))
+	}
+	buf = make([]byte, kdfLen)
+	if _, err = readFull(r, buf); err != nil {
+		return
+	}
+	reserved := int(buf[0])
+	f.KdfHash = kdfHashFunction(buf[1])
+	f.KdfAlgo = kdfAlgorithm(buf[2])
+	if reserved != 0x01 {
+		return errors.UnsupportedError("Unsupported KDF reserved field: " + strconv.Itoa(reserved))
+	}
+	return
+}
+
+func (f *ecdhKdf) serialize(w io.Writer) (err error) {
+	buf := make([]byte, 4)
+	// See RFC 6637, Section 9, Algorithm-Specific Fields for ECDH keys.
+	buf[0] = byte(0x03) // Length of the following fields
+	buf[1] = byte(0x01) // Reserved for future extensions, must be 1 for now
+	buf[2] = byte(f.KdfHash)
+	buf[3] = byte(f.KdfAlgo)
+	_, err = w.Write(buf[:])
+	return
+}
+
+func (f *ecdhKdf) byteLen() int {
+	return 4
+}
+
+// PublicKey represents an OpenPGP public key. See RFC 4880, section 5.5.2.
+type PublicKey struct {
+	CreationTime time.Time
+	PubKeyAlgo   PublicKeyAlgorithm
+	PublicKey    interface{} // *rsa.PublicKey, *dsa.PublicKey or *ecdsa.PublicKey
+	Fingerprint  [20]byte
+	KeyId        uint64
+	IsSubkey     bool
+
+	n, e, p, q, g, y parsedMPI
+
+	// RFC 6637 fields
+	ec   *ecdsaKey
+	ecdh *ecdhKdf
+}
+
+// signingKey provides a convenient abstraction over signature verification
+// for v3 and v4 public keys.
+type signingKey interface {
+	SerializeSignaturePrefix(io.Writer)
+	serializeWithoutHeaders(io.Writer) error
+}
+
+func fromBig(n *big.Int) parsedMPI {
+	return parsedMPI{
+		bytes:     n.Bytes(),
+		bitLength: uint16(n.BitLen()),
+	}
+}
+
+// NewRSAPublicKey returns a PublicKey that wraps the given rsa.PublicKey.
+func NewRSAPublicKey(creationTime time.Time, pub *rsa.PublicKey) *PublicKey {
+	pk := &PublicKey{
+		CreationTime: creationTime,
+		PubKeyAlgo:   PubKeyAlgoRSA,
+		PublicKey:    pub,
+		n:            fromBig(pub.N),
+		e:            fromBig(big.NewInt(int64(pub.E))),
+	}
+
+	pk.setFingerPrintAndKeyId()
+	return pk
+}
+
+// NewDSAPublicKey returns a PublicKey that wraps the given dsa.PublicKey.
+func NewDSAPublicKey(creationTime time.Time, pub *dsa.PublicKey) *PublicKey {
+	pk := &PublicKey{
+		CreationTime: creationTime,
+		PubKeyAlgo:   PubKeyAlgoDSA,
+		PublicKey:    pub,
+		p:            fromBig(pub.P),
+		q:            fromBig(pub.Q),
+		g:            fromBig(pub.G),
+		y:            fromBig(pub.Y),
+	}
+
+	pk.setFingerPrintAndKeyId()
+	return pk
+}
+
+// NewElGamalPublicKey returns a PublicKey that wraps the given elgamal.PublicKey.
+func NewElGamalPublicKey(creationTime time.Time, pub *elgamal.PublicKey) *PublicKey {
+	pk := &PublicKey{
+		CreationTime: creationTime,
+		PubKeyAlgo:   PubKeyAlgoElGamal,
+		PublicKey:    pub,
+		p:            fromBig(pub.P),
+		g:            fromBig(pub.G),
+		y:            fromBig(pub.Y),
+	}
+
+	pk.setFingerPrintAndKeyId()
+	return pk
+}
+
+func NewECDSAPublicKey(creationTime time.Time, pub *ecdsa.PublicKey) *PublicKey {
+	pk := &PublicKey{
+		CreationTime: creationTime,
+		PubKeyAlgo:   PubKeyAlgoECDSA,
+		PublicKey:    pub,
+		ec:           new(ecdsaKey),
+	}
+
+	switch pub.Curve {
+	case elliptic.P256():
+		pk.ec.oid = oidCurveP256
+	case elliptic.P384():
+		pk.ec.oid = oidCurveP384
+	case elliptic.P521():
+		pk.ec.oid = oidCurveP521
+	default:
+		panic("unknown elliptic curve")
+	}
+
+	pk.ec.p.bytes = elliptic.Marshal(pub.Curve, pub.X, pub.Y)
+
+	// The bit length is 3 (for the 0x04 specifying an uncompressed key)
+	// plus two field elements (for x and y), which are rounded up to the
+	// nearest byte. See https://tools.ietf.org/html/rfc6637#section-6
+	fieldBytes := (pub.Curve.Params().BitSize + 7) & ^7
+	pk.ec.p.bitLength = uint16(3 + fieldBytes + fieldBytes)
+
+	pk.setFingerPrintAndKeyId()
+	return pk
+}
+
+func (pk *PublicKey) parse(r io.Reader) (err error) {
+	// RFC 4880, section 5.5.2
+	var buf [6]byte
+	_, err = readFull(r, buf[:])
+	if err != nil {
+		return
+	}
+	if buf[0] != 4 {
+		return errors.UnsupportedError("public key version")
+	}
+	pk.CreationTime = time.Unix(int64(uint32(buf[1])<<24|uint32(buf[2])<<16|uint32(buf[3])<<8|uint32(buf[4])), 0)
+	pk.PubKeyAlgo = PublicKeyAlgorithm(buf[5])
+	switch pk.PubKeyAlgo {
+	case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
+		err = pk.parseRSA(r)
+	case PubKeyAlgoDSA:
+		err = pk.parseDSA(r)
+	case PubKeyAlgoElGamal:
+		err = pk.parseElGamal(r)
+	case PubKeyAlgoECDSA:
+		pk.ec = new(ecdsaKey)
+		if err = pk.ec.parse(r); err != nil {
+			return err
+		}
+		pk.PublicKey, err = pk.ec.newECDSA()
+	case PubKeyAlgoECDH:
+		pk.ec = new(ecdsaKey)
+		if err = pk.ec.parse(r); err != nil {
+			return
+		}
+		pk.ecdh = new(ecdhKdf)
+		if err = pk.ecdh.parse(r); err != nil {
+			return
+		}
+		// The ECDH key is stored in an ecdsa.PublicKey for convenience.
+		pk.PublicKey, err = pk.ec.newECDSA()
+	default:
+		err = errors.UnsupportedError("public key type: " + strconv.Itoa(int(pk.PubKeyAlgo)))
+	}
+	if err != nil {
+		return
+	}
+
+	pk.setFingerPrintAndKeyId()
+	return
+}
+
+func (pk *PublicKey) setFingerPrintAndKeyId() {
+	// RFC 4880, section 12.2
+	fingerPrint := sha1.New()
+	pk.SerializeSignaturePrefix(fingerPrint)
+	pk.serializeWithoutHeaders(fingerPrint)
+	copy(pk.Fingerprint[:], fingerPrint.Sum(nil))
+	pk.KeyId = binary.BigEndian.Uint64(pk.Fingerprint[12:20])
+}
+
+// parseRSA parses RSA public key material from the given Reader. See RFC 4880,
+// section 5.5.2.
+func (pk *PublicKey) parseRSA(r io.Reader) (err error) {
+	pk.n.bytes, pk.n.bitLength, err = readMPI(r)
+	if err != nil {
+		return
+	}
+	pk.e.bytes, pk.e.bitLength, err = readMPI(r)
+	if err != nil {
+		return
+	}
+
+	if len(pk.e.bytes) > 3 {
+		err = errors.UnsupportedError("large public exponent")
+		return
+	}
+	rsa := &rsa.PublicKey{
+		N: new(big.Int).SetBytes(pk.n.bytes),
+		E: 0,
+	}
+	for i := 0; i < len(pk.e.bytes); i++ {
+		rsa.E <<= 8
+		rsa.E |= int(pk.e.bytes[i])
+	}
+	pk.PublicKey = rsa
+	return
+}
+
+// parseDSA parses DSA public key material from the given Reader. See RFC 4880,
+// section 5.5.2.
+func (pk *PublicKey) parseDSA(r io.Reader) (err error) {
+	pk.p.bytes, pk.p.bitLength, err = readMPI(r)
+	if err != nil {
+		return
+	}
+	pk.q.bytes, pk.q.bitLength, err = readMPI(r)
+	if err != nil {
+		return
+	}
+	pk.g.bytes, pk.g.bitLength, err = readMPI(r)
+	if err != nil {
+		return
+	}
+	pk.y.bytes, pk.y.bitLength, err = readMPI(r)
+	if err != nil {
+		return
+	}
+
+	dsa := new(dsa.PublicKey)
+	dsa.P = new(big.Int).SetBytes(pk.p.bytes)
+	dsa.Q = new(big.Int).SetBytes(pk.q.bytes)
+	dsa.G = new(big.Int).SetBytes(pk.g.bytes)
+	dsa.Y = new(big.Int).SetBytes(pk.y.bytes)
+	pk.PublicKey = dsa
+	return
+}
+
+// parseElGamal parses ElGamal public key material from the given Reader. See
+// RFC 4880, section 5.5.2.
+func (pk *PublicKey) parseElGamal(r io.Reader) (err error) {
+	pk.p.bytes, pk.p.bitLength, err = readMPI(r)
+	if err != nil {
+		return
+	}
+	pk.g.bytes, pk.g.bitLength, err = readMPI(r)
+	if err != nil {
+		return
+	}
+	pk.y.bytes, pk.y.bitLength, err = readMPI(r)
+	if err != nil {
+		return
+	}
+
+	elgamal := new(elgamal.PublicKey)
+	elgamal.P = new(big.Int).SetBytes(pk.p.bytes)
+	elgamal.G = new(big.Int).SetBytes(pk.g.bytes)
+	elgamal.Y = new(big.Int).SetBytes(pk.y.bytes)
+	pk.PublicKey = elgamal
+	return
+}
+
+// SerializeSignaturePrefix writes the prefix for this public key to the given Writer.
+// The prefix is used when calculating a signature over this public key. See
+// RFC 4880, section 5.2.4.
+func (pk *PublicKey) SerializeSignaturePrefix(h io.Writer) {
+	var pLength uint16
+	switch pk.PubKeyAlgo {
+	case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
+		pLength += 2 + uint16(len(pk.n.bytes))
+		pLength += 2 + uint16(len(pk.e.bytes))
+	case PubKeyAlgoDSA:
+		pLength += 2 + uint16(len(pk.p.bytes))
+		pLength += 2 + uint16(len(pk.q.bytes))
+		pLength += 2 + uint16(len(pk.g.bytes))
+		pLength += 2 + uint16(len(pk.y.bytes))
+	case PubKeyAlgoElGamal:
+		pLength += 2 + uint16(len(pk.p.bytes))
+		pLength += 2 + uint16(len(pk.g.bytes))
+		pLength += 2 + uint16(len(pk.y.bytes))
+	case PubKeyAlgoECDSA:
+		pLength += uint16(pk.ec.byteLen())
+	case PubKeyAlgoECDH:
+		pLength += uint16(pk.ec.byteLen())
+		pLength += uint16(pk.ecdh.byteLen())
+	default:
+		panic("unknown public key algorithm")
+	}
+	pLength += 6
+	h.Write([]byte{0x99, byte(pLength >> 8), byte(pLength)})
+	return
+}
+
+func (pk *PublicKey) Serialize(w io.Writer) (err error) {
+	length := 6 // 6 byte header
+
+	switch pk.PubKeyAlgo {
+	case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
+		length += 2 + len(pk.n.bytes)
+		length += 2 + len(pk.e.bytes)
+	case PubKeyAlgoDSA:
+		length += 2 + len(pk.p.bytes)
+		length += 2 + len(pk.q.bytes)
+		length += 2 + len(pk.g.bytes)
+		length += 2 + len(pk.y.bytes)
+	case PubKeyAlgoElGamal:
+		length += 2 + len(pk.p.bytes)
+		length += 2 + len(pk.g.bytes)
+		length += 2 + len(pk.y.bytes)
+	case PubKeyAlgoECDSA:
+		length += pk.ec.byteLen()
+	case PubKeyAlgoECDH:
+		length += pk.ec.byteLen()
+		length += pk.ecdh.byteLen()
+	default:
+		panic("unknown public key algorithm")
+	}
+
+	packetType := packetTypePublicKey
+	if pk.IsSubkey {
+		packetType = packetTypePublicSubkey
+	}
+	err = serializeHeader(w, packetType, length)
+	if err != nil {
+		return
+	}
+	return pk.serializeWithoutHeaders(w)
+}
+
+// serializeWithoutHeaders marshals the PublicKey to w in the form of an
+// OpenPGP public key packet, not including the packet header.
+func (pk *PublicKey) serializeWithoutHeaders(w io.Writer) (err error) {
+	var buf [6]byte
+	buf[0] = 4
+	t := uint32(pk.CreationTime.Unix())
+	buf[1] = byte(t >> 24)
+	buf[2] = byte(t >> 16)
+	buf[3] = byte(t >> 8)
+	buf[4] = byte(t)
+	buf[5] = byte(pk.PubKeyAlgo)
+
+	_, err = w.Write(buf[:])
+	if err != nil {
+		return
+	}
+
+	switch pk.PubKeyAlgo {
+	case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
+		return writeMPIs(w, pk.n, pk.e)
+	case PubKeyAlgoDSA:
+		return writeMPIs(w, pk.p, pk.q, pk.g, pk.y)
+	case PubKeyAlgoElGamal:
+		return writeMPIs(w, pk.p, pk.g, pk.y)
+	case PubKeyAlgoECDSA:
+		return pk.ec.serialize(w)
+	case PubKeyAlgoECDH:
+		if err = pk.ec.serialize(w); err != nil {
+			return
+		}
+		return pk.ecdh.serialize(w)
+	}
+	return errors.InvalidArgumentError("bad public-key algorithm")
+}
+
+// CanSign returns true iff this public key can generate signatures
+func (pk *PublicKey) CanSign() bool {
+	return pk.PubKeyAlgo != PubKeyAlgoRSAEncryptOnly && pk.PubKeyAlgo != PubKeyAlgoElGamal
+}
+
+// VerifySignature returns nil iff sig is a valid signature, made by this
+// public key, of the data hashed into signed. signed is mutated by this call.
+func (pk *PublicKey) VerifySignature(signed hash.Hash, sig *Signature) (err error) {
+	if !pk.CanSign() {
+		return errors.InvalidArgumentError("public key cannot generate signatures")
+	}
+
+	signed.Write(sig.HashSuffix)
+	hashBytes := signed.Sum(nil)
+
+	if hashBytes[0] != sig.HashTag[0] || hashBytes[1] != sig.HashTag[1] {
+		return errors.SignatureError("hash tag doesn't match")
+	}
+
+	if pk.PubKeyAlgo != sig.PubKeyAlgo {
+		return errors.InvalidArgumentError("public key and signature use different algorithms")
+	}
+
+	switch pk.PubKeyAlgo {
+	case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly:
+		rsaPublicKey, _ := pk.PublicKey.(*rsa.PublicKey)
+		err = rsa.VerifyPKCS1v15(rsaPublicKey, sig.Hash, hashBytes, padToKeySize(rsaPublicKey, sig.RSASignature.bytes))
+		if err != nil {
+			return errors.SignatureError("RSA verification failure")
+		}
+		return nil
+	case PubKeyAlgoDSA:
+		dsaPublicKey, _ := pk.PublicKey.(*dsa.PublicKey)
+		// Need to truncate hashBytes to match FIPS 186-3 section 4.6.
+		subgroupSize := (dsaPublicKey.Q.BitLen() + 7) / 8
+		if len(hashBytes) > subgroupSize {
+			hashBytes = hashBytes[:subgroupSize]
+		}
+		if !dsa.Verify(dsaPublicKey, hashBytes, new(big.Int).SetBytes(sig.DSASigR.bytes), new(big.Int).SetBytes(sig.DSASigS.bytes)) {
+			return errors.SignatureError("DSA verification failure")
+		}
+		return nil
+	case PubKeyAlgoECDSA:
+		ecdsaPublicKey := pk.PublicKey.(*ecdsa.PublicKey)
+		if !ecdsa.Verify(ecdsaPublicKey, hashBytes, new(big.Int).SetBytes(sig.ECDSASigR.bytes), new(big.Int).SetBytes(sig.ECDSASigS.bytes)) {
+			return errors.SignatureError("ECDSA verification failure")
+		}
+		return nil
+	default:
+		return errors.SignatureError("Unsupported public key algorithm used in signature")
+	}
+}
+
+// VerifySignatureV3 returns nil iff sig is a valid signature, made by this
+// public key, of the data hashed into signed. signed is mutated by this call.
+func (pk *PublicKey) VerifySignatureV3(signed hash.Hash, sig *SignatureV3) (err error) {
+	if !pk.CanSign() {
+		return errors.InvalidArgumentError("public key cannot generate signatures")
+	}
+
+	suffix := make([]byte, 5)
+	suffix[0] = byte(sig.SigType)
+	binary.BigEndian.PutUint32(suffix[1:], uint32(sig.CreationTime.Unix()))
+	signed.Write(suffix)
+	hashBytes := signed.Sum(nil)
+
+	if hashBytes[0] != sig.HashTag[0] || hashBytes[1] != sig.HashTag[1] {
+		return errors.SignatureError("hash tag doesn't match")
+	}
+
+	if pk.PubKeyAlgo != sig.PubKeyAlgo {
+		return errors.InvalidArgumentError("public key and signature use different algorithms")
+	}
+
+	switch pk.PubKeyAlgo {
+	case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly:
+		rsaPublicKey := pk.PublicKey.(*rsa.PublicKey)
+		if err = rsa.VerifyPKCS1v15(rsaPublicKey, sig.Hash, hashBytes, padToKeySize(rsaPublicKey, sig.RSASignature.bytes)); err != nil {
+			return errors.SignatureError("RSA verification failure")
+		}
+		return
+	case PubKeyAlgoDSA:
+		dsaPublicKey := pk.PublicKey.(*dsa.PublicKey)
+		// Need to truncate hashBytes to match FIPS 186-3 section 4.6.
+		subgroupSize := (dsaPublicKey.Q.BitLen() + 7) / 8
+		if len(hashBytes) > subgroupSize {
+			hashBytes = hashBytes[:subgroupSize]
+		}
+		if !dsa.Verify(dsaPublicKey, hashBytes, new(big.Int).SetBytes(sig.DSASigR.bytes), new(big.Int).SetBytes(sig.DSASigS.bytes)) {
+			return errors.SignatureError("DSA verification failure")
+		}
+		return nil
+	default:
+		panic("shouldn't happen")
+	}
+}
+
+// keySignatureHash returns a Hash of the message that needs to be signed for
+// pk to assert a subkey relationship to signed.
+func keySignatureHash(pk, signed signingKey, hashFunc crypto.Hash) (h hash.Hash, err error) {
+	if !hashFunc.Available() {
+		return nil, errors.UnsupportedError("hash function")
+	}
+	h = hashFunc.New()
+
+	// RFC 4880, section 5.2.4
+	pk.SerializeSignaturePrefix(h)
+	pk.serializeWithoutHeaders(h)
+	signed.SerializeSignaturePrefix(h)
+	signed.serializeWithoutHeaders(h)
+	return
+}
+
+// VerifyKeySignature returns nil iff sig is a valid signature, made by this
+// public key, of signed.
+func (pk *PublicKey) VerifyKeySignature(signed *PublicKey, sig *Signature) error {
+	h, err := keySignatureHash(pk, signed, sig.Hash)
+	if err != nil {
+		return err
+	}
+	if err = pk.VerifySignature(h, sig); err != nil {
+		return err
+	}
+
+	if sig.FlagSign {
+		// Signing subkeys must be cross-signed. See
+		// https://www.gnupg.org/faq/subkey-cross-certify.html.
+		if sig.EmbeddedSignature == nil {
+			return errors.StructuralError("signing subkey is missing cross-signature")
+		}
+		// Verify the cross-signature. This is calculated over the same
+		// data as the main signature, so we cannot just recursively
+		// call signed.VerifyKeySignature(...)
+		if h, err = keySignatureHash(pk, signed, sig.EmbeddedSignature.Hash); err != nil {
+			return errors.StructuralError("error while hashing for cross-signature: " + err.Error())
+		}
+		if err := signed.VerifySignature(h, sig.EmbeddedSignature); err != nil {
+			return errors.StructuralError("error while verifying cross-signature: " + err.Error())
+		}
+	}
+
+	return nil
+}
+
+func keyRevocationHash(pk signingKey, hashFunc crypto.Hash) (h hash.Hash, err error) {
+	if !hashFunc.Available() {
+		return nil, errors.UnsupportedError("hash function")
+	}
+	h = hashFunc.New()
+
+	// RFC 4880, section 5.2.4
+	pk.SerializeSignaturePrefix(h)
+	pk.serializeWithoutHeaders(h)
+
+	return
+}
+
+// VerifyRevocationSignature returns nil iff sig is a valid signature, made by this
+// public key.
+func (pk *PublicKey) VerifyRevocationSignature(sig *Signature) (err error) {
+	h, err := keyRevocationHash(pk, sig.Hash)
+	if err != nil {
+		return err
+	}
+	return pk.VerifySignature(h, sig)
+}
+
+// userIdSignatureHash returns a Hash of the message that needs to be signed
+// to assert that pk is a valid key for id.
+func userIdSignatureHash(id string, pk *PublicKey, hashFunc crypto.Hash) (h hash.Hash, err error) {
+	if !hashFunc.Available() {
+		return nil, errors.UnsupportedError("hash function")
+	}
+	h = hashFunc.New()
+
+	// RFC 4880, section 5.2.4
+	pk.SerializeSignaturePrefix(h)
+	pk.serializeWithoutHeaders(h)
+
+	var buf [5]byte
+	buf[0] = 0xb4
+	buf[1] = byte(len(id) >> 24)
+	buf[2] = byte(len(id) >> 16)
+	buf[3] = byte(len(id) >> 8)
+	buf[4] = byte(len(id))
+	h.Write(buf[:])
+	h.Write([]byte(id))
+
+	return
+}
+
+// VerifyUserIdSignature returns nil iff sig is a valid signature, made by this
+// public key, that id is the identity of pub.
+func (pk *PublicKey) VerifyUserIdSignature(id string, pub *PublicKey, sig *Signature) (err error) {
+	h, err := userIdSignatureHash(id, pub, sig.Hash)
+	if err != nil {
+		return err
+	}
+	return pk.VerifySignature(h, sig)
+}
+
+// VerifyUserIdSignatureV3 returns nil iff sig is a valid signature, made by this
+// public key, that id is the identity of pub.
+func (pk *PublicKey) VerifyUserIdSignatureV3(id string, pub *PublicKey, sig *SignatureV3) (err error) {
+	h, err := userIdSignatureV3Hash(id, pub, sig.Hash)
+	if err != nil {
+		return err
+	}
+	return pk.VerifySignatureV3(h, sig)
+}
+
+// KeyIdString returns the public key's fingerprint in capital hex
+// (e.g. "6C7EE1B8621CC013").
+func (pk *PublicKey) KeyIdString() string {
+	return fmt.Sprintf("%X", pk.Fingerprint[12:20])
+}
+
+// KeyIdShortString returns the short form of public key's fingerprint
+// in capital hex, as shown by gpg --list-keys (e.g. "621CC013").
+func (pk *PublicKey) KeyIdShortString() string {
+	return fmt.Sprintf("%X", pk.Fingerprint[16:20])
+}
+
+// A parsedMPI is used to store the contents of a big integer, along with the
+// bit length that was specified in the original input. This allows the MPI to
+// be reserialized exactly.
+type parsedMPI struct {
+	bytes     []byte
+	bitLength uint16
+}
+
+// writeMPIs is a utility function for serializing several big integers to the
+// given Writer.
+func writeMPIs(w io.Writer, mpis ...parsedMPI) (err error) {
+	for _, mpi := range mpis {
+		err = writeMPI(w, mpi.bitLength, mpi.bytes)
+		if err != nil {
+			return
+		}
+	}
+	return
+}
+
+// BitLength returns the bit length for the given public key.
+func (pk *PublicKey) BitLength() (bitLength uint16, err error) {
+	switch pk.PubKeyAlgo {
+	case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
+		bitLength = pk.n.bitLength
+	case PubKeyAlgoDSA:
+		bitLength = pk.p.bitLength
+	case PubKeyAlgoElGamal:
+		bitLength = pk.p.bitLength
+	default:
+		err = errors.InvalidArgumentError("bad public-key algorithm")
+	}
+	return
+}
diff --git a/vendor/golang.org/x/crypto/openpgp/packet/public_key_v3.go b/vendor/golang.org/x/crypto/openpgp/packet/public_key_v3.go
new file mode 100644
index 0000000000..5daf7b6cfd
--- /dev/null
+++ b/vendor/golang.org/x/crypto/openpgp/packet/public_key_v3.go
@@ -0,0 +1,279 @@
+// 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.
+
+package packet
+
+import (
+	"crypto"
+	"crypto/md5"
+	"crypto/rsa"
+	"encoding/binary"
+	"fmt"
+	"hash"
+	"io"
+	"math/big"
+	"strconv"
+	"time"
+
+	"golang.org/x/crypto/openpgp/errors"
+)
+
+// PublicKeyV3 represents older, version 3 public keys. These keys are less secure and
+// should not be used for signing or encrypting. They are supported here only for
+// parsing version 3 key material and validating signatures.
+// See RFC 4880, section 5.5.2.
+type PublicKeyV3 struct {
+	CreationTime time.Time
+	DaysToExpire uint16
+	PubKeyAlgo   PublicKeyAlgorithm
+	PublicKey    *rsa.PublicKey
+	Fingerprint  [16]byte
+	KeyId        uint64
+	IsSubkey     bool
+
+	n, e parsedMPI
+}
+
+// newRSAPublicKeyV3 returns a PublicKey that wraps the given rsa.PublicKey.
+// Included here for testing purposes only. RFC 4880, section 5.5.2:
+// "an implementation MUST NOT generate a V3 key, but MAY accept it."
+func newRSAPublicKeyV3(creationTime time.Time, pub *rsa.PublicKey) *PublicKeyV3 {
+	pk := &PublicKeyV3{
+		CreationTime: creationTime,
+		PublicKey:    pub,
+		n:            fromBig(pub.N),
+		e:            fromBig(big.NewInt(int64(pub.E))),
+	}
+
+	pk.setFingerPrintAndKeyId()
+	return pk
+}
+
+func (pk *PublicKeyV3) parse(r io.Reader) (err error) {
+	// RFC 4880, section 5.5.2
+	var buf [8]byte
+	if _, err = readFull(r, buf[:]); err != nil {
+		return
+	}
+	if buf[0] < 2 || buf[0] > 3 {
+		return errors.UnsupportedError("public key version")
+	}
+	pk.CreationTime = time.Unix(int64(uint32(buf[1])<<24|uint32(buf[2])<<16|uint32(buf[3])<<8|uint32(buf[4])), 0)
+	pk.DaysToExpire = binary.BigEndian.Uint16(buf[5:7])
+	pk.PubKeyAlgo = PublicKeyAlgorithm(buf[7])
+	switch pk.PubKeyAlgo {
+	case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
+		err = pk.parseRSA(r)
+	default:
+		err = errors.UnsupportedError("public key type: " + strconv.Itoa(int(pk.PubKeyAlgo)))
+	}
+	if err != nil {
+		return
+	}
+
+	pk.setFingerPrintAndKeyId()
+	return
+}
+
+func (pk *PublicKeyV3) setFingerPrintAndKeyId() {
+	// RFC 4880, section 12.2
+	fingerPrint := md5.New()
+	fingerPrint.Write(pk.n.bytes)
+	fingerPrint.Write(pk.e.bytes)
+	fingerPrint.Sum(pk.Fingerprint[:0])
+	pk.KeyId = binary.BigEndian.Uint64(pk.n.bytes[len(pk.n.bytes)-8:])
+}
+
+// parseRSA parses RSA public key material from the given Reader. See RFC 4880,
+// section 5.5.2.
+func (pk *PublicKeyV3) parseRSA(r io.Reader) (err error) {
+	if pk.n.bytes, pk.n.bitLength, err = readMPI(r); err != nil {
+		return
+	}
+	if pk.e.bytes, pk.e.bitLength, err = readMPI(r); err != nil {
+		return
+	}
+
+	// RFC 4880 Section 12.2 requires the low 8 bytes of the
+	// modulus to form the key id.
+	if len(pk.n.bytes) < 8 {
+		return errors.StructuralError("v3 public key modulus is too short")
+	}
+	if len(pk.e.bytes) > 3 {
+		err = errors.UnsupportedError("large public exponent")
+		return
+	}
+	rsa := &rsa.PublicKey{N: new(big.Int).SetBytes(pk.n.bytes)}
+	for i := 0; i < len(pk.e.bytes); i++ {
+		rsa.E <<= 8
+		rsa.E |= int(pk.e.bytes[i])
+	}
+	pk.PublicKey = rsa
+	return
+}
+
+// SerializeSignaturePrefix writes the prefix for this public key to the given Writer.
+// The prefix is used when calculating a signature over this public key. See
+// RFC 4880, section 5.2.4.
+func (pk *PublicKeyV3) SerializeSignaturePrefix(w io.Writer) {
+	var pLength uint16
+	switch pk.PubKeyAlgo {
+	case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
+		pLength += 2 + uint16(len(pk.n.bytes))
+		pLength += 2 + uint16(len(pk.e.bytes))
+	default:
+		panic("unknown public key algorithm")
+	}
+	pLength += 6
+	w.Write([]byte{0x99, byte(pLength >> 8), byte(pLength)})
+	return
+}
+
+func (pk *PublicKeyV3) Serialize(w io.Writer) (err error) {
+	length := 8 // 8 byte header
+
+	switch pk.PubKeyAlgo {
+	case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
+		length += 2 + len(pk.n.bytes)
+		length += 2 + len(pk.e.bytes)
+	default:
+		panic("unknown public key algorithm")
+	}
+
+	packetType := packetTypePublicKey
+	if pk.IsSubkey {
+		packetType = packetTypePublicSubkey
+	}
+	if err = serializeHeader(w, packetType, length); err != nil {
+		return
+	}
+	return pk.serializeWithoutHeaders(w)
+}
+
+// serializeWithoutHeaders marshals the PublicKey to w in the form of an
+// OpenPGP public key packet, not including the packet header.
+func (pk *PublicKeyV3) serializeWithoutHeaders(w io.Writer) (err error) {
+	var buf [8]byte
+	// Version 3
+	buf[0] = 3
+	// Creation time
+	t := uint32(pk.CreationTime.Unix())
+	buf[1] = byte(t >> 24)
+	buf[2] = byte(t >> 16)
+	buf[3] = byte(t >> 8)
+	buf[4] = byte(t)
+	// Days to expire
+	buf[5] = byte(pk.DaysToExpire >> 8)
+	buf[6] = byte(pk.DaysToExpire)
+	// Public key algorithm
+	buf[7] = byte(pk.PubKeyAlgo)
+
+	if _, err = w.Write(buf[:]); err != nil {
+		return
+	}
+
+	switch pk.PubKeyAlgo {
+	case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
+		return writeMPIs(w, pk.n, pk.e)
+	}
+	return errors.InvalidArgumentError("bad public-key algorithm")
+}
+
+// CanSign returns true iff this public key can generate signatures
+func (pk *PublicKeyV3) CanSign() bool {
+	return pk.PubKeyAlgo != PubKeyAlgoRSAEncryptOnly
+}
+
+// VerifySignatureV3 returns nil iff sig is a valid signature, made by this
+// public key, of the data hashed into signed. signed is mutated by this call.
+func (pk *PublicKeyV3) VerifySignatureV3(signed hash.Hash, sig *SignatureV3) (err error) {
+	if !pk.CanSign() {
+		return errors.InvalidArgumentError("public key cannot generate signatures")
+	}
+
+	suffix := make([]byte, 5)
+	suffix[0] = byte(sig.SigType)
+	binary.BigEndian.PutUint32(suffix[1:], uint32(sig.CreationTime.Unix()))
+	signed.Write(suffix)
+	hashBytes := signed.Sum(nil)
+
+	if hashBytes[0] != sig.HashTag[0] || hashBytes[1] != sig.HashTag[1] {
+		return errors.SignatureError("hash tag doesn't match")
+	}
+
+	if pk.PubKeyAlgo != sig.PubKeyAlgo {
+		return errors.InvalidArgumentError("public key and signature use different algorithms")
+	}
+
+	switch pk.PubKeyAlgo {
+	case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly:
+		if err = rsa.VerifyPKCS1v15(pk.PublicKey, sig.Hash, hashBytes, sig.RSASignature.bytes); err != nil {
+			return errors.SignatureError("RSA verification failure")
+		}
+		return
+	default:
+		// V3 public keys only support RSA.
+		panic("shouldn't happen")
+	}
+}
+
+// VerifyUserIdSignatureV3 returns nil iff sig is a valid signature, made by this
+// public key, that id is the identity of pub.
+func (pk *PublicKeyV3) VerifyUserIdSignatureV3(id string, pub *PublicKeyV3, sig *SignatureV3) (err error) {
+	h, err := userIdSignatureV3Hash(id, pk, sig.Hash)
+	if err != nil {
+		return err
+	}
+	return pk.VerifySignatureV3(h, sig)
+}
+
+// VerifyKeySignatureV3 returns nil iff sig is a valid signature, made by this
+// public key, of signed.
+func (pk *PublicKeyV3) VerifyKeySignatureV3(signed *PublicKeyV3, sig *SignatureV3) (err error) {
+	h, err := keySignatureHash(pk, signed, sig.Hash)
+	if err != nil {
+		return err
+	}
+	return pk.VerifySignatureV3(h, sig)
+}
+
+// userIdSignatureV3Hash returns a Hash of the message that needs to be signed
+// to assert that pk is a valid key for id.
+func userIdSignatureV3Hash(id string, pk signingKey, hfn crypto.Hash) (h hash.Hash, err error) {
+	if !hfn.Available() {
+		return nil, errors.UnsupportedError("hash function")
+	}
+	h = hfn.New()
+
+	// RFC 4880, section 5.2.4
+	pk.SerializeSignaturePrefix(h)
+	pk.serializeWithoutHeaders(h)
+
+	h.Write([]byte(id))
+
+	return
+}
+
+// KeyIdString returns the public key's fingerprint in capital hex
+// (e.g. "6C7EE1B8621CC013").
+func (pk *PublicKeyV3) KeyIdString() string {
+	return fmt.Sprintf("%X", pk.KeyId)
+}
+
+// KeyIdShortString returns the short form of public key's fingerprint
+// in capital hex, as shown by gpg --list-keys (e.g. "621CC013").
+func (pk *PublicKeyV3) KeyIdShortString() string {
+	return fmt.Sprintf("%X", pk.KeyId&0xFFFFFFFF)
+}
+
+// BitLength returns the bit length for the given public key.
+func (pk *PublicKeyV3) BitLength() (bitLength uint16, err error) {
+	switch pk.PubKeyAlgo {
+	case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
+		bitLength = pk.n.bitLength
+	default:
+		err = errors.InvalidArgumentError("bad public-key algorithm")
+	}
+	return
+}
diff --git a/vendor/golang.org/x/crypto/openpgp/packet/reader.go b/vendor/golang.org/x/crypto/openpgp/packet/reader.go
new file mode 100644
index 0000000000..34bc7c613e
--- /dev/null
+++ b/vendor/golang.org/x/crypto/openpgp/packet/reader.go
@@ -0,0 +1,76 @@
+// Copyright 2011 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 packet
+
+import (
+	"golang.org/x/crypto/openpgp/errors"
+	"io"
+)
+
+// Reader reads packets from an io.Reader and allows packets to be 'unread' so
+// that they result from the next call to Next.
+type Reader struct {
+	q       []Packet
+	readers []io.Reader
+}
+
+// New io.Readers are pushed when a compressed or encrypted packet is processed
+// and recursively treated as a new source of packets. However, a carefully
+// crafted packet can trigger an infinite recursive sequence of packets. See
+// http://mumble.net/~campbell/misc/pgp-quine
+// https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2013-4402
+// This constant limits the number of recursive packets that may be pushed.
+const maxReaders = 32
+
+// Next returns the most recently unread Packet, or reads another packet from
+// the top-most io.Reader. Unknown packet types are skipped.
+func (r *Reader) Next() (p Packet, err error) {
+	if len(r.q) > 0 {
+		p = r.q[len(r.q)-1]
+		r.q = r.q[:len(r.q)-1]
+		return
+	}
+
+	for len(r.readers) > 0 {
+		p, err = Read(r.readers[len(r.readers)-1])
+		if err == nil {
+			return
+		}
+		if err == io.EOF {
+			r.readers = r.readers[:len(r.readers)-1]
+			continue
+		}
+		if _, ok := err.(errors.UnknownPacketTypeError); !ok {
+			return nil, err
+		}
+	}
+
+	return nil, io.EOF
+}
+
+// Push causes the Reader to start reading from a new io.Reader. When an EOF
+// error is seen from the new io.Reader, it is popped and the Reader continues
+// to read from the next most recent io.Reader. Push returns a StructuralError
+// if pushing the reader would exceed the maximum recursion level, otherwise it
+// returns nil.
+func (r *Reader) Push(reader io.Reader) (err error) {
+	if len(r.readers) >= maxReaders {
+		return errors.StructuralError("too many layers of packets")
+	}
+	r.readers = append(r.readers, reader)
+	return nil
+}
+
+// Unread causes the given Packet to be returned from the next call to Next.
+func (r *Reader) Unread(p Packet) {
+	r.q = append(r.q, p)
+}
+
+func NewReader(r io.Reader) *Reader {
+	return &Reader{
+		q:       nil,
+		readers: []io.Reader{r},
+	}
+}
diff --git a/vendor/golang.org/x/crypto/openpgp/packet/signature.go b/vendor/golang.org/x/crypto/openpgp/packet/signature.go
new file mode 100644
index 0000000000..b2a24a5323
--- /dev/null
+++ b/vendor/golang.org/x/crypto/openpgp/packet/signature.go
@@ -0,0 +1,731 @@
+// Copyright 2011 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 packet
+
+import (
+	"bytes"
+	"crypto"
+	"crypto/dsa"
+	"crypto/ecdsa"
+	"encoding/asn1"
+	"encoding/binary"
+	"hash"
+	"io"
+	"math/big"
+	"strconv"
+	"time"
+
+	"golang.org/x/crypto/openpgp/errors"
+	"golang.org/x/crypto/openpgp/s2k"
+)
+
+const (
+	// See RFC 4880, section 5.2.3.21 for details.
+	KeyFlagCertify = 1 << iota
+	KeyFlagSign
+	KeyFlagEncryptCommunications
+	KeyFlagEncryptStorage
+)
+
+// Signature represents a signature. See RFC 4880, section 5.2.
+type Signature struct {
+	SigType    SignatureType
+	PubKeyAlgo PublicKeyAlgorithm
+	Hash       crypto.Hash
+
+	// HashSuffix is extra data that is hashed in after the signed data.
+	HashSuffix []byte
+	// HashTag contains the first two bytes of the hash for fast rejection
+	// of bad signed data.
+	HashTag      [2]byte
+	CreationTime time.Time
+
+	RSASignature         parsedMPI
+	DSASigR, DSASigS     parsedMPI
+	ECDSASigR, ECDSASigS parsedMPI
+
+	// rawSubpackets contains the unparsed subpackets, in order.
+	rawSubpackets []outputSubpacket
+
+	// The following are optional so are nil when not included in the
+	// signature.
+
+	SigLifetimeSecs, KeyLifetimeSecs                        *uint32
+	PreferredSymmetric, PreferredHash, PreferredCompression []uint8
+	IssuerKeyId                                             *uint64
+	IsPrimaryId                                             *bool
+
+	// FlagsValid is set if any flags were given. See RFC 4880, section
+	// 5.2.3.21 for details.
+	FlagsValid                                                           bool
+	FlagCertify, FlagSign, FlagEncryptCommunications, FlagEncryptStorage bool
+
+	// RevocationReason is set if this signature has been revoked.
+	// See RFC 4880, section 5.2.3.23 for details.
+	RevocationReason     *uint8
+	RevocationReasonText string
+
+	// MDC is set if this signature has a feature packet that indicates
+	// support for MDC subpackets.
+	MDC bool
+
+	// EmbeddedSignature, if non-nil, is a signature of the parent key, by
+	// this key. This prevents an attacker from claiming another's signing
+	// subkey as their own.
+	EmbeddedSignature *Signature
+
+	outSubpackets []outputSubpacket
+}
+
+func (sig *Signature) parse(r io.Reader) (err error) {
+	// RFC 4880, section 5.2.3
+	var buf [5]byte
+	_, err = readFull(r, buf[:1])
+	if err != nil {
+		return
+	}
+	if buf[0] != 4 {
+		err = errors.UnsupportedError("signature packet version " + strconv.Itoa(int(buf[0])))
+		return
+	}
+
+	_, err = readFull(r, buf[:5])
+	if err != nil {
+		return
+	}
+	sig.SigType = SignatureType(buf[0])
+	sig.PubKeyAlgo = PublicKeyAlgorithm(buf[1])
+	switch sig.PubKeyAlgo {
+	case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly, PubKeyAlgoDSA, PubKeyAlgoECDSA:
+	default:
+		err = errors.UnsupportedError("public key algorithm " + strconv.Itoa(int(sig.PubKeyAlgo)))
+		return
+	}
+
+	var ok bool
+	sig.Hash, ok = s2k.HashIdToHash(buf[2])
+	if !ok {
+		return errors.UnsupportedError("hash function " + strconv.Itoa(int(buf[2])))
+	}
+
+	hashedSubpacketsLength := int(buf[3])<<8 | int(buf[4])
+	l := 6 + hashedSubpacketsLength
+	sig.HashSuffix = make([]byte, l+6)
+	sig.HashSuffix[0] = 4
+	copy(sig.HashSuffix[1:], buf[:5])
+	hashedSubpackets := sig.HashSuffix[6:l]
+	_, err = readFull(r, hashedSubpackets)
+	if err != nil {
+		return
+	}
+	// See RFC 4880, section 5.2.4
+	trailer := sig.HashSuffix[l:]
+	trailer[0] = 4
+	trailer[1] = 0xff
+	trailer[2] = uint8(l >> 24)
+	trailer[3] = uint8(l >> 16)
+	trailer[4] = uint8(l >> 8)
+	trailer[5] = uint8(l)
+
+	err = parseSignatureSubpackets(sig, hashedSubpackets, true)
+	if err != nil {
+		return
+	}
+
+	_, err = readFull(r, buf[:2])
+	if err != nil {
+		return
+	}
+	unhashedSubpacketsLength := int(buf[0])<<8 | int(buf[1])
+	unhashedSubpackets := make([]byte, unhashedSubpacketsLength)
+	_, err = readFull(r, unhashedSubpackets)
+	if err != nil {
+		return
+	}
+	err = parseSignatureSubpackets(sig, unhashedSubpackets, false)
+	if err != nil {
+		return
+	}
+
+	_, err = readFull(r, sig.HashTag[:2])
+	if err != nil {
+		return
+	}
+
+	switch sig.PubKeyAlgo {
+	case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly:
+		sig.RSASignature.bytes, sig.RSASignature.bitLength, err = readMPI(r)
+	case PubKeyAlgoDSA:
+		sig.DSASigR.bytes, sig.DSASigR.bitLength, err = readMPI(r)
+		if err == nil {
+			sig.DSASigS.bytes, sig.DSASigS.bitLength, err = readMPI(r)
+		}
+	case PubKeyAlgoECDSA:
+		sig.ECDSASigR.bytes, sig.ECDSASigR.bitLength, err = readMPI(r)
+		if err == nil {
+			sig.ECDSASigS.bytes, sig.ECDSASigS.bitLength, err = readMPI(r)
+		}
+	default:
+		panic("unreachable")
+	}
+	return
+}
+
+// parseSignatureSubpackets parses subpackets of the main signature packet. See
+// RFC 4880, section 5.2.3.1.
+func parseSignatureSubpackets(sig *Signature, subpackets []byte, isHashed bool) (err error) {
+	for len(subpackets) > 0 {
+		subpackets, err = parseSignatureSubpacket(sig, subpackets, isHashed)
+		if err != nil {
+			return
+		}
+	}
+
+	if sig.CreationTime.IsZero() {
+		err = errors.StructuralError("no creation time in signature")
+	}
+
+	return
+}
+
+type signatureSubpacketType uint8
+
+const (
+	creationTimeSubpacket        signatureSubpacketType = 2
+	signatureExpirationSubpacket signatureSubpacketType = 3
+	keyExpirationSubpacket       signatureSubpacketType = 9
+	prefSymmetricAlgosSubpacket  signatureSubpacketType = 11
+	issuerSubpacket              signatureSubpacketType = 16
+	prefHashAlgosSubpacket       signatureSubpacketType = 21
+	prefCompressionSubpacket     signatureSubpacketType = 22
+	primaryUserIdSubpacket       signatureSubpacketType = 25
+	keyFlagsSubpacket            signatureSubpacketType = 27
+	reasonForRevocationSubpacket signatureSubpacketType = 29
+	featuresSubpacket            signatureSubpacketType = 30
+	embeddedSignatureSubpacket   signatureSubpacketType = 32
+)
+
+// parseSignatureSubpacket parses a single subpacket. len(subpacket) is >= 1.
+func parseSignatureSubpacket(sig *Signature, subpacket []byte, isHashed bool) (rest []byte, err error) {
+	// RFC 4880, section 5.2.3.1
+	var (
+		length     uint32
+		packetType signatureSubpacketType
+		isCritical bool
+	)
+	switch {
+	case subpacket[0] < 192:
+		length = uint32(subpacket[0])
+		subpacket = subpacket[1:]
+	case subpacket[0] < 255:
+		if len(subpacket) < 2 {
+			goto Truncated
+		}
+		length = uint32(subpacket[0]-192)<<8 + uint32(subpacket[1]) + 192
+		subpacket = subpacket[2:]
+	default:
+		if len(subpacket) < 5 {
+			goto Truncated
+		}
+		length = uint32(subpacket[1])<<24 |
+			uint32(subpacket[2])<<16 |
+			uint32(subpacket[3])<<8 |
+			uint32(subpacket[4])
+		subpacket = subpacket[5:]
+	}
+	if length > uint32(len(subpacket)) {
+		goto Truncated
+	}
+	rest = subpacket[length:]
+	subpacket = subpacket[:length]
+	if len(subpacket) == 0 {
+		err = errors.StructuralError("zero length signature subpacket")
+		return
+	}
+	packetType = signatureSubpacketType(subpacket[0] & 0x7f)
+	isCritical = subpacket[0]&0x80 == 0x80
+	subpacket = subpacket[1:]
+	sig.rawSubpackets = append(sig.rawSubpackets, outputSubpacket{isHashed, packetType, isCritical, subpacket})
+	switch packetType {
+	case creationTimeSubpacket:
+		if !isHashed {
+			err = errors.StructuralError("signature creation time in non-hashed area")
+			return
+		}
+		if len(subpacket) != 4 {
+			err = errors.StructuralError("signature creation time not four bytes")
+			return
+		}
+		t := binary.BigEndian.Uint32(subpacket)
+		sig.CreationTime = time.Unix(int64(t), 0)
+	case signatureExpirationSubpacket:
+		// Signature expiration time, section 5.2.3.10
+		if !isHashed {
+			return
+		}
+		if len(subpacket) != 4 {
+			err = errors.StructuralError("expiration subpacket with bad length")
+			return
+		}
+		sig.SigLifetimeSecs = new(uint32)
+		*sig.SigLifetimeSecs = binary.BigEndian.Uint32(subpacket)
+	case keyExpirationSubpacket:
+		// Key expiration time, section 5.2.3.6
+		if !isHashed {
+			return
+		}
+		if len(subpacket) != 4 {
+			err = errors.StructuralError("key expiration subpacket with bad length")
+			return
+		}
+		sig.KeyLifetimeSecs = new(uint32)
+		*sig.KeyLifetimeSecs = binary.BigEndian.Uint32(subpacket)
+	case prefSymmetricAlgosSubpacket:
+		// Preferred symmetric algorithms, section 5.2.3.7
+		if !isHashed {
+			return
+		}
+		sig.PreferredSymmetric = make([]byte, len(subpacket))
+		copy(sig.PreferredSymmetric, subpacket)
+	case issuerSubpacket:
+		// Issuer, section 5.2.3.5
+		if len(subpacket) != 8 {
+			err = errors.StructuralError("issuer subpacket with bad length")
+			return
+		}
+		sig.IssuerKeyId = new(uint64)
+		*sig.IssuerKeyId = binary.BigEndian.Uint64(subpacket)
+	case prefHashAlgosSubpacket:
+		// Preferred hash algorithms, section 5.2.3.8
+		if !isHashed {
+			return
+		}
+		sig.PreferredHash = make([]byte, len(subpacket))
+		copy(sig.PreferredHash, subpacket)
+	case prefCompressionSubpacket:
+		// Preferred compression algorithms, section 5.2.3.9
+		if !isHashed {
+			return
+		}
+		sig.PreferredCompression = make([]byte, len(subpacket))
+		copy(sig.PreferredCompression, subpacket)
+	case primaryUserIdSubpacket:
+		// Primary User ID, section 5.2.3.19
+		if !isHashed {
+			return
+		}
+		if len(subpacket) != 1 {
+			err = errors.StructuralError("primary user id subpacket with bad length")
+			return
+		}
+		sig.IsPrimaryId = new(bool)
+		if subpacket[0] > 0 {
+			*sig.IsPrimaryId = true
+		}
+	case keyFlagsSubpacket:
+		// Key flags, section 5.2.3.21
+		if !isHashed {
+			return
+		}
+		if len(subpacket) == 0 {
+			err = errors.StructuralError("empty key flags subpacket")
+			return
+		}
+		sig.FlagsValid = true
+		if subpacket[0]&KeyFlagCertify != 0 {
+			sig.FlagCertify = true
+		}
+		if subpacket[0]&KeyFlagSign != 0 {
+			sig.FlagSign = true
+		}
+		if subpacket[0]&KeyFlagEncryptCommunications != 0 {
+			sig.FlagEncryptCommunications = true
+		}
+		if subpacket[0]&KeyFlagEncryptStorage != 0 {
+			sig.FlagEncryptStorage = true
+		}
+	case reasonForRevocationSubpacket:
+		// Reason For Revocation, section 5.2.3.23
+		if !isHashed {
+			return
+		}
+		if len(subpacket) == 0 {
+			err = errors.StructuralError("empty revocation reason subpacket")
+			return
+		}
+		sig.RevocationReason = new(uint8)
+		*sig.RevocationReason = subpacket[0]
+		sig.RevocationReasonText = string(subpacket[1:])
+	case featuresSubpacket:
+		// Features subpacket, section 5.2.3.24 specifies a very general
+		// mechanism for OpenPGP implementations to signal support for new
+		// features. In practice, the subpacket is used exclusively to
+		// indicate support for MDC-protected encryption.
+		sig.MDC = len(subpacket) >= 1 && subpacket[0]&1 == 1
+	case embeddedSignatureSubpacket:
+		// Only usage is in signatures that cross-certify
+		// signing subkeys. section 5.2.3.26 describes the
+		// format, with its usage described in section 11.1
+		if sig.EmbeddedSignature != nil {
+			err = errors.StructuralError("Cannot have multiple embedded signatures")
+			return
+		}
+		sig.EmbeddedSignature = new(Signature)
+		// Embedded signatures are required to be v4 signatures see
+		// section 12.1. However, we only parse v4 signatures in this
+		// file anyway.
+		if err := sig.EmbeddedSignature.parse(bytes.NewBuffer(subpacket)); err != nil {
+			return nil, err
+		}
+		if sigType := sig.EmbeddedSignature.SigType; sigType != SigTypePrimaryKeyBinding {
+			return nil, errors.StructuralError("cross-signature has unexpected type " + strconv.Itoa(int(sigType)))
+		}
+	default:
+		if isCritical {
+			err = errors.UnsupportedError("unknown critical signature subpacket type " + strconv.Itoa(int(packetType)))
+			return
+		}
+	}
+	return
+
+Truncated:
+	err = errors.StructuralError("signature subpacket truncated")
+	return
+}
+
+// subpacketLengthLength returns the length, in bytes, of an encoded length value.
+func subpacketLengthLength(length int) int {
+	if length < 192 {
+		return 1
+	}
+	if length < 16320 {
+		return 2
+	}
+	return 5
+}
+
+// serializeSubpacketLength marshals the given length into to.
+func serializeSubpacketLength(to []byte, length int) int {
+	// RFC 4880, Section 4.2.2.
+	if length < 192 {
+		to[0] = byte(length)
+		return 1
+	}
+	if length < 16320 {
+		length -= 192
+		to[0] = byte((length >> 8) + 192)
+		to[1] = byte(length)
+		return 2
+	}
+	to[0] = 255
+	to[1] = byte(length >> 24)
+	to[2] = byte(length >> 16)
+	to[3] = byte(length >> 8)
+	to[4] = byte(length)
+	return 5
+}
+
+// subpacketsLength returns the serialized length, in bytes, of the given
+// subpackets.
+func subpacketsLength(subpackets []outputSubpacket, hashed bool) (length int) {
+	for _, subpacket := range subpackets {
+		if subpacket.hashed == hashed {
+			length += subpacketLengthLength(len(subpacket.contents) + 1)
+			length += 1 // type byte
+			length += len(subpacket.contents)
+		}
+	}
+	return
+}
+
+// serializeSubpackets marshals the given subpackets into to.
+func serializeSubpackets(to []byte, subpackets []outputSubpacket, hashed bool) {
+	for _, subpacket := range subpackets {
+		if subpacket.hashed == hashed {
+			n := serializeSubpacketLength(to, len(subpacket.contents)+1)
+			to[n] = byte(subpacket.subpacketType)
+			to = to[1+n:]
+			n = copy(to, subpacket.contents)
+			to = to[n:]
+		}
+	}
+	return
+}
+
+// KeyExpired returns whether sig is a self-signature of a key that has
+// expired.
+func (sig *Signature) KeyExpired(currentTime time.Time) bool {
+	if sig.KeyLifetimeSecs == nil {
+		return false
+	}
+	expiry := sig.CreationTime.Add(time.Duration(*sig.KeyLifetimeSecs) * time.Second)
+	return currentTime.After(expiry)
+}
+
+// buildHashSuffix constructs the HashSuffix member of sig in preparation for signing.
+func (sig *Signature) buildHashSuffix() (err error) {
+	hashedSubpacketsLen := subpacketsLength(sig.outSubpackets, true)
+
+	var ok bool
+	l := 6 + hashedSubpacketsLen
+	sig.HashSuffix = make([]byte, l+6)
+	sig.HashSuffix[0] = 4
+	sig.HashSuffix[1] = uint8(sig.SigType)
+	sig.HashSuffix[2] = uint8(sig.PubKeyAlgo)
+	sig.HashSuffix[3], ok = s2k.HashToHashId(sig.Hash)
+	if !ok {
+		sig.HashSuffix = nil
+		return errors.InvalidArgumentError("hash cannot be represented in OpenPGP: " + strconv.Itoa(int(sig.Hash)))
+	}
+	sig.HashSuffix[4] = byte(hashedSubpacketsLen >> 8)
+	sig.HashSuffix[5] = byte(hashedSubpacketsLen)
+	serializeSubpackets(sig.HashSuffix[6:l], sig.outSubpackets, true)
+	trailer := sig.HashSuffix[l:]
+	trailer[0] = 4
+	trailer[1] = 0xff
+	trailer[2] = byte(l >> 24)
+	trailer[3] = byte(l >> 16)
+	trailer[4] = byte(l >> 8)
+	trailer[5] = byte(l)
+	return
+}
+
+func (sig *Signature) signPrepareHash(h hash.Hash) (digest []byte, err error) {
+	err = sig.buildHashSuffix()
+	if err != nil {
+		return
+	}
+
+	h.Write(sig.HashSuffix)
+	digest = h.Sum(nil)
+	copy(sig.HashTag[:], digest)
+	return
+}
+
+// Sign signs a message with a private key. The hash, h, must contain
+// the hash of the message to be signed and will be mutated by this function.
+// On success, the signature is stored in sig. Call Serialize to write it out.
+// If config is nil, sensible defaults will be used.
+func (sig *Signature) Sign(h hash.Hash, priv *PrivateKey, config *Config) (err error) {
+	sig.outSubpackets = sig.buildSubpackets()
+	digest, err := sig.signPrepareHash(h)
+	if err != nil {
+		return
+	}
+
+	switch priv.PubKeyAlgo {
+	case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly:
+		// supports both *rsa.PrivateKey and crypto.Signer
+		sig.RSASignature.bytes, err = priv.PrivateKey.(crypto.Signer).Sign(config.Random(), digest, sig.Hash)
+		sig.RSASignature.bitLength = uint16(8 * len(sig.RSASignature.bytes))
+	case PubKeyAlgoDSA:
+		dsaPriv := priv.PrivateKey.(*dsa.PrivateKey)
+
+		// Need to truncate hashBytes to match FIPS 186-3 section 4.6.
+		subgroupSize := (dsaPriv.Q.BitLen() + 7) / 8
+		if len(digest) > subgroupSize {
+			digest = digest[:subgroupSize]
+		}
+		r, s, err := dsa.Sign(config.Random(), dsaPriv, digest)
+		if err == nil {
+			sig.DSASigR.bytes = r.Bytes()
+			sig.DSASigR.bitLength = uint16(8 * len(sig.DSASigR.bytes))
+			sig.DSASigS.bytes = s.Bytes()
+			sig.DSASigS.bitLength = uint16(8 * len(sig.DSASigS.bytes))
+		}
+	case PubKeyAlgoECDSA:
+		var r, s *big.Int
+		if pk, ok := priv.PrivateKey.(*ecdsa.PrivateKey); ok {
+			// direct support, avoid asn1 wrapping/unwrapping
+			r, s, err = ecdsa.Sign(config.Random(), pk, digest)
+		} else {
+			var b []byte
+			b, err = priv.PrivateKey.(crypto.Signer).Sign(config.Random(), digest, sig.Hash)
+			if err == nil {
+				r, s, err = unwrapECDSASig(b)
+			}
+		}
+		if err == nil {
+			sig.ECDSASigR = fromBig(r)
+			sig.ECDSASigS = fromBig(s)
+		}
+	default:
+		err = errors.UnsupportedError("public key algorithm: " + strconv.Itoa(int(sig.PubKeyAlgo)))
+	}
+
+	return
+}
+
+// unwrapECDSASig parses the two integer components of an ASN.1-encoded ECDSA
+// signature.
+func unwrapECDSASig(b []byte) (r, s *big.Int, err error) {
+	var ecsdaSig struct {
+		R, S *big.Int
+	}
+	_, err = asn1.Unmarshal(b, &ecsdaSig)
+	if err != nil {
+		return
+	}
+	return ecsdaSig.R, ecsdaSig.S, nil
+}
+
+// SignUserId computes a signature from priv, asserting that pub is a valid
+// key for the identity id.  On success, the signature is stored in sig. Call
+// Serialize to write it out.
+// If config is nil, sensible defaults will be used.
+func (sig *Signature) SignUserId(id string, pub *PublicKey, priv *PrivateKey, config *Config) error {
+	h, err := userIdSignatureHash(id, pub, sig.Hash)
+	if err != nil {
+		return err
+	}
+	return sig.Sign(h, priv, config)
+}
+
+// SignKey computes a signature from priv, asserting that pub is a subkey. On
+// success, the signature is stored in sig. Call Serialize to write it out.
+// If config is nil, sensible defaults will be used.
+func (sig *Signature) SignKey(pub *PublicKey, priv *PrivateKey, config *Config) error {
+	h, err := keySignatureHash(&priv.PublicKey, pub, sig.Hash)
+	if err != nil {
+		return err
+	}
+	return sig.Sign(h, priv, config)
+}
+
+// Serialize marshals sig to w. Sign, SignUserId or SignKey must have been
+// called first.
+func (sig *Signature) Serialize(w io.Writer) (err error) {
+	if len(sig.outSubpackets) == 0 {
+		sig.outSubpackets = sig.rawSubpackets
+	}
+	if sig.RSASignature.bytes == nil && sig.DSASigR.bytes == nil && sig.ECDSASigR.bytes == nil {
+		return errors.InvalidArgumentError("Signature: need to call Sign, SignUserId or SignKey before Serialize")
+	}
+
+	sigLength := 0
+	switch sig.PubKeyAlgo {
+	case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly:
+		sigLength = 2 + len(sig.RSASignature.bytes)
+	case PubKeyAlgoDSA:
+		sigLength = 2 + len(sig.DSASigR.bytes)
+		sigLength += 2 + len(sig.DSASigS.bytes)
+	case PubKeyAlgoECDSA:
+		sigLength = 2 + len(sig.ECDSASigR.bytes)
+		sigLength += 2 + len(sig.ECDSASigS.bytes)
+	default:
+		panic("impossible")
+	}
+
+	unhashedSubpacketsLen := subpacketsLength(sig.outSubpackets, false)
+	length := len(sig.HashSuffix) - 6 /* trailer not included */ +
+		2 /* length of unhashed subpackets */ + unhashedSubpacketsLen +
+		2 /* hash tag */ + sigLength
+	err = serializeHeader(w, packetTypeSignature, length)
+	if err != nil {
+		return
+	}
+
+	_, err = w.Write(sig.HashSuffix[:len(sig.HashSuffix)-6])
+	if err != nil {
+		return
+	}
+
+	unhashedSubpackets := make([]byte, 2+unhashedSubpacketsLen)
+	unhashedSubpackets[0] = byte(unhashedSubpacketsLen >> 8)
+	unhashedSubpackets[1] = byte(unhashedSubpacketsLen)
+	serializeSubpackets(unhashedSubpackets[2:], sig.outSubpackets, false)
+
+	_, err = w.Write(unhashedSubpackets)
+	if err != nil {
+		return
+	}
+	_, err = w.Write(sig.HashTag[:])
+	if err != nil {
+		return
+	}
+
+	switch sig.PubKeyAlgo {
+	case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly:
+		err = writeMPIs(w, sig.RSASignature)
+	case PubKeyAlgoDSA:
+		err = writeMPIs(w, sig.DSASigR, sig.DSASigS)
+	case PubKeyAlgoECDSA:
+		err = writeMPIs(w, sig.ECDSASigR, sig.ECDSASigS)
+	default:
+		panic("impossible")
+	}
+	return
+}
+
+// outputSubpacket represents a subpacket to be marshaled.
+type outputSubpacket struct {
+	hashed        bool // true if this subpacket is in the hashed area.
+	subpacketType signatureSubpacketType
+	isCritical    bool
+	contents      []byte
+}
+
+func (sig *Signature) buildSubpackets() (subpackets []outputSubpacket) {
+	creationTime := make([]byte, 4)
+	binary.BigEndian.PutUint32(creationTime, uint32(sig.CreationTime.Unix()))
+	subpackets = append(subpackets, outputSubpacket{true, creationTimeSubpacket, false, creationTime})
+
+	if sig.IssuerKeyId != nil {
+		keyId := make([]byte, 8)
+		binary.BigEndian.PutUint64(keyId, *sig.IssuerKeyId)
+		subpackets = append(subpackets, outputSubpacket{true, issuerSubpacket, false, keyId})
+	}
+
+	if sig.SigLifetimeSecs != nil && *sig.SigLifetimeSecs != 0 {
+		sigLifetime := make([]byte, 4)
+		binary.BigEndian.PutUint32(sigLifetime, *sig.SigLifetimeSecs)
+		subpackets = append(subpackets, outputSubpacket{true, signatureExpirationSubpacket, true, sigLifetime})
+	}
+
+	// Key flags may only appear in self-signatures or certification signatures.
+
+	if sig.FlagsValid {
+		var flags byte
+		if sig.FlagCertify {
+			flags |= KeyFlagCertify
+		}
+		if sig.FlagSign {
+			flags |= KeyFlagSign
+		}
+		if sig.FlagEncryptCommunications {
+			flags |= KeyFlagEncryptCommunications
+		}
+		if sig.FlagEncryptStorage {
+			flags |= KeyFlagEncryptStorage
+		}
+		subpackets = append(subpackets, outputSubpacket{true, keyFlagsSubpacket, false, []byte{flags}})
+	}
+
+	// The following subpackets may only appear in self-signatures
+
+	if sig.KeyLifetimeSecs != nil && *sig.KeyLifetimeSecs != 0 {
+		keyLifetime := make([]byte, 4)
+		binary.BigEndian.PutUint32(keyLifetime, *sig.KeyLifetimeSecs)
+		subpackets = append(subpackets, outputSubpacket{true, keyExpirationSubpacket, true, keyLifetime})
+	}
+
+	if sig.IsPrimaryId != nil && *sig.IsPrimaryId {
+		subpackets = append(subpackets, outputSubpacket{true, primaryUserIdSubpacket, false, []byte{1}})
+	}
+
+	if len(sig.PreferredSymmetric) > 0 {
+		subpackets = append(subpackets, outputSubpacket{true, prefSymmetricAlgosSubpacket, false, sig.PreferredSymmetric})
+	}
+
+	if len(sig.PreferredHash) > 0 {
+		subpackets = append(subpackets, outputSubpacket{true, prefHashAlgosSubpacket, false, sig.PreferredHash})
+	}
+
+	if len(sig.PreferredCompression) > 0 {
+		subpackets = append(subpackets, outputSubpacket{true, prefCompressionSubpacket, false, sig.PreferredCompression})
+	}
+
+	return
+}
diff --git a/vendor/golang.org/x/crypto/openpgp/packet/signature_v3.go b/vendor/golang.org/x/crypto/openpgp/packet/signature_v3.go
new file mode 100644
index 0000000000..6edff88934
--- /dev/null
+++ b/vendor/golang.org/x/crypto/openpgp/packet/signature_v3.go
@@ -0,0 +1,146 @@
+// 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.
+
+package packet
+
+import (
+	"crypto"
+	"encoding/binary"
+	"fmt"
+	"io"
+	"strconv"
+	"time"
+
+	"golang.org/x/crypto/openpgp/errors"
+	"golang.org/x/crypto/openpgp/s2k"
+)
+
+// SignatureV3 represents older version 3 signatures. These signatures are less secure
+// than version 4 and should not be used to create new signatures. They are included
+// here for backwards compatibility to read and validate with older key material.
+// See RFC 4880, section 5.2.2.
+type SignatureV3 struct {
+	SigType      SignatureType
+	CreationTime time.Time
+	IssuerKeyId  uint64
+	PubKeyAlgo   PublicKeyAlgorithm
+	Hash         crypto.Hash
+	HashTag      [2]byte
+
+	RSASignature     parsedMPI
+	DSASigR, DSASigS parsedMPI
+}
+
+func (sig *SignatureV3) parse(r io.Reader) (err error) {
+	// RFC 4880, section 5.2.2
+	var buf [8]byte
+	if _, err = readFull(r, buf[:1]); err != nil {
+		return
+	}
+	if buf[0] < 2 || buf[0] > 3 {
+		err = errors.UnsupportedError("signature packet version " + strconv.Itoa(int(buf[0])))
+		return
+	}
+	if _, err = readFull(r, buf[:1]); err != nil {
+		return
+	}
+	if buf[0] != 5 {
+		err = errors.UnsupportedError(
+			"invalid hashed material length " + strconv.Itoa(int(buf[0])))
+		return
+	}
+
+	// Read hashed material: signature type + creation time
+	if _, err = readFull(r, buf[:5]); err != nil {
+		return
+	}
+	sig.SigType = SignatureType(buf[0])
+	t := binary.BigEndian.Uint32(buf[1:5])
+	sig.CreationTime = time.Unix(int64(t), 0)
+
+	// Eight-octet Key ID of signer.
+	if _, err = readFull(r, buf[:8]); err != nil {
+		return
+	}
+	sig.IssuerKeyId = binary.BigEndian.Uint64(buf[:])
+
+	// Public-key and hash algorithm
+	if _, err = readFull(r, buf[:2]); err != nil {
+		return
+	}
+	sig.PubKeyAlgo = PublicKeyAlgorithm(buf[0])
+	switch sig.PubKeyAlgo {
+	case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly, PubKeyAlgoDSA:
+	default:
+		err = errors.UnsupportedError("public key algorithm " + strconv.Itoa(int(sig.PubKeyAlgo)))
+		return
+	}
+	var ok bool
+	if sig.Hash, ok = s2k.HashIdToHash(buf[1]); !ok {
+		return errors.UnsupportedError("hash function " + strconv.Itoa(int(buf[2])))
+	}
+
+	// Two-octet field holding left 16 bits of signed hash value.
+	if _, err = readFull(r, sig.HashTag[:2]); err != nil {
+		return
+	}
+
+	switch sig.PubKeyAlgo {
+	case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly:
+		sig.RSASignature.bytes, sig.RSASignature.bitLength, err = readMPI(r)
+	case PubKeyAlgoDSA:
+		if sig.DSASigR.bytes, sig.DSASigR.bitLength, err = readMPI(r); err != nil {
+			return
+		}
+		sig.DSASigS.bytes, sig.DSASigS.bitLength, err = readMPI(r)
+	default:
+		panic("unreachable")
+	}
+	return
+}
+
+// Serialize marshals sig to w. Sign, SignUserId or SignKey must have been
+// called first.
+func (sig *SignatureV3) Serialize(w io.Writer) (err error) {
+	buf := make([]byte, 8)
+
+	// Write the sig type and creation time
+	buf[0] = byte(sig.SigType)
+	binary.BigEndian.PutUint32(buf[1:5], uint32(sig.CreationTime.Unix()))
+	if _, err = w.Write(buf[:5]); err != nil {
+		return
+	}
+
+	// Write the issuer long key ID
+	binary.BigEndian.PutUint64(buf[:8], sig.IssuerKeyId)
+	if _, err = w.Write(buf[:8]); err != nil {
+		return
+	}
+
+	// Write public key algorithm, hash ID, and hash value
+	buf[0] = byte(sig.PubKeyAlgo)
+	hashId, ok := s2k.HashToHashId(sig.Hash)
+	if !ok {
+		return errors.UnsupportedError(fmt.Sprintf("hash function %v", sig.Hash))
+	}
+	buf[1] = hashId
+	copy(buf[2:4], sig.HashTag[:])
+	if _, err = w.Write(buf[:4]); err != nil {
+		return
+	}
+
+	if sig.RSASignature.bytes == nil && sig.DSASigR.bytes == nil {
+		return errors.InvalidArgumentError("Signature: need to call Sign, SignUserId or SignKey before Serialize")
+	}
+
+	switch sig.PubKeyAlgo {
+	case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly:
+		err = writeMPIs(w, sig.RSASignature)
+	case PubKeyAlgoDSA:
+		err = writeMPIs(w, sig.DSASigR, sig.DSASigS)
+	default:
+		panic("impossible")
+	}
+	return
+}
diff --git a/vendor/golang.org/x/crypto/openpgp/packet/symmetric_key_encrypted.go b/vendor/golang.org/x/crypto/openpgp/packet/symmetric_key_encrypted.go
new file mode 100644
index 0000000000..744c2d2c42
--- /dev/null
+++ b/vendor/golang.org/x/crypto/openpgp/packet/symmetric_key_encrypted.go
@@ -0,0 +1,155 @@
+// Copyright 2011 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 packet
+
+import (
+	"bytes"
+	"crypto/cipher"
+	"io"
+	"strconv"
+
+	"golang.org/x/crypto/openpgp/errors"
+	"golang.org/x/crypto/openpgp/s2k"
+)
+
+// This is the largest session key that we'll support. Since no 512-bit cipher
+// has even been seriously used, this is comfortably large.
+const maxSessionKeySizeInBytes = 64
+
+// SymmetricKeyEncrypted represents a passphrase protected session key. See RFC
+// 4880, section 5.3.
+type SymmetricKeyEncrypted struct {
+	CipherFunc   CipherFunction
+	s2k          func(out, in []byte)
+	encryptedKey []byte
+}
+
+const symmetricKeyEncryptedVersion = 4
+
+func (ske *SymmetricKeyEncrypted) parse(r io.Reader) error {
+	// RFC 4880, section 5.3.
+	var buf [2]byte
+	if _, err := readFull(r, buf[:]); err != nil {
+		return err
+	}
+	if buf[0] != symmetricKeyEncryptedVersion {
+		return errors.UnsupportedError("SymmetricKeyEncrypted version")
+	}
+	ske.CipherFunc = CipherFunction(buf[1])
+
+	if ske.CipherFunc.KeySize() == 0 {
+		return errors.UnsupportedError("unknown cipher: " + strconv.Itoa(int(buf[1])))
+	}
+
+	var err error
+	ske.s2k, err = s2k.Parse(r)
+	if err != nil {
+		return err
+	}
+
+	encryptedKey := make([]byte, maxSessionKeySizeInBytes)
+	// The session key may follow. We just have to try and read to find
+	// out. If it exists then we limit it to maxSessionKeySizeInBytes.
+	n, err := readFull(r, encryptedKey)
+	if err != nil && err != io.ErrUnexpectedEOF {
+		return err
+	}
+
+	if n != 0 {
+		if n == maxSessionKeySizeInBytes {
+			return errors.UnsupportedError("oversized encrypted session key")
+		}
+		ske.encryptedKey = encryptedKey[:n]
+	}
+
+	return nil
+}
+
+// Decrypt attempts to decrypt an encrypted session key and returns the key and
+// the cipher to use when decrypting a subsequent Symmetrically Encrypted Data
+// packet.
+func (ske *SymmetricKeyEncrypted) Decrypt(passphrase []byte) ([]byte, CipherFunction, error) {
+	key := make([]byte, ske.CipherFunc.KeySize())
+	ske.s2k(key, passphrase)
+
+	if len(ske.encryptedKey) == 0 {
+		return key, ske.CipherFunc, nil
+	}
+
+	// the IV is all zeros
+	iv := make([]byte, ske.CipherFunc.blockSize())
+	c := cipher.NewCFBDecrypter(ske.CipherFunc.new(key), iv)
+	plaintextKey := make([]byte, len(ske.encryptedKey))
+	c.XORKeyStream(plaintextKey, ske.encryptedKey)
+	cipherFunc := CipherFunction(plaintextKey[0])
+	if cipherFunc.blockSize() == 0 {
+		return nil, ske.CipherFunc, errors.UnsupportedError("unknown cipher: " + strconv.Itoa(int(cipherFunc)))
+	}
+	plaintextKey = plaintextKey[1:]
+	if l, cipherKeySize := len(plaintextKey), cipherFunc.KeySize(); l != cipherFunc.KeySize() {
+		return nil, cipherFunc, errors.StructuralError("length of decrypted key (" + strconv.Itoa(l) + ") " +
+			"not equal to cipher keysize (" + strconv.Itoa(cipherKeySize) + ")")
+	}
+	return plaintextKey, cipherFunc, nil
+}
+
+// SerializeSymmetricKeyEncrypted serializes a symmetric key packet to w. The
+// packet contains a random session key, encrypted by a key derived from the
+// given passphrase. The session key is returned and must be passed to
+// SerializeSymmetricallyEncrypted.
+// If config is nil, sensible defaults will be used.
+func SerializeSymmetricKeyEncrypted(w io.Writer, passphrase []byte, config *Config) (key []byte, err error) {
+	cipherFunc := config.Cipher()
+	keySize := cipherFunc.KeySize()
+	if keySize == 0 {
+		return nil, errors.UnsupportedError("unknown cipher: " + strconv.Itoa(int(cipherFunc)))
+	}
+
+	s2kBuf := new(bytes.Buffer)
+	keyEncryptingKey := make([]byte, keySize)
+	// s2k.Serialize salts and stretches the passphrase, and writes the
+	// resulting key to keyEncryptingKey and the s2k descriptor to s2kBuf.
+	err = s2k.Serialize(s2kBuf, keyEncryptingKey, config.Random(), passphrase, &s2k.Config{Hash: config.Hash(), S2KCount: config.PasswordHashIterations()})
+	if err != nil {
+		return
+	}
+	s2kBytes := s2kBuf.Bytes()
+
+	packetLength := 2 /* header */ + len(s2kBytes) + 1 /* cipher type */ + keySize
+	err = serializeHeader(w, packetTypeSymmetricKeyEncrypted, packetLength)
+	if err != nil {
+		return
+	}
+
+	var buf [2]byte
+	buf[0] = symmetricKeyEncryptedVersion
+	buf[1] = byte(cipherFunc)
+	_, err = w.Write(buf[:])
+	if err != nil {
+		return
+	}
+	_, err = w.Write(s2kBytes)
+	if err != nil {
+		return
+	}
+
+	sessionKey := make([]byte, keySize)
+	_, err = io.ReadFull(config.Random(), sessionKey)
+	if err != nil {
+		return
+	}
+	iv := make([]byte, cipherFunc.blockSize())
+	c := cipher.NewCFBEncrypter(cipherFunc.new(keyEncryptingKey), iv)
+	encryptedCipherAndKey := make([]byte, keySize+1)
+	c.XORKeyStream(encryptedCipherAndKey, buf[1:])
+	c.XORKeyStream(encryptedCipherAndKey[1:], sessionKey)
+	_, err = w.Write(encryptedCipherAndKey)
+	if err != nil {
+		return
+	}
+
+	key = sessionKey
+	return
+}
diff --git a/vendor/golang.org/x/crypto/openpgp/packet/symmetrically_encrypted.go b/vendor/golang.org/x/crypto/openpgp/packet/symmetrically_encrypted.go
new file mode 100644
index 0000000000..6126030eb9
--- /dev/null
+++ b/vendor/golang.org/x/crypto/openpgp/packet/symmetrically_encrypted.go
@@ -0,0 +1,290 @@
+// Copyright 2011 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 packet
+
+import (
+	"crypto/cipher"
+	"crypto/sha1"
+	"crypto/subtle"
+	"golang.org/x/crypto/openpgp/errors"
+	"hash"
+	"io"
+	"strconv"
+)
+
+// SymmetricallyEncrypted represents a symmetrically encrypted byte string. The
+// encrypted contents will consist of more OpenPGP packets. See RFC 4880,
+// sections 5.7 and 5.13.
+type SymmetricallyEncrypted struct {
+	MDC      bool // true iff this is a type 18 packet and thus has an embedded MAC.
+	contents io.Reader
+	prefix   []byte
+}
+
+const symmetricallyEncryptedVersion = 1
+
+func (se *SymmetricallyEncrypted) parse(r io.Reader) error {
+	if se.MDC {
+		// See RFC 4880, section 5.13.
+		var buf [1]byte
+		_, err := readFull(r, buf[:])
+		if err != nil {
+			return err
+		}
+		if buf[0] != symmetricallyEncryptedVersion {
+			return errors.UnsupportedError("unknown SymmetricallyEncrypted version")
+		}
+	}
+	se.contents = r
+	return nil
+}
+
+// Decrypt returns a ReadCloser, from which the decrypted contents of the
+// packet can be read. An incorrect key can, with high probability, be detected
+// immediately and this will result in a KeyIncorrect error being returned.
+func (se *SymmetricallyEncrypted) Decrypt(c CipherFunction, key []byte) (io.ReadCloser, error) {
+	keySize := c.KeySize()
+	if keySize == 0 {
+		return nil, errors.UnsupportedError("unknown cipher: " + strconv.Itoa(int(c)))
+	}
+	if len(key) != keySize {
+		return nil, errors.InvalidArgumentError("SymmetricallyEncrypted: incorrect key length")
+	}
+
+	if se.prefix == nil {
+		se.prefix = make([]byte, c.blockSize()+2)
+		_, err := readFull(se.contents, se.prefix)
+		if err != nil {
+			return nil, err
+		}
+	} else if len(se.prefix) != c.blockSize()+2 {
+		return nil, errors.InvalidArgumentError("can't try ciphers with different block lengths")
+	}
+
+	ocfbResync := OCFBResync
+	if se.MDC {
+		// MDC packets use a different form of OCFB mode.
+		ocfbResync = OCFBNoResync
+	}
+
+	s := NewOCFBDecrypter(c.new(key), se.prefix, ocfbResync)
+	if s == nil {
+		return nil, errors.ErrKeyIncorrect
+	}
+
+	plaintext := cipher.StreamReader{S: s, R: se.contents}
+
+	if se.MDC {
+		// MDC packets have an embedded hash that we need to check.
+		h := sha1.New()
+		h.Write(se.prefix)
+		return &seMDCReader{in: plaintext, h: h}, nil
+	}
+
+	// Otherwise, we just need to wrap plaintext so that it's a valid ReadCloser.
+	return seReader{plaintext}, nil
+}
+
+// seReader wraps an io.Reader with a no-op Close method.
+type seReader struct {
+	in io.Reader
+}
+
+func (ser seReader) Read(buf []byte) (int, error) {
+	return ser.in.Read(buf)
+}
+
+func (ser seReader) Close() error {
+	return nil
+}
+
+const mdcTrailerSize = 1 /* tag byte */ + 1 /* length byte */ + sha1.Size
+
+// An seMDCReader wraps an io.Reader, maintains a running hash and keeps hold
+// of the most recent 22 bytes (mdcTrailerSize). Upon EOF, those bytes form an
+// MDC packet containing a hash of the previous contents which is checked
+// against the running hash. See RFC 4880, section 5.13.
+type seMDCReader struct {
+	in          io.Reader
+	h           hash.Hash
+	trailer     [mdcTrailerSize]byte
+	scratch     [mdcTrailerSize]byte
+	trailerUsed int
+	error       bool
+	eof         bool
+}
+
+func (ser *seMDCReader) Read(buf []byte) (n int, err error) {
+	if ser.error {
+		err = io.ErrUnexpectedEOF
+		return
+	}
+	if ser.eof {
+		err = io.EOF
+		return
+	}
+
+	// If we haven't yet filled the trailer buffer then we must do that
+	// first.
+	for ser.trailerUsed < mdcTrailerSize {
+		n, err = ser.in.Read(ser.trailer[ser.trailerUsed:])
+		ser.trailerUsed += n
+		if err == io.EOF {
+			if ser.trailerUsed != mdcTrailerSize {
+				n = 0
+				err = io.ErrUnexpectedEOF
+				ser.error = true
+				return
+			}
+			ser.eof = true
+			n = 0
+			return
+		}
+
+		if err != nil {
+			n = 0
+			return
+		}
+	}
+
+	// If it's a short read then we read into a temporary buffer and shift
+	// the data into the caller's buffer.
+	if len(buf) <= mdcTrailerSize {
+		n, err = readFull(ser.in, ser.scratch[:len(buf)])
+		copy(buf, ser.trailer[:n])
+		ser.h.Write(buf[:n])
+		copy(ser.trailer[:], ser.trailer[n:])
+		copy(ser.trailer[mdcTrailerSize-n:], ser.scratch[:])
+		if n < len(buf) {
+			ser.eof = true
+			err = io.EOF
+		}
+		return
+	}
+
+	n, err = ser.in.Read(buf[mdcTrailerSize:])
+	copy(buf, ser.trailer[:])
+	ser.h.Write(buf[:n])
+	copy(ser.trailer[:], buf[n:])
+
+	if err == io.EOF {
+		ser.eof = true
+	}
+	return
+}
+
+// This is a new-format packet tag byte for a type 19 (MDC) packet.
+const mdcPacketTagByte = byte(0x80) | 0x40 | 19
+
+func (ser *seMDCReader) Close() error {
+	if ser.error {
+		return errors.SignatureError("error during reading")
+	}
+
+	for !ser.eof {
+		// We haven't seen EOF so we need to read to the end
+		var buf [1024]byte
+		_, err := ser.Read(buf[:])
+		if err == io.EOF {
+			break
+		}
+		if err != nil {
+			return errors.SignatureError("error during reading")
+		}
+	}
+
+	if ser.trailer[0] != mdcPacketTagByte || ser.trailer[1] != sha1.Size {
+		return errors.SignatureError("MDC packet not found")
+	}
+	ser.h.Write(ser.trailer[:2])
+
+	final := ser.h.Sum(nil)
+	if subtle.ConstantTimeCompare(final, ser.trailer[2:]) != 1 {
+		return errors.SignatureError("hash mismatch")
+	}
+	return nil
+}
+
+// An seMDCWriter writes through to an io.WriteCloser while maintains a running
+// hash of the data written. On close, it emits an MDC packet containing the
+// running hash.
+type seMDCWriter struct {
+	w io.WriteCloser
+	h hash.Hash
+}
+
+func (w *seMDCWriter) Write(buf []byte) (n int, err error) {
+	w.h.Write(buf)
+	return w.w.Write(buf)
+}
+
+func (w *seMDCWriter) Close() (err error) {
+	var buf [mdcTrailerSize]byte
+
+	buf[0] = mdcPacketTagByte
+	buf[1] = sha1.Size
+	w.h.Write(buf[:2])
+	digest := w.h.Sum(nil)
+	copy(buf[2:], digest)
+
+	_, err = w.w.Write(buf[:])
+	if err != nil {
+		return
+	}
+	return w.w.Close()
+}
+
+// noOpCloser is like an ioutil.NopCloser, but for an io.Writer.
+type noOpCloser struct {
+	w io.Writer
+}
+
+func (c noOpCloser) Write(data []byte) (n int, err error) {
+	return c.w.Write(data)
+}
+
+func (c noOpCloser) Close() error {
+	return nil
+}
+
+// SerializeSymmetricallyEncrypted serializes a symmetrically encrypted packet
+// to w and returns a WriteCloser to which the to-be-encrypted packets can be
+// written.
+// If config is nil, sensible defaults will be used.
+func SerializeSymmetricallyEncrypted(w io.Writer, c CipherFunction, key []byte, config *Config) (contents io.WriteCloser, err error) {
+	if c.KeySize() != len(key) {
+		return nil, errors.InvalidArgumentError("SymmetricallyEncrypted.Serialize: bad key length")
+	}
+	writeCloser := noOpCloser{w}
+	ciphertext, err := serializeStreamHeader(writeCloser, packetTypeSymmetricallyEncryptedMDC)
+	if err != nil {
+		return
+	}
+
+	_, err = ciphertext.Write([]byte{symmetricallyEncryptedVersion})
+	if err != nil {
+		return
+	}
+
+	block := c.new(key)
+	blockSize := block.BlockSize()
+	iv := make([]byte, blockSize)
+	_, err = config.Random().Read(iv)
+	if err != nil {
+		return
+	}
+	s, prefix := NewOCFBEncrypter(block, iv, OCFBNoResync)
+	_, err = ciphertext.Write(prefix)
+	if err != nil {
+		return
+	}
+	plaintext := cipher.StreamWriter{S: s, W: ciphertext}
+
+	h := sha1.New()
+	h.Write(iv)
+	h.Write(iv[blockSize-2:])
+	contents = &seMDCWriter{w: plaintext, h: h}
+	return
+}
diff --git a/vendor/golang.org/x/crypto/openpgp/packet/userattribute.go b/vendor/golang.org/x/crypto/openpgp/packet/userattribute.go
new file mode 100644
index 0000000000..d19ffbc786
--- /dev/null
+++ b/vendor/golang.org/x/crypto/openpgp/packet/userattribute.go
@@ -0,0 +1,91 @@
+// 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.
+
+package packet
+
+import (
+	"bytes"
+	"image"
+	"image/jpeg"
+	"io"
+	"io/ioutil"
+)
+
+const UserAttrImageSubpacket = 1
+
+// UserAttribute is capable of storing other types of data about a user
+// beyond name, email and a text comment. In practice, user attributes are typically used
+// to store a signed thumbnail photo JPEG image of the user.
+// See RFC 4880, section 5.12.
+type UserAttribute struct {
+	Contents []*OpaqueSubpacket
+}
+
+// NewUserAttributePhoto creates a user attribute packet
+// containing the given images.
+func NewUserAttributePhoto(photos ...image.Image) (uat *UserAttribute, err error) {
+	uat = new(UserAttribute)
+	for _, photo := range photos {
+		var buf bytes.Buffer
+		// RFC 4880, Section 5.12.1.
+		data := []byte{
+			0x10, 0x00, // Little-endian image header length (16 bytes)
+			0x01,       // Image header version 1
+			0x01,       // JPEG
+			0, 0, 0, 0, // 12 reserved octets, must be all zero.
+			0, 0, 0, 0,
+			0, 0, 0, 0}
+		if _, err = buf.Write(data); err != nil {
+			return
+		}
+		if err = jpeg.Encode(&buf, photo, nil); err != nil {
+			return
+		}
+		uat.Contents = append(uat.Contents, &OpaqueSubpacket{
+			SubType:  UserAttrImageSubpacket,
+			Contents: buf.Bytes()})
+	}
+	return
+}
+
+// NewUserAttribute creates a new user attribute packet containing the given subpackets.
+func NewUserAttribute(contents ...*OpaqueSubpacket) *UserAttribute {
+	return &UserAttribute{Contents: contents}
+}
+
+func (uat *UserAttribute) parse(r io.Reader) (err error) {
+	// RFC 4880, section 5.13
+	b, err := ioutil.ReadAll(r)
+	if err != nil {
+		return
+	}
+	uat.Contents, err = OpaqueSubpackets(b)
+	return
+}
+
+// Serialize marshals the user attribute to w in the form of an OpenPGP packet, including
+// header.
+func (uat *UserAttribute) Serialize(w io.Writer) (err error) {
+	var buf bytes.Buffer
+	for _, sp := range uat.Contents {
+		sp.Serialize(&buf)
+	}
+	if err = serializeHeader(w, packetTypeUserAttribute, buf.Len()); err != nil {
+		return err
+	}
+	_, err = w.Write(buf.Bytes())
+	return
+}
+
+// ImageData returns zero or more byte slices, each containing
+// JPEG File Interchange Format (JFIF), for each photo in the
+// user attribute packet.
+func (uat *UserAttribute) ImageData() (imageData [][]byte) {
+	for _, sp := range uat.Contents {
+		if sp.SubType == UserAttrImageSubpacket && len(sp.Contents) > 16 {
+			imageData = append(imageData, sp.Contents[16:])
+		}
+	}
+	return
+}
diff --git a/vendor/golang.org/x/crypto/openpgp/packet/userid.go b/vendor/golang.org/x/crypto/openpgp/packet/userid.go
new file mode 100644
index 0000000000..d6bea7d4ac
--- /dev/null
+++ b/vendor/golang.org/x/crypto/openpgp/packet/userid.go
@@ -0,0 +1,160 @@
+// Copyright 2011 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 packet
+
+import (
+	"io"
+	"io/ioutil"
+	"strings"
+)
+
+// UserId contains text that is intended to represent the name and email
+// address of the key holder. See RFC 4880, section 5.11. By convention, this
+// takes the form "Full Name (Comment) <email@example.com>"
+type UserId struct {
+	Id string // By convention, this takes the form "Full Name (Comment) <email@example.com>" which is split out in the fields below.
+
+	Name, Comment, Email string
+}
+
+func hasInvalidCharacters(s string) bool {
+	for _, c := range s {
+		switch c {
+		case '(', ')', '<', '>', 0:
+			return true
+		}
+	}
+	return false
+}
+
+// NewUserId returns a UserId or nil if any of the arguments contain invalid
+// characters. The invalid characters are '\x00', '(', ')', '<' and '>'
+func NewUserId(name, comment, email string) *UserId {
+	// RFC 4880 doesn't deal with the structure of userid strings; the
+	// name, comment and email form is just a convention. However, there's
+	// no convention about escaping the metacharacters and GPG just refuses
+	// to create user ids where, say, the name contains a '('. We mirror
+	// this behaviour.
+
+	if hasInvalidCharacters(name) || hasInvalidCharacters(comment) || hasInvalidCharacters(email) {
+		return nil
+	}
+
+	uid := new(UserId)
+	uid.Name, uid.Comment, uid.Email = name, comment, email
+	uid.Id = name
+	if len(comment) > 0 {
+		if len(uid.Id) > 0 {
+			uid.Id += " "
+		}
+		uid.Id += "("
+		uid.Id += comment
+		uid.Id += ")"
+	}
+	if len(email) > 0 {
+		if len(uid.Id) > 0 {
+			uid.Id += " "
+		}
+		uid.Id += "<"
+		uid.Id += email
+		uid.Id += ">"
+	}
+	return uid
+}
+
+func (uid *UserId) parse(r io.Reader) (err error) {
+	// RFC 4880, section 5.11
+	b, err := ioutil.ReadAll(r)
+	if err != nil {
+		return
+	}
+	uid.Id = string(b)
+	uid.Name, uid.Comment, uid.Email = parseUserId(uid.Id)
+	return
+}
+
+// Serialize marshals uid to w in the form of an OpenPGP packet, including
+// header.
+func (uid *UserId) Serialize(w io.Writer) error {
+	err := serializeHeader(w, packetTypeUserId, len(uid.Id))
+	if err != nil {
+		return err
+	}
+	_, err = w.Write([]byte(uid.Id))
+	return err
+}
+
+// parseUserId extracts the name, comment and email from a user id string that
+// is formatted as "Full Name (Comment) <email@example.com>".
+func parseUserId(id string) (name, comment, email string) {
+	var n, c, e struct {
+		start, end int
+	}
+	var state int
+
+	for offset, rune := range id {
+		switch state {
+		case 0:
+			// Entering name
+			n.start = offset
+			state = 1
+			fallthrough
+		case 1:
+			// In name
+			if rune == '(' {
+				state = 2
+				n.end = offset
+			} else if rune == '<' {
+				state = 5
+				n.end = offset
+			}
+		case 2:
+			// Entering comment
+			c.start = offset
+			state = 3
+			fallthrough
+		case 3:
+			// In comment
+			if rune == ')' {
+				state = 4
+				c.end = offset
+			}
+		case 4:
+			// Between comment and email
+			if rune == '<' {
+				state = 5
+			}
+		case 5:
+			// Entering email
+			e.start = offset
+			state = 6
+			fallthrough
+		case 6:
+			// In email
+			if rune == '>' {
+				state = 7
+				e.end = offset
+			}
+		default:
+			// After email
+		}
+	}
+	switch state {
+	case 1:
+		// ended in the name
+		n.end = len(id)
+	case 3:
+		// ended in comment
+		c.end = len(id)
+	case 6:
+		// ended in email
+		e.end = len(id)
+	}
+
+	name = strings.TrimSpace(id[n.start:n.end])
+	comment = strings.TrimSpace(id[c.start:c.end])
+	email = strings.TrimSpace(id[e.start:e.end])
+	return
+}
diff --git a/vendor/golang.org/x/crypto/openpgp/read.go b/vendor/golang.org/x/crypto/openpgp/read.go
new file mode 100644
index 0000000000..48a8931468
--- /dev/null
+++ b/vendor/golang.org/x/crypto/openpgp/read.go
@@ -0,0 +1,448 @@
+// Copyright 2011 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 openpgp implements high level operations on OpenPGP messages.
+//
+// Deprecated: this package is unmaintained except for security fixes. New
+// applications should consider a more focused, modern alternative to OpenPGP
+// for their specific task. If you are required to interoperate with OpenPGP
+// systems and need a maintained package, consider a community fork.
+// See https://golang.org/issue/44226.
+package openpgp // import "golang.org/x/crypto/openpgp"
+
+import (
+	"crypto"
+	_ "crypto/sha256"
+	"hash"
+	"io"
+	"strconv"
+
+	"golang.org/x/crypto/openpgp/armor"
+	"golang.org/x/crypto/openpgp/errors"
+	"golang.org/x/crypto/openpgp/packet"
+)
+
+// SignatureType is the armor type for a PGP signature.
+var SignatureType = "PGP SIGNATURE"
+
+// readArmored reads an armored block with the given type.
+func readArmored(r io.Reader, expectedType string) (body io.Reader, err error) {
+	block, err := armor.Decode(r)
+	if err != nil {
+		return
+	}
+
+	if block.Type != expectedType {
+		return nil, errors.InvalidArgumentError("expected '" + expectedType + "', got: " + block.Type)
+	}
+
+	return block.Body, nil
+}
+
+// MessageDetails contains the result of parsing an OpenPGP encrypted and/or
+// signed message.
+type MessageDetails struct {
+	IsEncrypted              bool                // true if the message was encrypted.
+	EncryptedToKeyIds        []uint64            // the list of recipient key ids.
+	IsSymmetricallyEncrypted bool                // true if a passphrase could have decrypted the message.
+	DecryptedWith            Key                 // the private key used to decrypt the message, if any.
+	IsSigned                 bool                // true if the message is signed.
+	SignedByKeyId            uint64              // the key id of the signer, if any.
+	SignedBy                 *Key                // the key of the signer, if available.
+	LiteralData              *packet.LiteralData // the metadata of the contents
+	UnverifiedBody           io.Reader           // the contents of the message.
+
+	// If IsSigned is true and SignedBy is non-zero then the signature will
+	// be verified as UnverifiedBody is read. The signature cannot be
+	// checked until the whole of UnverifiedBody is read so UnverifiedBody
+	// must be consumed until EOF before the data can be trusted. Even if a
+	// message isn't signed (or the signer is unknown) the data may contain
+	// an authentication code that is only checked once UnverifiedBody has
+	// been consumed. Once EOF has been seen, the following fields are
+	// valid. (An authentication code failure is reported as a
+	// SignatureError error when reading from UnverifiedBody.)
+	SignatureError error               // nil if the signature is good.
+	Signature      *packet.Signature   // the signature packet itself, if v4 (default)
+	SignatureV3    *packet.SignatureV3 // the signature packet if it is a v2 or v3 signature
+
+	decrypted io.ReadCloser
+}
+
+// A PromptFunction is used as a callback by functions that may need to decrypt
+// a private key, or prompt for a passphrase. It is called with a list of
+// acceptable, encrypted private keys and a boolean that indicates whether a
+// passphrase is usable. It should either decrypt a private key or return a
+// passphrase to try. If the decrypted private key or given passphrase isn't
+// correct, the function will be called again, forever. Any error returned will
+// be passed up.
+type PromptFunction func(keys []Key, symmetric bool) ([]byte, error)
+
+// A keyEnvelopePair is used to store a private key with the envelope that
+// contains a symmetric key, encrypted with that key.
+type keyEnvelopePair struct {
+	key          Key
+	encryptedKey *packet.EncryptedKey
+}
+
+// ReadMessage parses an OpenPGP message that may be signed and/or encrypted.
+// The given KeyRing should contain both public keys (for signature
+// verification) and, possibly encrypted, private keys for decrypting.
+// If config is nil, sensible defaults will be used.
+func ReadMessage(r io.Reader, keyring KeyRing, prompt PromptFunction, config *packet.Config) (md *MessageDetails, err error) {
+	var p packet.Packet
+
+	var symKeys []*packet.SymmetricKeyEncrypted
+	var pubKeys []keyEnvelopePair
+	var se *packet.SymmetricallyEncrypted
+
+	packets := packet.NewReader(r)
+	md = new(MessageDetails)
+	md.IsEncrypted = true
+
+	// The message, if encrypted, starts with a number of packets
+	// containing an encrypted decryption key. The decryption key is either
+	// encrypted to a public key, or with a passphrase. This loop
+	// collects these packets.
+ParsePackets:
+	for {
+		p, err = packets.Next()
+		if err != nil {
+			return nil, err
+		}
+		switch p := p.(type) {
+		case *packet.SymmetricKeyEncrypted:
+			// This packet contains the decryption key encrypted with a passphrase.
+			md.IsSymmetricallyEncrypted = true
+			symKeys = append(symKeys, p)
+		case *packet.EncryptedKey:
+			// This packet contains the decryption key encrypted to a public key.
+			md.EncryptedToKeyIds = append(md.EncryptedToKeyIds, p.KeyId)
+			switch p.Algo {
+			case packet.PubKeyAlgoRSA, packet.PubKeyAlgoRSAEncryptOnly, packet.PubKeyAlgoElGamal:
+				break
+			default:
+				continue
+			}
+			var keys []Key
+			if p.KeyId == 0 {
+				keys = keyring.DecryptionKeys()
+			} else {
+				keys = keyring.KeysById(p.KeyId)
+			}
+			for _, k := range keys {
+				pubKeys = append(pubKeys, keyEnvelopePair{k, p})
+			}
+		case *packet.SymmetricallyEncrypted:
+			se = p
+			break ParsePackets
+		case *packet.Compressed, *packet.LiteralData, *packet.OnePassSignature:
+			// This message isn't encrypted.
+			if len(symKeys) != 0 || len(pubKeys) != 0 {
+				return nil, errors.StructuralError("key material not followed by encrypted message")
+			}
+			packets.Unread(p)
+			return readSignedMessage(packets, nil, keyring)
+		}
+	}
+
+	var candidates []Key
+	var decrypted io.ReadCloser
+
+	// Now that we have the list of encrypted keys we need to decrypt at
+	// least one of them or, if we cannot, we need to call the prompt
+	// function so that it can decrypt a key or give us a passphrase.
+FindKey:
+	for {
+		// See if any of the keys already have a private key available
+		candidates = candidates[:0]
+		candidateFingerprints := make(map[string]bool)
+
+		for _, pk := range pubKeys {
+			if pk.key.PrivateKey == nil {
+				continue
+			}
+			if !pk.key.PrivateKey.Encrypted {
+				if len(pk.encryptedKey.Key) == 0 {
+					pk.encryptedKey.Decrypt(pk.key.PrivateKey, config)
+				}
+				if len(pk.encryptedKey.Key) == 0 {
+					continue
+				}
+				decrypted, err = se.Decrypt(pk.encryptedKey.CipherFunc, pk.encryptedKey.Key)
+				if err != nil && err != errors.ErrKeyIncorrect {
+					return nil, err
+				}
+				if decrypted != nil {
+					md.DecryptedWith = pk.key
+					break FindKey
+				}
+			} else {
+				fpr := string(pk.key.PublicKey.Fingerprint[:])
+				if v := candidateFingerprints[fpr]; v {
+					continue
+				}
+				candidates = append(candidates, pk.key)
+				candidateFingerprints[fpr] = true
+			}
+		}
+
+		if len(candidates) == 0 && len(symKeys) == 0 {
+			return nil, errors.ErrKeyIncorrect
+		}
+
+		if prompt == nil {
+			return nil, errors.ErrKeyIncorrect
+		}
+
+		passphrase, err := prompt(candidates, len(symKeys) != 0)
+		if err != nil {
+			return nil, err
+		}
+
+		// Try the symmetric passphrase first
+		if len(symKeys) != 0 && passphrase != nil {
+			for _, s := range symKeys {
+				key, cipherFunc, err := s.Decrypt(passphrase)
+				if err == nil {
+					decrypted, err = se.Decrypt(cipherFunc, key)
+					if err != nil && err != errors.ErrKeyIncorrect {
+						return nil, err
+					}
+					if decrypted != nil {
+						break FindKey
+					}
+				}
+
+			}
+		}
+	}
+
+	md.decrypted = decrypted
+	if err := packets.Push(decrypted); err != nil {
+		return nil, err
+	}
+	return readSignedMessage(packets, md, keyring)
+}
+
+// readSignedMessage reads a possibly signed message if mdin is non-zero then
+// that structure is updated and returned. Otherwise a fresh MessageDetails is
+// used.
+func readSignedMessage(packets *packet.Reader, mdin *MessageDetails, keyring KeyRing) (md *MessageDetails, err error) {
+	if mdin == nil {
+		mdin = new(MessageDetails)
+	}
+	md = mdin
+
+	var p packet.Packet
+	var h hash.Hash
+	var wrappedHash hash.Hash
+FindLiteralData:
+	for {
+		p, err = packets.Next()
+		if err != nil {
+			return nil, err
+		}
+		switch p := p.(type) {
+		case *packet.Compressed:
+			if err := packets.Push(p.Body); err != nil {
+				return nil, err
+			}
+		case *packet.OnePassSignature:
+			if !p.IsLast {
+				return nil, errors.UnsupportedError("nested signatures")
+			}
+
+			h, wrappedHash, err = hashForSignature(p.Hash, p.SigType)
+			if err != nil {
+				md = nil
+				return
+			}
+
+			md.IsSigned = true
+			md.SignedByKeyId = p.KeyId
+			keys := keyring.KeysByIdUsage(p.KeyId, packet.KeyFlagSign)
+			if len(keys) > 0 {
+				md.SignedBy = &keys[0]
+			}
+		case *packet.LiteralData:
+			md.LiteralData = p
+			break FindLiteralData
+		}
+	}
+
+	if md.SignedBy != nil {
+		md.UnverifiedBody = &signatureCheckReader{packets, h, wrappedHash, md}
+	} else if md.decrypted != nil {
+		md.UnverifiedBody = checkReader{md}
+	} else {
+		md.UnverifiedBody = md.LiteralData.Body
+	}
+
+	return md, nil
+}
+
+// hashForSignature returns a pair of hashes that can be used to verify a
+// signature. The signature may specify that the contents of the signed message
+// should be preprocessed (i.e. to normalize line endings). Thus this function
+// returns two hashes. The second should be used to hash the message itself and
+// performs any needed preprocessing.
+func hashForSignature(hashId crypto.Hash, sigType packet.SignatureType) (hash.Hash, hash.Hash, error) {
+	if !hashId.Available() {
+		return nil, nil, errors.UnsupportedError("hash not available: " + strconv.Itoa(int(hashId)))
+	}
+	h := hashId.New()
+
+	switch sigType {
+	case packet.SigTypeBinary:
+		return h, h, nil
+	case packet.SigTypeText:
+		return h, NewCanonicalTextHash(h), nil
+	}
+
+	return nil, nil, errors.UnsupportedError("unsupported signature type: " + strconv.Itoa(int(sigType)))
+}
+
+// checkReader wraps an io.Reader from a LiteralData packet. When it sees EOF
+// it closes the ReadCloser from any SymmetricallyEncrypted packet to trigger
+// MDC checks.
+type checkReader struct {
+	md *MessageDetails
+}
+
+func (cr checkReader) Read(buf []byte) (n int, err error) {
+	n, err = cr.md.LiteralData.Body.Read(buf)
+	if err == io.EOF {
+		mdcErr := cr.md.decrypted.Close()
+		if mdcErr != nil {
+			err = mdcErr
+		}
+	}
+	return
+}
+
+// signatureCheckReader wraps an io.Reader from a LiteralData packet and hashes
+// the data as it is read. When it sees an EOF from the underlying io.Reader
+// it parses and checks a trailing Signature packet and triggers any MDC checks.
+type signatureCheckReader struct {
+	packets        *packet.Reader
+	h, wrappedHash hash.Hash
+	md             *MessageDetails
+}
+
+func (scr *signatureCheckReader) Read(buf []byte) (n int, err error) {
+	n, err = scr.md.LiteralData.Body.Read(buf)
+	scr.wrappedHash.Write(buf[:n])
+	if err == io.EOF {
+		var p packet.Packet
+		p, scr.md.SignatureError = scr.packets.Next()
+		if scr.md.SignatureError != nil {
+			return
+		}
+
+		var ok bool
+		if scr.md.Signature, ok = p.(*packet.Signature); ok {
+			scr.md.SignatureError = scr.md.SignedBy.PublicKey.VerifySignature(scr.h, scr.md.Signature)
+		} else if scr.md.SignatureV3, ok = p.(*packet.SignatureV3); ok {
+			scr.md.SignatureError = scr.md.SignedBy.PublicKey.VerifySignatureV3(scr.h, scr.md.SignatureV3)
+		} else {
+			scr.md.SignatureError = errors.StructuralError("LiteralData not followed by Signature")
+			return
+		}
+
+		// The SymmetricallyEncrypted packet, if any, might have an
+		// unsigned hash of its own. In order to check this we need to
+		// close that Reader.
+		if scr.md.decrypted != nil {
+			mdcErr := scr.md.decrypted.Close()
+			if mdcErr != nil {
+				err = mdcErr
+			}
+		}
+	}
+	return
+}
+
+// CheckDetachedSignature takes a signed file and a detached signature and
+// returns the signer if the signature is valid. If the signer isn't known,
+// ErrUnknownIssuer is returned.
+func CheckDetachedSignature(keyring KeyRing, signed, signature io.Reader) (signer *Entity, err error) {
+	var issuerKeyId uint64
+	var hashFunc crypto.Hash
+	var sigType packet.SignatureType
+	var keys []Key
+	var p packet.Packet
+
+	packets := packet.NewReader(signature)
+	for {
+		p, err = packets.Next()
+		if err == io.EOF {
+			return nil, errors.ErrUnknownIssuer
+		}
+		if err != nil {
+			return nil, err
+		}
+
+		switch sig := p.(type) {
+		case *packet.Signature:
+			if sig.IssuerKeyId == nil {
+				return nil, errors.StructuralError("signature doesn't have an issuer")
+			}
+			issuerKeyId = *sig.IssuerKeyId
+			hashFunc = sig.Hash
+			sigType = sig.SigType
+		case *packet.SignatureV3:
+			issuerKeyId = sig.IssuerKeyId
+			hashFunc = sig.Hash
+			sigType = sig.SigType
+		default:
+			return nil, errors.StructuralError("non signature packet found")
+		}
+
+		keys = keyring.KeysByIdUsage(issuerKeyId, packet.KeyFlagSign)
+		if len(keys) > 0 {
+			break
+		}
+	}
+
+	if len(keys) == 0 {
+		panic("unreachable")
+	}
+
+	h, wrappedHash, err := hashForSignature(hashFunc, sigType)
+	if err != nil {
+		return nil, err
+	}
+
+	if _, err := io.Copy(wrappedHash, signed); err != nil && err != io.EOF {
+		return nil, err
+	}
+
+	for _, key := range keys {
+		switch sig := p.(type) {
+		case *packet.Signature:
+			err = key.PublicKey.VerifySignature(h, sig)
+		case *packet.SignatureV3:
+			err = key.PublicKey.VerifySignatureV3(h, sig)
+		default:
+			panic("unreachable")
+		}
+
+		if err == nil {
+			return key.Entity, nil
+		}
+	}
+
+	return nil, err
+}
+
+// CheckArmoredDetachedSignature performs the same actions as
+// CheckDetachedSignature but expects the signature to be armored.
+func CheckArmoredDetachedSignature(keyring KeyRing, signed, signature io.Reader) (signer *Entity, err error) {
+	body, err := readArmored(signature, SignatureType)
+	if err != nil {
+		return
+	}
+
+	return CheckDetachedSignature(keyring, signed, body)
+}
diff --git a/vendor/golang.org/x/crypto/openpgp/s2k/s2k.go b/vendor/golang.org/x/crypto/openpgp/s2k/s2k.go
new file mode 100644
index 0000000000..9de04958ea
--- /dev/null
+++ b/vendor/golang.org/x/crypto/openpgp/s2k/s2k.go
@@ -0,0 +1,279 @@
+// Copyright 2011 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 s2k implements the various OpenPGP string-to-key transforms as
+// specified in RFC 4800 section 3.7.1.
+//
+// Deprecated: this package is unmaintained except for security fixes. New
+// applications should consider a more focused, modern alternative to OpenPGP
+// for their specific task. If you are required to interoperate with OpenPGP
+// systems and need a maintained package, consider a community fork.
+// See https://golang.org/issue/44226.
+package s2k // import "golang.org/x/crypto/openpgp/s2k"
+
+import (
+	"crypto"
+	"hash"
+	"io"
+	"strconv"
+
+	"golang.org/x/crypto/openpgp/errors"
+)
+
+// Config collects configuration parameters for s2k key-stretching
+// transformatioms. A nil *Config is valid and results in all default
+// values. Currently, Config is used only by the Serialize function in
+// this package.
+type Config struct {
+	// Hash is the default hash function to be used. If
+	// nil, SHA1 is used.
+	Hash crypto.Hash
+	// S2KCount is only used for symmetric encryption. It
+	// determines the strength of the passphrase stretching when
+	// the said passphrase is hashed to produce a key. S2KCount
+	// should be between 1024 and 65011712, inclusive. If Config
+	// is nil or S2KCount is 0, the value 65536 used. Not all
+	// values in the above range can be represented. S2KCount will
+	// be rounded up to the next representable value if it cannot
+	// be encoded exactly. When set, it is strongly encrouraged to
+	// use a value that is at least 65536. See RFC 4880 Section
+	// 3.7.1.3.
+	S2KCount int
+}
+
+func (c *Config) hash() crypto.Hash {
+	if c == nil || uint(c.Hash) == 0 {
+		// SHA1 is the historical default in this package.
+		return crypto.SHA1
+	}
+
+	return c.Hash
+}
+
+func (c *Config) encodedCount() uint8 {
+	if c == nil || c.S2KCount == 0 {
+		return 96 // The common case. Correspoding to 65536
+	}
+
+	i := c.S2KCount
+	switch {
+	// Behave like GPG. Should we make 65536 the lowest value used?
+	case i < 1024:
+		i = 1024
+	case i > 65011712:
+		i = 65011712
+	}
+
+	return encodeCount(i)
+}
+
+// encodeCount converts an iterative "count" in the range 1024 to
+// 65011712, inclusive, to an encoded count. The return value is the
+// octet that is actually stored in the GPG file. encodeCount panics
+// if i is not in the above range (encodedCount above takes care to
+// pass i in the correct range). See RFC 4880 Section 3.7.7.1.
+func encodeCount(i int) uint8 {
+	if i < 1024 || i > 65011712 {
+		panic("count arg i outside the required range")
+	}
+
+	for encoded := 0; encoded < 256; encoded++ {
+		count := decodeCount(uint8(encoded))
+		if count >= i {
+			return uint8(encoded)
+		}
+	}
+
+	return 255
+}
+
+// decodeCount returns the s2k mode 3 iterative "count" corresponding to
+// the encoded octet c.
+func decodeCount(c uint8) int {
+	return (16 + int(c&15)) << (uint32(c>>4) + 6)
+}
+
+// Simple writes to out the result of computing the Simple S2K function (RFC
+// 4880, section 3.7.1.1) using the given hash and input passphrase.
+func Simple(out []byte, h hash.Hash, in []byte) {
+	Salted(out, h, in, nil)
+}
+
+var zero [1]byte
+
+// Salted writes to out the result of computing the Salted S2K function (RFC
+// 4880, section 3.7.1.2) using the given hash, input passphrase and salt.
+func Salted(out []byte, h hash.Hash, in []byte, salt []byte) {
+	done := 0
+	var digest []byte
+
+	for i := 0; done < len(out); i++ {
+		h.Reset()
+		for j := 0; j < i; j++ {
+			h.Write(zero[:])
+		}
+		h.Write(salt)
+		h.Write(in)
+		digest = h.Sum(digest[:0])
+		n := copy(out[done:], digest)
+		done += n
+	}
+}
+
+// Iterated writes to out the result of computing the Iterated and Salted S2K
+// function (RFC 4880, section 3.7.1.3) using the given hash, input passphrase,
+// salt and iteration count.
+func Iterated(out []byte, h hash.Hash, in []byte, salt []byte, count int) {
+	combined := make([]byte, len(in)+len(salt))
+	copy(combined, salt)
+	copy(combined[len(salt):], in)
+
+	if count < len(combined) {
+		count = len(combined)
+	}
+
+	done := 0
+	var digest []byte
+	for i := 0; done < len(out); i++ {
+		h.Reset()
+		for j := 0; j < i; j++ {
+			h.Write(zero[:])
+		}
+		written := 0
+		for written < count {
+			if written+len(combined) > count {
+				todo := count - written
+				h.Write(combined[:todo])
+				written = count
+			} else {
+				h.Write(combined)
+				written += len(combined)
+			}
+		}
+		digest = h.Sum(digest[:0])
+		n := copy(out[done:], digest)
+		done += n
+	}
+}
+
+// Parse reads a binary specification for a string-to-key transformation from r
+// and returns a function which performs that transform.
+func Parse(r io.Reader) (f func(out, in []byte), err error) {
+	var buf [9]byte
+
+	_, err = io.ReadFull(r, buf[:2])
+	if err != nil {
+		return
+	}
+
+	hash, ok := HashIdToHash(buf[1])
+	if !ok {
+		return nil, errors.UnsupportedError("hash for S2K function: " + strconv.Itoa(int(buf[1])))
+	}
+	if !hash.Available() {
+		return nil, errors.UnsupportedError("hash not available: " + strconv.Itoa(int(hash)))
+	}
+	h := hash.New()
+
+	switch buf[0] {
+	case 0:
+		f := func(out, in []byte) {
+			Simple(out, h, in)
+		}
+		return f, nil
+	case 1:
+		_, err = io.ReadFull(r, buf[:8])
+		if err != nil {
+			return
+		}
+		f := func(out, in []byte) {
+			Salted(out, h, in, buf[:8])
+		}
+		return f, nil
+	case 3:
+		_, err = io.ReadFull(r, buf[:9])
+		if err != nil {
+			return
+		}
+		count := decodeCount(buf[8])
+		f := func(out, in []byte) {
+			Iterated(out, h, in, buf[:8], count)
+		}
+		return f, nil
+	}
+
+	return nil, errors.UnsupportedError("S2K function")
+}
+
+// Serialize salts and stretches the given passphrase and writes the
+// resulting key into key. It also serializes an S2K descriptor to
+// w. The key stretching can be configured with c, which may be
+// nil. In that case, sensible defaults will be used.
+func Serialize(w io.Writer, key []byte, rand io.Reader, passphrase []byte, c *Config) error {
+	var buf [11]byte
+	buf[0] = 3 /* iterated and salted */
+	buf[1], _ = HashToHashId(c.hash())
+	salt := buf[2:10]
+	if _, err := io.ReadFull(rand, salt); err != nil {
+		return err
+	}
+	encodedCount := c.encodedCount()
+	count := decodeCount(encodedCount)
+	buf[10] = encodedCount
+	if _, err := w.Write(buf[:]); err != nil {
+		return err
+	}
+
+	Iterated(key, c.hash().New(), passphrase, salt, count)
+	return nil
+}
+
+// hashToHashIdMapping contains pairs relating OpenPGP's hash identifier with
+// Go's crypto.Hash type. See RFC 4880, section 9.4.
+var hashToHashIdMapping = []struct {
+	id   byte
+	hash crypto.Hash
+	name string
+}{
+	{1, crypto.MD5, "MD5"},
+	{2, crypto.SHA1, "SHA1"},
+	{3, crypto.RIPEMD160, "RIPEMD160"},
+	{8, crypto.SHA256, "SHA256"},
+	{9, crypto.SHA384, "SHA384"},
+	{10, crypto.SHA512, "SHA512"},
+	{11, crypto.SHA224, "SHA224"},
+}
+
+// HashIdToHash returns a crypto.Hash which corresponds to the given OpenPGP
+// hash id.
+func HashIdToHash(id byte) (h crypto.Hash, ok bool) {
+	for _, m := range hashToHashIdMapping {
+		if m.id == id {
+			return m.hash, true
+		}
+	}
+	return 0, false
+}
+
+// HashIdToString returns the name of the hash function corresponding to the
+// given OpenPGP hash id.
+func HashIdToString(id byte) (name string, ok bool) {
+	for _, m := range hashToHashIdMapping {
+		if m.id == id {
+			return m.name, true
+		}
+	}
+
+	return "", false
+}
+
+// HashIdToHash returns an OpenPGP hash id which corresponds the given Hash.
+func HashToHashId(h crypto.Hash) (id byte, ok bool) {
+	for _, m := range hashToHashIdMapping {
+		if m.hash == h {
+			return m.id, true
+		}
+	}
+	return 0, false
+}
diff --git a/vendor/golang.org/x/crypto/openpgp/write.go b/vendor/golang.org/x/crypto/openpgp/write.go
new file mode 100644
index 0000000000..4ee71784eb
--- /dev/null
+++ b/vendor/golang.org/x/crypto/openpgp/write.go
@@ -0,0 +1,418 @@
+// Copyright 2011 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 openpgp
+
+import (
+	"crypto"
+	"hash"
+	"io"
+	"strconv"
+	"time"
+
+	"golang.org/x/crypto/openpgp/armor"
+	"golang.org/x/crypto/openpgp/errors"
+	"golang.org/x/crypto/openpgp/packet"
+	"golang.org/x/crypto/openpgp/s2k"
+)
+
+// DetachSign signs message with the private key from signer (which must
+// already have been decrypted) and writes the signature to w.
+// If config is nil, sensible defaults will be used.
+func DetachSign(w io.Writer, signer *Entity, message io.Reader, config *packet.Config) error {
+	return detachSign(w, signer, message, packet.SigTypeBinary, config)
+}
+
+// ArmoredDetachSign signs message with the private key from signer (which
+// must already have been decrypted) and writes an armored signature to w.
+// If config is nil, sensible defaults will be used.
+func ArmoredDetachSign(w io.Writer, signer *Entity, message io.Reader, config *packet.Config) (err error) {
+	return armoredDetachSign(w, signer, message, packet.SigTypeBinary, config)
+}
+
+// DetachSignText signs message (after canonicalising the line endings) with
+// the private key from signer (which must already have been decrypted) and
+// writes the signature to w.
+// If config is nil, sensible defaults will be used.
+func DetachSignText(w io.Writer, signer *Entity, message io.Reader, config *packet.Config) error {
+	return detachSign(w, signer, message, packet.SigTypeText, config)
+}
+
+// ArmoredDetachSignText signs message (after canonicalising the line endings)
+// with the private key from signer (which must already have been decrypted)
+// and writes an armored signature to w.
+// If config is nil, sensible defaults will be used.
+func ArmoredDetachSignText(w io.Writer, signer *Entity, message io.Reader, config *packet.Config) error {
+	return armoredDetachSign(w, signer, message, packet.SigTypeText, config)
+}
+
+func armoredDetachSign(w io.Writer, signer *Entity, message io.Reader, sigType packet.SignatureType, config *packet.Config) (err error) {
+	out, err := armor.Encode(w, SignatureType, nil)
+	if err != nil {
+		return
+	}
+	err = detachSign(out, signer, message, sigType, config)
+	if err != nil {
+		return
+	}
+	return out.Close()
+}
+
+func detachSign(w io.Writer, signer *Entity, message io.Reader, sigType packet.SignatureType, config *packet.Config) (err error) {
+	if signer.PrivateKey == nil {
+		return errors.InvalidArgumentError("signing key doesn't have a private key")
+	}
+	if signer.PrivateKey.Encrypted {
+		return errors.InvalidArgumentError("signing key is encrypted")
+	}
+
+	sig := new(packet.Signature)
+	sig.SigType = sigType
+	sig.PubKeyAlgo = signer.PrivateKey.PubKeyAlgo
+	sig.Hash = config.Hash()
+	sig.CreationTime = config.Now()
+	sig.IssuerKeyId = &signer.PrivateKey.KeyId
+
+	h, wrappedHash, err := hashForSignature(sig.Hash, sig.SigType)
+	if err != nil {
+		return
+	}
+	io.Copy(wrappedHash, message)
+
+	err = sig.Sign(h, signer.PrivateKey, config)
+	if err != nil {
+		return
+	}
+
+	return sig.Serialize(w)
+}
+
+// FileHints contains metadata about encrypted files. This metadata is, itself,
+// encrypted.
+type FileHints struct {
+	// IsBinary can be set to hint that the contents are binary data.
+	IsBinary bool
+	// FileName hints at the name of the file that should be written. It's
+	// truncated to 255 bytes if longer. It may be empty to suggest that the
+	// file should not be written to disk. It may be equal to "_CONSOLE" to
+	// suggest the data should not be written to disk.
+	FileName string
+	// ModTime contains the modification time of the file, or the zero time if not applicable.
+	ModTime time.Time
+}
+
+// SymmetricallyEncrypt acts like gpg -c: it encrypts a file with a passphrase.
+// The resulting WriteCloser must be closed after the contents of the file have
+// been written.
+// If config is nil, sensible defaults will be used.
+func SymmetricallyEncrypt(ciphertext io.Writer, passphrase []byte, hints *FileHints, config *packet.Config) (plaintext io.WriteCloser, err error) {
+	if hints == nil {
+		hints = &FileHints{}
+	}
+
+	key, err := packet.SerializeSymmetricKeyEncrypted(ciphertext, passphrase, config)
+	if err != nil {
+		return
+	}
+	w, err := packet.SerializeSymmetricallyEncrypted(ciphertext, config.Cipher(), key, config)
+	if err != nil {
+		return
+	}
+
+	literaldata := w
+	if algo := config.Compression(); algo != packet.CompressionNone {
+		var compConfig *packet.CompressionConfig
+		if config != nil {
+			compConfig = config.CompressionConfig
+		}
+		literaldata, err = packet.SerializeCompressed(w, algo, compConfig)
+		if err != nil {
+			return
+		}
+	}
+
+	var epochSeconds uint32
+	if !hints.ModTime.IsZero() {
+		epochSeconds = uint32(hints.ModTime.Unix())
+	}
+	return packet.SerializeLiteral(literaldata, hints.IsBinary, hints.FileName, epochSeconds)
+}
+
+// intersectPreferences mutates and returns a prefix of a that contains only
+// the values in the intersection of a and b. The order of a is preserved.
+func intersectPreferences(a []uint8, b []uint8) (intersection []uint8) {
+	var j int
+	for _, v := range a {
+		for _, v2 := range b {
+			if v == v2 {
+				a[j] = v
+				j++
+				break
+			}
+		}
+	}
+
+	return a[:j]
+}
+
+func hashToHashId(h crypto.Hash) uint8 {
+	v, ok := s2k.HashToHashId(h)
+	if !ok {
+		panic("tried to convert unknown hash")
+	}
+	return v
+}
+
+// writeAndSign writes the data as a payload package and, optionally, signs
+// it. hints contains optional information, that is also encrypted,
+// that aids the recipients in processing the message. The resulting
+// WriteCloser must be closed after the contents of the file have been
+// written. If config is nil, sensible defaults will be used.
+func writeAndSign(payload io.WriteCloser, candidateHashes []uint8, signed *Entity, hints *FileHints, config *packet.Config) (plaintext io.WriteCloser, err error) {
+	var signer *packet.PrivateKey
+	if signed != nil {
+		signKey, ok := signed.signingKey(config.Now())
+		if !ok {
+			return nil, errors.InvalidArgumentError("no valid signing keys")
+		}
+		signer = signKey.PrivateKey
+		if signer == nil {
+			return nil, errors.InvalidArgumentError("no private key in signing key")
+		}
+		if signer.Encrypted {
+			return nil, errors.InvalidArgumentError("signing key must be decrypted")
+		}
+	}
+
+	var hash crypto.Hash
+	for _, hashId := range candidateHashes {
+		if h, ok := s2k.HashIdToHash(hashId); ok && h.Available() {
+			hash = h
+			break
+		}
+	}
+
+	// If the hash specified by config is a candidate, we'll use that.
+	if configuredHash := config.Hash(); configuredHash.Available() {
+		for _, hashId := range candidateHashes {
+			if h, ok := s2k.HashIdToHash(hashId); ok && h == configuredHash {
+				hash = h
+				break
+			}
+		}
+	}
+
+	if hash == 0 {
+		hashId := candidateHashes[0]
+		name, ok := s2k.HashIdToString(hashId)
+		if !ok {
+			name = "#" + strconv.Itoa(int(hashId))
+		}
+		return nil, errors.InvalidArgumentError("cannot encrypt because no candidate hash functions are compiled in. (Wanted " + name + " in this case.)")
+	}
+
+	if signer != nil {
+		ops := &packet.OnePassSignature{
+			SigType:    packet.SigTypeBinary,
+			Hash:       hash,
+			PubKeyAlgo: signer.PubKeyAlgo,
+			KeyId:      signer.KeyId,
+			IsLast:     true,
+		}
+		if err := ops.Serialize(payload); err != nil {
+			return nil, err
+		}
+	}
+
+	if hints == nil {
+		hints = &FileHints{}
+	}
+
+	w := payload
+	if signer != nil {
+		// If we need to write a signature packet after the literal
+		// data then we need to stop literalData from closing
+		// encryptedData.
+		w = noOpCloser{w}
+
+	}
+	var epochSeconds uint32
+	if !hints.ModTime.IsZero() {
+		epochSeconds = uint32(hints.ModTime.Unix())
+	}
+	literalData, err := packet.SerializeLiteral(w, hints.IsBinary, hints.FileName, epochSeconds)
+	if err != nil {
+		return nil, err
+	}
+
+	if signer != nil {
+		return signatureWriter{payload, literalData, hash, hash.New(), signer, config}, nil
+	}
+	return literalData, nil
+}
+
+// Encrypt encrypts a message to a number of recipients and, optionally, signs
+// it. hints contains optional information, that is also encrypted, that aids
+// the recipients in processing the message. The resulting WriteCloser must
+// be closed after the contents of the file have been written.
+// If config is nil, sensible defaults will be used.
+func Encrypt(ciphertext io.Writer, to []*Entity, signed *Entity, hints *FileHints, config *packet.Config) (plaintext io.WriteCloser, err error) {
+	if len(to) == 0 {
+		return nil, errors.InvalidArgumentError("no encryption recipient provided")
+	}
+
+	// These are the possible ciphers that we'll use for the message.
+	candidateCiphers := []uint8{
+		uint8(packet.CipherAES128),
+		uint8(packet.CipherAES256),
+		uint8(packet.CipherCAST5),
+	}
+	// These are the possible hash functions that we'll use for the signature.
+	candidateHashes := []uint8{
+		hashToHashId(crypto.SHA256),
+		hashToHashId(crypto.SHA384),
+		hashToHashId(crypto.SHA512),
+		hashToHashId(crypto.SHA1),
+		hashToHashId(crypto.RIPEMD160),
+	}
+	// In the event that a recipient doesn't specify any supported ciphers
+	// or hash functions, these are the ones that we assume that every
+	// implementation supports.
+	defaultCiphers := candidateCiphers[len(candidateCiphers)-1:]
+	defaultHashes := candidateHashes[len(candidateHashes)-1:]
+
+	encryptKeys := make([]Key, len(to))
+	for i := range to {
+		var ok bool
+		encryptKeys[i], ok = to[i].encryptionKey(config.Now())
+		if !ok {
+			return nil, errors.InvalidArgumentError("cannot encrypt a message to key id " + strconv.FormatUint(to[i].PrimaryKey.KeyId, 16) + " because it has no encryption keys")
+		}
+
+		sig := to[i].primaryIdentity().SelfSignature
+
+		preferredSymmetric := sig.PreferredSymmetric
+		if len(preferredSymmetric) == 0 {
+			preferredSymmetric = defaultCiphers
+		}
+		preferredHashes := sig.PreferredHash
+		if len(preferredHashes) == 0 {
+			preferredHashes = defaultHashes
+		}
+		candidateCiphers = intersectPreferences(candidateCiphers, preferredSymmetric)
+		candidateHashes = intersectPreferences(candidateHashes, preferredHashes)
+	}
+
+	if len(candidateCiphers) == 0 || len(candidateHashes) == 0 {
+		return nil, errors.InvalidArgumentError("cannot encrypt because recipient set shares no common algorithms")
+	}
+
+	cipher := packet.CipherFunction(candidateCiphers[0])
+	// If the cipher specified by config is a candidate, we'll use that.
+	configuredCipher := config.Cipher()
+	for _, c := range candidateCiphers {
+		cipherFunc := packet.CipherFunction(c)
+		if cipherFunc == configuredCipher {
+			cipher = cipherFunc
+			break
+		}
+	}
+
+	symKey := make([]byte, cipher.KeySize())
+	if _, err := io.ReadFull(config.Random(), symKey); err != nil {
+		return nil, err
+	}
+
+	for _, key := range encryptKeys {
+		if err := packet.SerializeEncryptedKey(ciphertext, key.PublicKey, cipher, symKey, config); err != nil {
+			return nil, err
+		}
+	}
+
+	payload, err := packet.SerializeSymmetricallyEncrypted(ciphertext, cipher, symKey, config)
+	if err != nil {
+		return
+	}
+
+	return writeAndSign(payload, candidateHashes, signed, hints, config)
+}
+
+// Sign signs a message. The resulting WriteCloser must be closed after the
+// contents of the file have been written.  hints contains optional information
+// that aids the recipients in processing the message.
+// If config is nil, sensible defaults will be used.
+func Sign(output io.Writer, signed *Entity, hints *FileHints, config *packet.Config) (input io.WriteCloser, err error) {
+	if signed == nil {
+		return nil, errors.InvalidArgumentError("no signer provided")
+	}
+
+	// These are the possible hash functions that we'll use for the signature.
+	candidateHashes := []uint8{
+		hashToHashId(crypto.SHA256),
+		hashToHashId(crypto.SHA384),
+		hashToHashId(crypto.SHA512),
+		hashToHashId(crypto.SHA1),
+		hashToHashId(crypto.RIPEMD160),
+	}
+	defaultHashes := candidateHashes[len(candidateHashes)-1:]
+	preferredHashes := signed.primaryIdentity().SelfSignature.PreferredHash
+	if len(preferredHashes) == 0 {
+		preferredHashes = defaultHashes
+	}
+	candidateHashes = intersectPreferences(candidateHashes, preferredHashes)
+	return writeAndSign(noOpCloser{output}, candidateHashes, signed, hints, config)
+}
+
+// signatureWriter hashes the contents of a message while passing it along to
+// literalData. When closed, it closes literalData, writes a signature packet
+// to encryptedData and then also closes encryptedData.
+type signatureWriter struct {
+	encryptedData io.WriteCloser
+	literalData   io.WriteCloser
+	hashType      crypto.Hash
+	h             hash.Hash
+	signer        *packet.PrivateKey
+	config        *packet.Config
+}
+
+func (s signatureWriter) Write(data []byte) (int, error) {
+	s.h.Write(data)
+	return s.literalData.Write(data)
+}
+
+func (s signatureWriter) Close() error {
+	sig := &packet.Signature{
+		SigType:      packet.SigTypeBinary,
+		PubKeyAlgo:   s.signer.PubKeyAlgo,
+		Hash:         s.hashType,
+		CreationTime: s.config.Now(),
+		IssuerKeyId:  &s.signer.KeyId,
+	}
+
+	if err := sig.Sign(s.h, s.signer, s.config); err != nil {
+		return err
+	}
+	if err := s.literalData.Close(); err != nil {
+		return err
+	}
+	if err := sig.Serialize(s.encryptedData); err != nil {
+		return err
+	}
+	return s.encryptedData.Close()
+}
+
+// noOpCloser is like an ioutil.NopCloser, but for an io.Writer.
+// TODO: we have two of these in OpenPGP packages alone. This probably needs
+// to be promoted somewhere more common.
+type noOpCloser struct {
+	w io.Writer
+}
+
+func (c noOpCloser) Write(data []byte) (n int, err error) {
+	return c.w.Write(data)
+}
+
+func (c noOpCloser) Close() error {
+	return nil
+}
diff --git a/vendor/golang.org/x/crypto/poly1305/poly1305_compat.go b/vendor/golang.org/x/crypto/poly1305/poly1305_compat.go
new file mode 100644
index 0000000000..dd975a32c9
--- /dev/null
+++ b/vendor/golang.org/x/crypto/poly1305/poly1305_compat.go
@@ -0,0 +1,91 @@
+// 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 poly1305 implements Poly1305 one-time message authentication code as
+// specified in https://cr.yp.to/mac/poly1305-20050329.pdf.
+//
+// Poly1305 is a fast, one-time authentication function. It is infeasible for an
+// attacker to generate an authenticator for a message without the key. However, a
+// key must only be used for a single message. Authenticating two different
+// messages with the same key allows an attacker to forge authenticators for other
+// messages with the same key.
+//
+// Poly1305 was originally coupled with AES in order to make Poly1305-AES. AES was
+// used with a fixed key in order to generate one-time keys from an nonce.
+// However, in this package AES isn't used and the one-time key is specified
+// directly.
+//
+// Deprecated: Poly1305 as implemented by this package is a cryptographic
+// building block that is not safe for general purpose use.
+// For encryption, use the full ChaCha20-Poly1305 construction implemented by
+// golang.org/x/crypto/chacha20poly1305. For authentication, use a general
+// purpose MAC such as HMAC implemented by crypto/hmac.
+package poly1305 // import "golang.org/x/crypto/poly1305"
+
+import "golang.org/x/crypto/internal/poly1305"
+
+// TagSize is the size, in bytes, of a poly1305 authenticator.
+//
+// For use with golang.org/x/crypto/chacha20poly1305, chacha20poly1305.Overhead
+// can be used instead.
+const TagSize = 16
+
+// Sum generates an authenticator for msg using a one-time key and puts the
+// 16-byte result into out. Authenticating two different messages with the same
+// key allows an attacker to forge messages at will.
+func Sum(out *[16]byte, m []byte, key *[32]byte) {
+	poly1305.Sum(out, m, key)
+}
+
+// Verify returns true if mac is a valid authenticator for m with the given key.
+func Verify(mac *[16]byte, m []byte, key *[32]byte) bool {
+	return poly1305.Verify(mac, m, key)
+}
+
+// New returns a new MAC computing an authentication
+// tag of all data written to it with the given key.
+// This allows writing the message progressively instead
+// of passing it as a single slice. Common users should use
+// the Sum function instead.
+//
+// The key must be unique for each message, as authenticating
+// two different messages with the same key allows an attacker
+// to forge messages at will.
+func New(key *[32]byte) *MAC {
+	return &MAC{mac: poly1305.New(key)}
+}
+
+// MAC is an io.Writer computing an authentication tag
+// of the data written to it.
+//
+// MAC cannot be used like common hash.Hash implementations,
+// because using a poly1305 key twice breaks its security.
+// Therefore writing data to a running MAC after calling
+// Sum or Verify causes it to panic.
+type MAC struct {
+	mac *poly1305.MAC
+}
+
+// Size returns the number of bytes Sum will return.
+func (h *MAC) Size() int { return TagSize }
+
+// Write adds more data to the running message authentication code.
+// It never returns an error.
+//
+// It must not be called after the first call of Sum or Verify.
+func (h *MAC) Write(p []byte) (n int, err error) {
+	return h.mac.Write(p)
+}
+
+// Sum computes the authenticator of all data written to the
+// message authentication code.
+func (h *MAC) Sum(b []byte) []byte {
+	return h.mac.Sum(b)
+}
+
+// Verify returns whether the authenticator of all data written to
+// the message authentication code matches the expected value.
+func (h *MAC) Verify(expected []byte) bool {
+	return h.mac.Verify(expected)
+}
diff --git a/vendor/golang.org/x/crypto/ripemd160/ripemd160.go b/vendor/golang.org/x/crypto/ripemd160/ripemd160.go
new file mode 100644
index 0000000000..cf3eeb158a
--- /dev/null
+++ b/vendor/golang.org/x/crypto/ripemd160/ripemd160.go
@@ -0,0 +1,124 @@
+// Copyright 2010 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 ripemd160 implements the RIPEMD-160 hash algorithm.
+//
+// Deprecated: RIPEMD-160 is a legacy hash and should not be used for new
+// applications. Also, this package does not and will not provide an optimized
+// implementation. Instead, use a modern hash like SHA-256 (from crypto/sha256).
+package ripemd160 // import "golang.org/x/crypto/ripemd160"
+
+// RIPEMD-160 is designed by Hans Dobbertin, Antoon Bosselaers, and Bart
+// Preneel with specifications available at:
+// http://homes.esat.kuleuven.be/~cosicart/pdf/AB-9601/AB-9601.pdf.
+
+import (
+	"crypto"
+	"hash"
+)
+
+func init() {
+	crypto.RegisterHash(crypto.RIPEMD160, New)
+}
+
+// The size of the checksum in bytes.
+const Size = 20
+
+// The block size of the hash algorithm in bytes.
+const BlockSize = 64
+
+const (
+	_s0 = 0x67452301
+	_s1 = 0xefcdab89
+	_s2 = 0x98badcfe
+	_s3 = 0x10325476
+	_s4 = 0xc3d2e1f0
+)
+
+// digest represents the partial evaluation of a checksum.
+type digest struct {
+	s  [5]uint32       // running context
+	x  [BlockSize]byte // temporary buffer
+	nx int             // index into x
+	tc uint64          // total count of bytes processed
+}
+
+func (d *digest) Reset() {
+	d.s[0], d.s[1], d.s[2], d.s[3], d.s[4] = _s0, _s1, _s2, _s3, _s4
+	d.nx = 0
+	d.tc = 0
+}
+
+// New returns a new hash.Hash computing the checksum.
+func New() hash.Hash {
+	result := new(digest)
+	result.Reset()
+	return result
+}
+
+func (d *digest) Size() int { return Size }
+
+func (d *digest) BlockSize() int { return BlockSize }
+
+func (d *digest) Write(p []byte) (nn int, err error) {
+	nn = len(p)
+	d.tc += uint64(nn)
+	if d.nx > 0 {
+		n := len(p)
+		if n > BlockSize-d.nx {
+			n = BlockSize - d.nx
+		}
+		for i := 0; i < n; i++ {
+			d.x[d.nx+i] = p[i]
+		}
+		d.nx += n
+		if d.nx == BlockSize {
+			_Block(d, d.x[0:])
+			d.nx = 0
+		}
+		p = p[n:]
+	}
+	n := _Block(d, p)
+	p = p[n:]
+	if len(p) > 0 {
+		d.nx = copy(d.x[:], p)
+	}
+	return
+}
+
+func (d0 *digest) Sum(in []byte) []byte {
+	// Make a copy of d0 so that caller can keep writing and summing.
+	d := *d0
+
+	// Padding.  Add a 1 bit and 0 bits until 56 bytes mod 64.
+	tc := d.tc
+	var tmp [64]byte
+	tmp[0] = 0x80
+	if tc%64 < 56 {
+		d.Write(tmp[0 : 56-tc%64])
+	} else {
+		d.Write(tmp[0 : 64+56-tc%64])
+	}
+
+	// Length in bits.
+	tc <<= 3
+	for i := uint(0); i < 8; i++ {
+		tmp[i] = byte(tc >> (8 * i))
+	}
+	d.Write(tmp[0:8])
+
+	if d.nx != 0 {
+		panic("d.nx != 0")
+	}
+
+	var digest [Size]byte
+	for i, s := range d.s {
+		digest[i*4] = byte(s)
+		digest[i*4+1] = byte(s >> 8)
+		digest[i*4+2] = byte(s >> 16)
+		digest[i*4+3] = byte(s >> 24)
+	}
+
+	return append(in, digest[:]...)
+}
diff --git a/vendor/golang.org/x/crypto/ripemd160/ripemd160block.go b/vendor/golang.org/x/crypto/ripemd160/ripemd160block.go
new file mode 100644
index 0000000000..e0edc02f0f
--- /dev/null
+++ b/vendor/golang.org/x/crypto/ripemd160/ripemd160block.go
@@ -0,0 +1,165 @@
+// Copyright 2010 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.
+
+// RIPEMD-160 block step.
+// In its own file so that a faster assembly or C version
+// can be substituted easily.
+
+package ripemd160
+
+import (
+	"math/bits"
+)
+
+// work buffer indices and roll amounts for one line
+var _n = [80]uint{
+	0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+	7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8,
+	3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12,
+	1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2,
+	4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13,
+}
+
+var _r = [80]uint{
+	11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8,
+	7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12,
+	11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5,
+	11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12,
+	9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6,
+}
+
+// same for the other parallel one
+var n_ = [80]uint{
+	5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12,
+	6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2,
+	15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13,
+	8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14,
+	12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11,
+}
+
+var r_ = [80]uint{
+	8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6,
+	9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11,
+	9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5,
+	15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8,
+	8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11,
+}
+
+func _Block(md *digest, p []byte) int {
+	n := 0
+	var x [16]uint32
+	var alpha, beta uint32
+	for len(p) >= BlockSize {
+		a, b, c, d, e := md.s[0], md.s[1], md.s[2], md.s[3], md.s[4]
+		aa, bb, cc, dd, ee := a, b, c, d, e
+		j := 0
+		for i := 0; i < 16; i++ {
+			x[i] = uint32(p[j]) | uint32(p[j+1])<<8 | uint32(p[j+2])<<16 | uint32(p[j+3])<<24
+			j += 4
+		}
+
+		// round 1
+		i := 0
+		for i < 16 {
+			alpha = a + (b ^ c ^ d) + x[_n[i]]
+			s := int(_r[i])
+			alpha = bits.RotateLeft32(alpha, s) + e
+			beta = bits.RotateLeft32(c, 10)
+			a, b, c, d, e = e, alpha, b, beta, d
+
+			// parallel line
+			alpha = aa + (bb ^ (cc | ^dd)) + x[n_[i]] + 0x50a28be6
+			s = int(r_[i])
+			alpha = bits.RotateLeft32(alpha, s) + ee
+			beta = bits.RotateLeft32(cc, 10)
+			aa, bb, cc, dd, ee = ee, alpha, bb, beta, dd
+
+			i++
+		}
+
+		// round 2
+		for i < 32 {
+			alpha = a + (b&c | ^b&d) + x[_n[i]] + 0x5a827999
+			s := int(_r[i])
+			alpha = bits.RotateLeft32(alpha, s) + e
+			beta = bits.RotateLeft32(c, 10)
+			a, b, c, d, e = e, alpha, b, beta, d
+
+			// parallel line
+			alpha = aa + (bb&dd | cc&^dd) + x[n_[i]] + 0x5c4dd124
+			s = int(r_[i])
+			alpha = bits.RotateLeft32(alpha, s) + ee
+			beta = bits.RotateLeft32(cc, 10)
+			aa, bb, cc, dd, ee = ee, alpha, bb, beta, dd
+
+			i++
+		}
+
+		// round 3
+		for i < 48 {
+			alpha = a + (b | ^c ^ d) + x[_n[i]] + 0x6ed9eba1
+			s := int(_r[i])
+			alpha = bits.RotateLeft32(alpha, s) + e
+			beta = bits.RotateLeft32(c, 10)
+			a, b, c, d, e = e, alpha, b, beta, d
+
+			// parallel line
+			alpha = aa + (bb | ^cc ^ dd) + x[n_[i]] + 0x6d703ef3
+			s = int(r_[i])
+			alpha = bits.RotateLeft32(alpha, s) + ee
+			beta = bits.RotateLeft32(cc, 10)
+			aa, bb, cc, dd, ee = ee, alpha, bb, beta, dd
+
+			i++
+		}
+
+		// round 4
+		for i < 64 {
+			alpha = a + (b&d | c&^d) + x[_n[i]] + 0x8f1bbcdc
+			s := int(_r[i])
+			alpha = bits.RotateLeft32(alpha, s) + e
+			beta = bits.RotateLeft32(c, 10)
+			a, b, c, d, e = e, alpha, b, beta, d
+
+			// parallel line
+			alpha = aa + (bb&cc | ^bb&dd) + x[n_[i]] + 0x7a6d76e9
+			s = int(r_[i])
+			alpha = bits.RotateLeft32(alpha, s) + ee
+			beta = bits.RotateLeft32(cc, 10)
+			aa, bb, cc, dd, ee = ee, alpha, bb, beta, dd
+
+			i++
+		}
+
+		// round 5
+		for i < 80 {
+			alpha = a + (b ^ (c | ^d)) + x[_n[i]] + 0xa953fd4e
+			s := int(_r[i])
+			alpha = bits.RotateLeft32(alpha, s) + e
+			beta = bits.RotateLeft32(c, 10)
+			a, b, c, d, e = e, alpha, b, beta, d
+
+			// parallel line
+			alpha = aa + (bb ^ cc ^ dd) + x[n_[i]]
+			s = int(r_[i])
+			alpha = bits.RotateLeft32(alpha, s) + ee
+			beta = bits.RotateLeft32(cc, 10)
+			aa, bb, cc, dd, ee = ee, alpha, bb, beta, dd
+
+			i++
+		}
+
+		// combine results
+		dd += c + md.s[1]
+		md.s[1] = md.s[2] + d + ee
+		md.s[2] = md.s[3] + e + aa
+		md.s[3] = md.s[4] + a + bb
+		md.s[4] = md.s[0] + b + cc
+		md.s[0] = dd
+
+		p = p[BlockSize:]
+		n += BlockSize
+	}
+	return n
+}
diff --git a/vendor/golang.org/x/crypto/salsa20/salsa/salsa20_amd64.go b/vendor/golang.org/x/crypto/salsa20/salsa/salsa20_amd64.go
index 656e8df942..c400dfcf7b 100644
--- a/vendor/golang.org/x/crypto/salsa20/salsa/salsa20_amd64.go
+++ b/vendor/golang.org/x/crypto/salsa20/salsa/salsa20_amd64.go
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build amd64,!appengine,!gccgo
+//go:build amd64 && !purego && gc
+// +build amd64,!purego,gc
 
 package salsa
 
diff --git a/vendor/golang.org/x/crypto/salsa20/salsa/salsa20_amd64.s b/vendor/golang.org/x/crypto/salsa20/salsa/salsa20_amd64.s
index 18085d2e8c..c089277204 100644
--- a/vendor/golang.org/x/crypto/salsa20/salsa/salsa20_amd64.s
+++ b/vendor/golang.org/x/crypto/salsa20/salsa/salsa20_amd64.s
@@ -2,13 +2,14 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build amd64,!appengine,!gccgo
+//go:build amd64 && !purego && gc
+// +build amd64,!purego,gc
 
 // This code was translated into a form compatible with 6a from the public
 // domain sources in SUPERCOP: https://bench.cr.yp.to/supercop.html
 
 // func salsa2020XORKeyStream(out, in *byte, n uint64, nonce, key *byte)
-// This needs up to 64 bytes at 360(SP); hence the non-obvious frame size.
+// This needs up to 64 bytes at 360(R12); hence the non-obvious frame size.
 TEXT ·salsa2020XORKeyStream(SB),0,$456-40 // frame = 424 + 32 byte alignment
 	MOVQ out+0(FP),DI
 	MOVQ in+8(FP),SI
@@ -17,10 +18,8 @@ TEXT ·salsa2020XORKeyStream(SB),0,$456-40 // frame = 424 + 32 byte alignment
 	MOVQ key+32(FP),R8
 
 	MOVQ SP,R12
-	MOVQ SP,R9
-	ADDQ $31, R9
-	ANDQ $~31, R9
-	MOVQ R9, SP
+	ADDQ $31, R12
+	ANDQ $~31, R12
 
 	MOVQ DX,R9
 	MOVQ CX,DX
@@ -32,116 +31,116 @@ TEXT ·salsa2020XORKeyStream(SB),0,$456-40 // frame = 424 + 32 byte alignment
 	MOVL 0(R10),R8
 	MOVL 0(DX),AX
 	MOVL 16(R10),R11
-	MOVL CX,0(SP)
-	MOVL R8, 4 (SP)
-	MOVL AX, 8 (SP)
-	MOVL R11, 12 (SP)
+	MOVL CX,0(R12)
+	MOVL R8, 4 (R12)
+	MOVL AX, 8 (R12)
+	MOVL R11, 12 (R12)
 	MOVL 8(DX),CX
 	MOVL 24(R10),R8
 	MOVL 4(R10),AX
 	MOVL 4(DX),R11
-	MOVL CX,16(SP)
-	MOVL R8, 20 (SP)
-	MOVL AX, 24 (SP)
-	MOVL R11, 28 (SP)
+	MOVL CX,16(R12)
+	MOVL R8, 20 (R12)
+	MOVL AX, 24 (R12)
+	MOVL R11, 28 (R12)
 	MOVL 12(DX),CX
 	MOVL 12(R10),DX
 	MOVL 28(R10),R8
 	MOVL 8(R10),AX
-	MOVL DX,32(SP)
-	MOVL CX, 36 (SP)
-	MOVL R8, 40 (SP)
-	MOVL AX, 44 (SP)
+	MOVL DX,32(R12)
+	MOVL CX, 36 (R12)
+	MOVL R8, 40 (R12)
+	MOVL AX, 44 (R12)
 	MOVQ $1634760805,DX
 	MOVQ $857760878,CX
 	MOVQ $2036477234,R8
 	MOVQ $1797285236,AX
-	MOVL DX,48(SP)
-	MOVL CX, 52 (SP)
-	MOVL R8, 56 (SP)
-	MOVL AX, 60 (SP)
+	MOVL DX,48(R12)
+	MOVL CX, 52 (R12)
+	MOVL R8, 56 (R12)
+	MOVL AX, 60 (R12)
 	CMPQ R9,$256
 	JB BYTESBETWEEN1AND255
-	MOVOA 48(SP),X0
+	MOVOA 48(R12),X0
 	PSHUFL $0X55,X0,X1
 	PSHUFL $0XAA,X0,X2
 	PSHUFL $0XFF,X0,X3
 	PSHUFL $0X00,X0,X0
-	MOVOA X1,64(SP)
-	MOVOA X2,80(SP)
-	MOVOA X3,96(SP)
-	MOVOA X0,112(SP)
-	MOVOA 0(SP),X0
+	MOVOA X1,64(R12)
+	MOVOA X2,80(R12)
+	MOVOA X3,96(R12)
+	MOVOA X0,112(R12)
+	MOVOA 0(R12),X0
 	PSHUFL $0XAA,X0,X1
 	PSHUFL $0XFF,X0,X2
 	PSHUFL $0X00,X0,X3
 	PSHUFL $0X55,X0,X0
-	MOVOA X1,128(SP)
-	MOVOA X2,144(SP)
-	MOVOA X3,160(SP)
-	MOVOA X0,176(SP)
-	MOVOA 16(SP),X0
+	MOVOA X1,128(R12)
+	MOVOA X2,144(R12)
+	MOVOA X3,160(R12)
+	MOVOA X0,176(R12)
+	MOVOA 16(R12),X0
 	PSHUFL $0XFF,X0,X1
 	PSHUFL $0X55,X0,X2
 	PSHUFL $0XAA,X0,X0
-	MOVOA X1,192(SP)
-	MOVOA X2,208(SP)
-	MOVOA X0,224(SP)
-	MOVOA 32(SP),X0
+	MOVOA X1,192(R12)
+	MOVOA X2,208(R12)
+	MOVOA X0,224(R12)
+	MOVOA 32(R12),X0
 	PSHUFL $0X00,X0,X1
 	PSHUFL $0XAA,X0,X2
 	PSHUFL $0XFF,X0,X0
-	MOVOA X1,240(SP)
-	MOVOA X2,256(SP)
-	MOVOA X0,272(SP)
+	MOVOA X1,240(R12)
+	MOVOA X2,256(R12)
+	MOVOA X0,272(R12)
 	BYTESATLEAST256:
-	MOVL 16(SP),DX
-	MOVL  36 (SP),CX
-	MOVL DX,288(SP)
-	MOVL CX,304(SP)
+	MOVL 16(R12),DX
+	MOVL  36 (R12),CX
+	MOVL DX,288(R12)
+	MOVL CX,304(R12)
 	SHLQ $32,CX
 	ADDQ CX,DX
 	ADDQ $1,DX
 	MOVQ DX,CX
 	SHRQ $32,CX
-	MOVL DX, 292 (SP)
-	MOVL CX, 308 (SP)
+	MOVL DX, 292 (R12)
+	MOVL CX, 308 (R12)
 	ADDQ $1,DX
 	MOVQ DX,CX
 	SHRQ $32,CX
-	MOVL DX, 296 (SP)
-	MOVL CX, 312 (SP)
+	MOVL DX, 296 (R12)
+	MOVL CX, 312 (R12)
 	ADDQ $1,DX
 	MOVQ DX,CX
 	SHRQ $32,CX
-	MOVL DX, 300 (SP)
-	MOVL CX, 316 (SP)
+	MOVL DX, 300 (R12)
+	MOVL CX, 316 (R12)
 	ADDQ $1,DX
 	MOVQ DX,CX
 	SHRQ $32,CX
-	MOVL DX,16(SP)
-	MOVL CX, 36 (SP)
-	MOVQ R9,352(SP)
+	MOVL DX,16(R12)
+	MOVL CX, 36 (R12)
+	MOVQ R9,352(R12)
 	MOVQ $20,DX
-	MOVOA 64(SP),X0
-	MOVOA 80(SP),X1
-	MOVOA 96(SP),X2
-	MOVOA 256(SP),X3
-	MOVOA 272(SP),X4
-	MOVOA 128(SP),X5
-	MOVOA 144(SP),X6
-	MOVOA 176(SP),X7
-	MOVOA 192(SP),X8
-	MOVOA 208(SP),X9
-	MOVOA 224(SP),X10
-	MOVOA 304(SP),X11
-	MOVOA 112(SP),X12
-	MOVOA 160(SP),X13
-	MOVOA 240(SP),X14
-	MOVOA 288(SP),X15
+	MOVOA 64(R12),X0
+	MOVOA 80(R12),X1
+	MOVOA 96(R12),X2
+	MOVOA 256(R12),X3
+	MOVOA 272(R12),X4
+	MOVOA 128(R12),X5
+	MOVOA 144(R12),X6
+	MOVOA 176(R12),X7
+	MOVOA 192(R12),X8
+	MOVOA 208(R12),X9
+	MOVOA 224(R12),X10
+	MOVOA 304(R12),X11
+	MOVOA 112(R12),X12
+	MOVOA 160(R12),X13
+	MOVOA 240(R12),X14
+	MOVOA 288(R12),X15
 	MAINLOOP1:
-	MOVOA X1,320(SP)
-	MOVOA X2,336(SP)
+	MOVOA X1,320(R12)
+	MOVOA X2,336(R12)
 	MOVOA X13,X1
 	PADDL X12,X1
 	MOVOA X1,X2
@@ -191,8 +190,8 @@ TEXT ·salsa2020XORKeyStream(SB),0,$456-40 // frame = 424 + 32 byte alignment
 	PXOR X1,X12
 	PSRLL $14,X2
 	PXOR X2,X12
-	MOVOA 320(SP),X1
-	MOVOA X12,320(SP)
+	MOVOA 320(R12),X1
+	MOVOA X12,320(R12)
 	MOVOA X9,X2
 	PADDL X7,X2
 	MOVOA X2,X12
@@ -207,8 +206,8 @@ TEXT ·salsa2020XORKeyStream(SB),0,$456-40 // frame = 424 + 32 byte alignment
 	PXOR X2,X3
 	PSRLL $25,X12
 	PXOR X12,X3
-	MOVOA 336(SP),X2
-	MOVOA X0,336(SP)
+	MOVOA 336(R12),X2
+	MOVOA X0,336(R12)
 	MOVOA X6,X0
 	PADDL X2,X0
 	MOVOA X0,X12
@@ -251,8 +250,8 @@ TEXT ·salsa2020XORKeyStream(SB),0,$456-40 // frame = 424 + 32 byte alignment
 	PXOR X0,X1
 	PSRLL $14,X12
 	PXOR X12,X1
-	MOVOA 320(SP),X0
-	MOVOA X1,320(SP)
+	MOVOA 320(R12),X0
+	MOVOA X1,320(R12)
 	MOVOA X4,X1
 	PADDL X0,X1
 	MOVOA X1,X12
@@ -267,8 +266,8 @@ TEXT ·salsa2020XORKeyStream(SB),0,$456-40 // frame = 424 + 32 byte alignment
 	PXOR X1,X2
 	PSRLL $14,X12
 	PXOR X12,X2
-	MOVOA 336(SP),X12
-	MOVOA X2,336(SP)
+	MOVOA 336(R12),X12
+	MOVOA X2,336(R12)
 	MOVOA X14,X1
 	PADDL X12,X1
 	MOVOA X1,X2
@@ -311,8 +310,8 @@ TEXT ·salsa2020XORKeyStream(SB),0,$456-40 // frame = 424 + 32 byte alignment
 	PXOR X1,X0
 	PSRLL $14,X2
 	PXOR X2,X0
-	MOVOA 320(SP),X1
-	MOVOA X0,320(SP)
+	MOVOA 320(R12),X1
+	MOVOA X0,320(R12)
 	MOVOA X8,X0
 	PADDL X14,X0
 	MOVOA X0,X2
@@ -327,8 +326,8 @@ TEXT ·salsa2020XORKeyStream(SB),0,$456-40 // frame = 424 + 32 byte alignment
 	PXOR X0,X6
 	PSRLL $25,X2
 	PXOR X2,X6
-	MOVOA 336(SP),X2
-	MOVOA X12,336(SP)
+	MOVOA 336(R12),X2
+	MOVOA X12,336(R12)
 	MOVOA X3,X0
 	PADDL X2,X0
 	MOVOA X0,X12
@@ -378,14 +377,14 @@ TEXT ·salsa2020XORKeyStream(SB),0,$456-40 // frame = 424 + 32 byte alignment
 	PXOR X0,X2
 	PSRLL $14,X12
 	PXOR X12,X2
-	MOVOA 320(SP),X12
-	MOVOA 336(SP),X0
+	MOVOA 320(R12),X12
+	MOVOA 336(R12),X0
 	SUBQ $2,DX
 	JA MAINLOOP1
-	PADDL 112(SP),X12
-	PADDL 176(SP),X7
-	PADDL 224(SP),X10
-	PADDL 272(SP),X4
+	PADDL 112(R12),X12
+	PADDL 176(R12),X7
+	PADDL 224(R12),X10
+	PADDL 272(R12),X4
 	MOVD X12,DX
 	MOVD X7,CX
 	MOVD X10,R8
@@ -446,10 +445,10 @@ TEXT ·salsa2020XORKeyStream(SB),0,$456-40 // frame = 424 + 32 byte alignment
 	MOVL CX,196(DI)
 	MOVL R8,200(DI)
 	MOVL R9,204(DI)
-	PADDL 240(SP),X14
-	PADDL 64(SP),X0
-	PADDL 128(SP),X5
-	PADDL 192(SP),X8
+	PADDL 240(R12),X14
+	PADDL 64(R12),X0
+	PADDL 128(R12),X5
+	PADDL 192(R12),X8
 	MOVD X14,DX
 	MOVD X0,CX
 	MOVD X5,R8
@@ -510,10 +509,10 @@ TEXT ·salsa2020XORKeyStream(SB),0,$456-40 // frame = 424 + 32 byte alignment
 	MOVL CX,212(DI)
 	MOVL R8,216(DI)
 	MOVL R9,220(DI)
-	PADDL 288(SP),X15
-	PADDL 304(SP),X11
-	PADDL 80(SP),X1
-	PADDL 144(SP),X6
+	PADDL 288(R12),X15
+	PADDL 304(R12),X11
+	PADDL 80(R12),X1
+	PADDL 144(R12),X6
 	MOVD X15,DX
 	MOVD X11,CX
 	MOVD X1,R8
@@ -574,10 +573,10 @@ TEXT ·salsa2020XORKeyStream(SB),0,$456-40 // frame = 424 + 32 byte alignment
 	MOVL CX,228(DI)
 	MOVL R8,232(DI)
 	MOVL R9,236(DI)
-	PADDL 160(SP),X13
-	PADDL 208(SP),X9
-	PADDL 256(SP),X3
-	PADDL 96(SP),X2
+	PADDL 160(R12),X13
+	PADDL 208(R12),X9
+	PADDL 256(R12),X3
+	PADDL 96(R12),X2
 	MOVD X13,DX
 	MOVD X9,CX
 	MOVD X3,R8
@@ -638,7 +637,7 @@ TEXT ·salsa2020XORKeyStream(SB),0,$456-40 // frame = 424 + 32 byte alignment
 	MOVL CX,244(DI)
 	MOVL R8,248(DI)
 	MOVL R9,252(DI)
-	MOVQ 352(SP),R9
+	MOVQ 352(R12),R9
 	SUBQ $256,R9
 	ADDQ $256,SI
 	ADDQ $256,DI
@@ -650,17 +649,17 @@ TEXT ·salsa2020XORKeyStream(SB),0,$456-40 // frame = 424 + 32 byte alignment
 	CMPQ R9,$64
 	JAE NOCOPY
 	MOVQ DI,DX
-	LEAQ 360(SP),DI
+	LEAQ 360(R12),DI
 	MOVQ R9,CX
 	REP; MOVSB
-	LEAQ 360(SP),DI
-	LEAQ 360(SP),SI
+	LEAQ 360(R12),DI
+	LEAQ 360(R12),SI
 	NOCOPY:
-	MOVQ R9,352(SP)
-	MOVOA 48(SP),X0
-	MOVOA 0(SP),X1
-	MOVOA 16(SP),X2
-	MOVOA 32(SP),X3
+	MOVQ R9,352(R12)
+	MOVOA 48(R12),X0
+	MOVOA 0(R12),X1
+	MOVOA 16(R12),X2
+	MOVOA 32(R12),X3
 	MOVOA X1,X4
 	MOVQ $20,CX
 	MAINLOOP2:
@@ -791,10 +790,10 @@ TEXT ·salsa2020XORKeyStream(SB),0,$456-40 // frame = 424 + 32 byte alignment
 	PSHUFL $0X39,X3,X3
 	PXOR X6,X0
 	JA MAINLOOP2
-	PADDL 48(SP),X0
-	PADDL 0(SP),X1
-	PADDL 16(SP),X2
-	PADDL 32(SP),X3
+	PADDL 48(R12),X0
+	PADDL 0(R12),X1
+	PADDL 16(R12),X2
+	PADDL 32(R12),X3
 	MOVD X0,CX
 	MOVD X1,R8
 	MOVD X2,R9
@@ -855,16 +854,16 @@ TEXT ·salsa2020XORKeyStream(SB),0,$456-40 // frame = 424 + 32 byte alignment
 	MOVL R8,44(DI)
 	MOVL R9,28(DI)
 	MOVL AX,12(DI)
-	MOVQ 352(SP),R9
-	MOVL 16(SP),CX
-	MOVL  36 (SP),R8
+	MOVQ 352(R12),R9
+	MOVL 16(R12),CX
+	MOVL  36 (R12),R8
 	ADDQ $1,CX
 	SHLQ $32,R8
 	ADDQ R8,CX
 	MOVQ CX,R8
 	SHRQ $32,R8
-	MOVL CX,16(SP)
-	MOVL R8, 36 (SP)
+	MOVL CX,16(R12)
+	MOVL R8, 36 (R12)
 	CMPQ R9,$64
 	JA BYTESATLEAST65
 	JAE BYTESATLEAST64
@@ -874,7 +873,6 @@ TEXT ·salsa2020XORKeyStream(SB),0,$456-40 // frame = 424 + 32 byte alignment
 	REP; MOVSB
 	BYTESATLEAST64:
 	DONE:
-	MOVQ R12,SP
 	RET
 	BYTESATLEAST65:
 	SUBQ $64,R9
diff --git a/vendor/golang.org/x/crypto/salsa20/salsa/salsa20_noasm.go b/vendor/golang.org/x/crypto/salsa20/salsa/salsa20_noasm.go
index 8a46bd2b3a..4392cc1ac7 100644
--- a/vendor/golang.org/x/crypto/salsa20/salsa/salsa20_noasm.go
+++ b/vendor/golang.org/x/crypto/salsa20/salsa/salsa20_noasm.go
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build !amd64 appengine gccgo
+//go:build !amd64 || purego || !gc
+// +build !amd64 purego !gc
 
 package salsa
 
diff --git a/vendor/golang.org/x/crypto/salsa20/salsa20.go b/vendor/golang.org/x/crypto/salsa20/salsa20.go
new file mode 100644
index 0000000000..6f9bb106ca
--- /dev/null
+++ b/vendor/golang.org/x/crypto/salsa20/salsa20.go
@@ -0,0 +1,58 @@
+// 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 salsa20 implements the Salsa20 stream cipher as specified in https://cr.yp.to/snuffle/spec.pdf.
+
+Salsa20 differs from many other stream ciphers in that it is message orientated
+rather than byte orientated. Keystream blocks are not preserved between calls,
+therefore each side must encrypt/decrypt data with the same segmentation.
+
+Another aspect of this difference is that part of the counter is exposed as
+a nonce in each call. Encrypting two different messages with the same (key,
+nonce) pair leads to trivial plaintext recovery. This is analogous to
+encrypting two different messages with the same key with a traditional stream
+cipher.
+
+This package also implements XSalsa20: a version of Salsa20 with a 24-byte
+nonce as specified in https://cr.yp.to/snuffle/xsalsa-20081128.pdf. Simply
+passing a 24-byte slice as the nonce triggers XSalsa20.
+*/
+package salsa20 // import "golang.org/x/crypto/salsa20"
+
+// TODO(agl): implement XORKeyStream12 and XORKeyStream8 - the reduced round variants of Salsa20.
+
+import (
+	"golang.org/x/crypto/internal/subtle"
+	"golang.org/x/crypto/salsa20/salsa"
+)
+
+// XORKeyStream crypts bytes from in to out using the given key and nonce.
+// In and out must overlap entirely or not at all. Nonce must
+// be either 8 or 24 bytes long.
+func XORKeyStream(out, in []byte, nonce []byte, key *[32]byte) {
+	if len(out) < len(in) {
+		panic("salsa20: output smaller than input")
+	}
+	if subtle.InexactOverlap(out[:len(in)], in) {
+		panic("salsa20: invalid buffer overlap")
+	}
+
+	var subNonce [16]byte
+
+	if len(nonce) == 24 {
+		var subKey [32]byte
+		var hNonce [16]byte
+		copy(hNonce[:], nonce[:16])
+		salsa.HSalsa20(&subKey, &hNonce, key, &salsa.Sigma)
+		copy(subNonce[:], nonce[16:])
+		key = &subKey
+	} else if len(nonce) == 8 {
+		copy(subNonce[:], nonce[:])
+	} else {
+		panic("salsa20: nonce must be 8 or 24 bytes")
+	}
+
+	salsa.XORKeyStream(out, in, &subNonce, key)
+}
diff --git a/vendor/golang.org/x/crypto/scrypt/scrypt.go b/vendor/golang.org/x/crypto/scrypt/scrypt.go
new file mode 100644
index 0000000000..bbe4494c6c
--- /dev/null
+++ b/vendor/golang.org/x/crypto/scrypt/scrypt.go
@@ -0,0 +1,212 @@
+// 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 scrypt implements the scrypt key derivation function as defined in
+// Colin Percival's paper "Stronger Key Derivation via Sequential Memory-Hard
+// Functions" (https://www.tarsnap.com/scrypt/scrypt.pdf).
+package scrypt // import "golang.org/x/crypto/scrypt"
+
+import (
+	"crypto/sha256"
+	"encoding/binary"
+	"errors"
+	"math/bits"
+
+	"golang.org/x/crypto/pbkdf2"
+)
+
+const maxInt = int(^uint(0) >> 1)
+
+// blockCopy copies n numbers from src into dst.
+func blockCopy(dst, src []uint32, n int) {
+	copy(dst, src[:n])
+}
+
+// blockXOR XORs numbers from dst with n numbers from src.
+func blockXOR(dst, src []uint32, n int) {
+	for i, v := range src[:n] {
+		dst[i] ^= v
+	}
+}
+
+// salsaXOR applies Salsa20/8 to the XOR of 16 numbers from tmp and in,
+// and puts the result into both tmp and out.
+func salsaXOR(tmp *[16]uint32, in, out []uint32) {
+	w0 := tmp[0] ^ in[0]
+	w1 := tmp[1] ^ in[1]
+	w2 := tmp[2] ^ in[2]
+	w3 := tmp[3] ^ in[3]
+	w4 := tmp[4] ^ in[4]
+	w5 := tmp[5] ^ in[5]
+	w6 := tmp[6] ^ in[6]
+	w7 := tmp[7] ^ in[7]
+	w8 := tmp[8] ^ in[8]
+	w9 := tmp[9] ^ in[9]
+	w10 := tmp[10] ^ in[10]
+	w11 := tmp[11] ^ in[11]
+	w12 := tmp[12] ^ in[12]
+	w13 := tmp[13] ^ in[13]
+	w14 := tmp[14] ^ in[14]
+	w15 := tmp[15] ^ in[15]
+
+	x0, x1, x2, x3, x4, x5, x6, x7, x8 := w0, w1, w2, w3, w4, w5, w6, w7, w8
+	x9, x10, x11, x12, x13, x14, x15 := w9, w10, w11, w12, w13, w14, w15
+
+	for i := 0; i < 8; i += 2 {
+		x4 ^= bits.RotateLeft32(x0+x12, 7)
+		x8 ^= bits.RotateLeft32(x4+x0, 9)
+		x12 ^= bits.RotateLeft32(x8+x4, 13)
+		x0 ^= bits.RotateLeft32(x12+x8, 18)
+
+		x9 ^= bits.RotateLeft32(x5+x1, 7)
+		x13 ^= bits.RotateLeft32(x9+x5, 9)
+		x1 ^= bits.RotateLeft32(x13+x9, 13)
+		x5 ^= bits.RotateLeft32(x1+x13, 18)
+
+		x14 ^= bits.RotateLeft32(x10+x6, 7)
+		x2 ^= bits.RotateLeft32(x14+x10, 9)
+		x6 ^= bits.RotateLeft32(x2+x14, 13)
+		x10 ^= bits.RotateLeft32(x6+x2, 18)
+
+		x3 ^= bits.RotateLeft32(x15+x11, 7)
+		x7 ^= bits.RotateLeft32(x3+x15, 9)
+		x11 ^= bits.RotateLeft32(x7+x3, 13)
+		x15 ^= bits.RotateLeft32(x11+x7, 18)
+
+		x1 ^= bits.RotateLeft32(x0+x3, 7)
+		x2 ^= bits.RotateLeft32(x1+x0, 9)
+		x3 ^= bits.RotateLeft32(x2+x1, 13)
+		x0 ^= bits.RotateLeft32(x3+x2, 18)
+
+		x6 ^= bits.RotateLeft32(x5+x4, 7)
+		x7 ^= bits.RotateLeft32(x6+x5, 9)
+		x4 ^= bits.RotateLeft32(x7+x6, 13)
+		x5 ^= bits.RotateLeft32(x4+x7, 18)
+
+		x11 ^= bits.RotateLeft32(x10+x9, 7)
+		x8 ^= bits.RotateLeft32(x11+x10, 9)
+		x9 ^= bits.RotateLeft32(x8+x11, 13)
+		x10 ^= bits.RotateLeft32(x9+x8, 18)
+
+		x12 ^= bits.RotateLeft32(x15+x14, 7)
+		x13 ^= bits.RotateLeft32(x12+x15, 9)
+		x14 ^= bits.RotateLeft32(x13+x12, 13)
+		x15 ^= bits.RotateLeft32(x14+x13, 18)
+	}
+	x0 += w0
+	x1 += w1
+	x2 += w2
+	x3 += w3
+	x4 += w4
+	x5 += w5
+	x6 += w6
+	x7 += w7
+	x8 += w8
+	x9 += w9
+	x10 += w10
+	x11 += w11
+	x12 += w12
+	x13 += w13
+	x14 += w14
+	x15 += w15
+
+	out[0], tmp[0] = x0, x0
+	out[1], tmp[1] = x1, x1
+	out[2], tmp[2] = x2, x2
+	out[3], tmp[3] = x3, x3
+	out[4], tmp[4] = x4, x4
+	out[5], tmp[5] = x5, x5
+	out[6], tmp[6] = x6, x6
+	out[7], tmp[7] = x7, x7
+	out[8], tmp[8] = x8, x8
+	out[9], tmp[9] = x9, x9
+	out[10], tmp[10] = x10, x10
+	out[11], tmp[11] = x11, x11
+	out[12], tmp[12] = x12, x12
+	out[13], tmp[13] = x13, x13
+	out[14], tmp[14] = x14, x14
+	out[15], tmp[15] = x15, x15
+}
+
+func blockMix(tmp *[16]uint32, in, out []uint32, r int) {
+	blockCopy(tmp[:], in[(2*r-1)*16:], 16)
+	for i := 0; i < 2*r; i += 2 {
+		salsaXOR(tmp, in[i*16:], out[i*8:])
+		salsaXOR(tmp, in[i*16+16:], out[i*8+r*16:])
+	}
+}
+
+func integer(b []uint32, r int) uint64 {
+	j := (2*r - 1) * 16
+	return uint64(b[j]) | uint64(b[j+1])<<32
+}
+
+func smix(b []byte, r, N int, v, xy []uint32) {
+	var tmp [16]uint32
+	R := 32 * r
+	x := xy
+	y := xy[R:]
+
+	j := 0
+	for i := 0; i < R; i++ {
+		x[i] = binary.LittleEndian.Uint32(b[j:])
+		j += 4
+	}
+	for i := 0; i < N; i += 2 {
+		blockCopy(v[i*R:], x, R)
+		blockMix(&tmp, x, y, r)
+
+		blockCopy(v[(i+1)*R:], y, R)
+		blockMix(&tmp, y, x, r)
+	}
+	for i := 0; i < N; i += 2 {
+		j := int(integer(x, r) & uint64(N-1))
+		blockXOR(x, v[j*R:], R)
+		blockMix(&tmp, x, y, r)
+
+		j = int(integer(y, r) & uint64(N-1))
+		blockXOR(y, v[j*R:], R)
+		blockMix(&tmp, y, x, r)
+	}
+	j = 0
+	for _, v := range x[:R] {
+		binary.LittleEndian.PutUint32(b[j:], v)
+		j += 4
+	}
+}
+
+// Key derives a key from the password, salt, and cost parameters, returning
+// a byte slice of length keyLen that can be used as cryptographic key.
+//
+// N is a CPU/memory cost parameter, which must be a power of two greater than 1.
+// r and p must satisfy r * p < 2³⁰. If the parameters do not satisfy the
+// limits, the function returns a nil byte slice and an error.
+//
+// For example, you can get a derived key for e.g. AES-256 (which needs a
+// 32-byte key) by doing:
+//
+//      dk, err := scrypt.Key([]byte("some password"), salt, 32768, 8, 1, 32)
+//
+// The recommended parameters for interactive logins as of 2017 are N=32768, r=8
+// and p=1. The parameters N, r, and p should be increased as memory latency and
+// CPU parallelism increases; consider setting N to the highest power of 2 you
+// can derive within 100 milliseconds. Remember to get a good random salt.
+func Key(password, salt []byte, N, r, p, keyLen int) ([]byte, error) {
+	if N <= 1 || N&(N-1) != 0 {
+		return nil, errors.New("scrypt: N must be > 1 and a power of 2")
+	}
+	if uint64(r)*uint64(p) >= 1<<30 || r > maxInt/128/p || r > maxInt/256 || N > maxInt/128/r {
+		return nil, errors.New("scrypt: parameters are too large")
+	}
+
+	xy := make([]uint32, 64*r)
+	v := make([]uint32, 32*N*r)
+	b := pbkdf2.Key(password, salt, 1, p*128*r, sha256.New)
+
+	for i := 0; i < p; i++ {
+		smix(b[i*128*r:], r, N, v, xy)
+	}
+
+	return pbkdf2.Key(password, b, 1, keyLen, sha256.New), nil
+}
diff --git a/vendor/golang.org/x/crypto/sha3/doc.go b/vendor/golang.org/x/crypto/sha3/doc.go
new file mode 100644
index 0000000000..c2fef30aff
--- /dev/null
+++ b/vendor/golang.org/x/crypto/sha3/doc.go
@@ -0,0 +1,66 @@
+// Copyright 2014 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 sha3 implements the SHA-3 fixed-output-length hash functions and
+// the SHAKE variable-output-length hash functions defined by FIPS-202.
+//
+// Both types of hash function use the "sponge" construction and the Keccak
+// permutation. For a detailed specification see http://keccak.noekeon.org/
+//
+//
+// Guidance
+//
+// If you aren't sure what function you need, use SHAKE256 with at least 64
+// bytes of output. The SHAKE instances are faster than the SHA3 instances;
+// the latter have to allocate memory to conform to the hash.Hash interface.
+//
+// If you need a secret-key MAC (message authentication code), prepend the
+// secret key to the input, hash with SHAKE256 and read at least 32 bytes of
+// output.
+//
+//
+// Security strengths
+//
+// The SHA3-x (x equals 224, 256, 384, or 512) functions have a security
+// strength against preimage attacks of x bits. Since they only produce "x"
+// bits of output, their collision-resistance is only "x/2" bits.
+//
+// The SHAKE-256 and -128 functions have a generic security strength of 256 and
+// 128 bits against all attacks, provided that at least 2x bits of their output
+// is used.  Requesting more than 64 or 32 bytes of output, respectively, does
+// not increase the collision-resistance of the SHAKE functions.
+//
+//
+// The sponge construction
+//
+// A sponge builds a pseudo-random function from a public pseudo-random
+// permutation, by applying the permutation to a state of "rate + capacity"
+// bytes, but hiding "capacity" of the bytes.
+//
+// A sponge starts out with a zero state. To hash an input using a sponge, up
+// to "rate" bytes of the input are XORed into the sponge's state. The sponge
+// is then "full" and the permutation is applied to "empty" it. This process is
+// repeated until all the input has been "absorbed". The input is then padded.
+// The digest is "squeezed" from the sponge in the same way, except that output
+// is copied out instead of input being XORed in.
+//
+// A sponge is parameterized by its generic security strength, which is equal
+// to half its capacity; capacity + rate is equal to the permutation's width.
+// Since the KeccakF-1600 permutation is 1600 bits (200 bytes) wide, this means
+// that the security strength of a sponge instance is equal to (1600 - bitrate) / 2.
+//
+//
+// Recommendations
+//
+// The SHAKE functions are recommended for most new uses. They can produce
+// output of arbitrary length. SHAKE256, with an output length of at least
+// 64 bytes, provides 256-bit security against all attacks.  The Keccak team
+// recommends it for most applications upgrading from SHA2-512. (NIST chose a
+// much stronger, but much slower, sponge instance for SHA3-512.)
+//
+// The SHA-3 functions are "drop-in" replacements for the SHA-2 functions.
+// They produce output of the same length, with the same security strengths
+// against all attacks. This means, in particular, that SHA3-256 only has
+// 128-bit collision resistance, because its output length is 32 bytes.
+package sha3 // import "golang.org/x/crypto/sha3"
diff --git a/vendor/golang.org/x/crypto/sha3/hashes.go b/vendor/golang.org/x/crypto/sha3/hashes.go
new file mode 100644
index 0000000000..0d8043fd2a
--- /dev/null
+++ b/vendor/golang.org/x/crypto/sha3/hashes.go
@@ -0,0 +1,97 @@
+// Copyright 2014 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 sha3
+
+// This file provides functions for creating instances of the SHA-3
+// and SHAKE hash functions, as well as utility functions for hashing
+// bytes.
+
+import (
+	"hash"
+)
+
+// New224 creates a new SHA3-224 hash.
+// Its generic security strength is 224 bits against preimage attacks,
+// and 112 bits against collision attacks.
+func New224() hash.Hash {
+	if h := new224Asm(); h != nil {
+		return h
+	}
+	return &state{rate: 144, outputLen: 28, dsbyte: 0x06}
+}
+
+// New256 creates a new SHA3-256 hash.
+// Its generic security strength is 256 bits against preimage attacks,
+// and 128 bits against collision attacks.
+func New256() hash.Hash {
+	if h := new256Asm(); h != nil {
+		return h
+	}
+	return &state{rate: 136, outputLen: 32, dsbyte: 0x06}
+}
+
+// New384 creates a new SHA3-384 hash.
+// Its generic security strength is 384 bits against preimage attacks,
+// and 192 bits against collision attacks.
+func New384() hash.Hash {
+	if h := new384Asm(); h != nil {
+		return h
+	}
+	return &state{rate: 104, outputLen: 48, dsbyte: 0x06}
+}
+
+// New512 creates a new SHA3-512 hash.
+// Its generic security strength is 512 bits against preimage attacks,
+// and 256 bits against collision attacks.
+func New512() hash.Hash {
+	if h := new512Asm(); h != nil {
+		return h
+	}
+	return &state{rate: 72, outputLen: 64, dsbyte: 0x06}
+}
+
+// NewLegacyKeccak256 creates a new Keccak-256 hash.
+//
+// Only use this function if you require compatibility with an existing cryptosystem
+// that uses non-standard padding. All other users should use New256 instead.
+func NewLegacyKeccak256() hash.Hash { return &state{rate: 136, outputLen: 32, dsbyte: 0x01} }
+
+// NewLegacyKeccak512 creates a new Keccak-512 hash.
+//
+// Only use this function if you require compatibility with an existing cryptosystem
+// that uses non-standard padding. All other users should use New512 instead.
+func NewLegacyKeccak512() hash.Hash { return &state{rate: 72, outputLen: 64, dsbyte: 0x01} }
+
+// Sum224 returns the SHA3-224 digest of the data.
+func Sum224(data []byte) (digest [28]byte) {
+	h := New224()
+	h.Write(data)
+	h.Sum(digest[:0])
+	return
+}
+
+// Sum256 returns the SHA3-256 digest of the data.
+func Sum256(data []byte) (digest [32]byte) {
+	h := New256()
+	h.Write(data)
+	h.Sum(digest[:0])
+	return
+}
+
+// Sum384 returns the SHA3-384 digest of the data.
+func Sum384(data []byte) (digest [48]byte) {
+	h := New384()
+	h.Write(data)
+	h.Sum(digest[:0])
+	return
+}
+
+// Sum512 returns the SHA3-512 digest of the data.
+func Sum512(data []byte) (digest [64]byte) {
+	h := New512()
+	h.Write(data)
+	h.Sum(digest[:0])
+	return
+}
diff --git a/vendor/golang.org/x/crypto/sha3/hashes_generic.go b/vendor/golang.org/x/crypto/sha3/hashes_generic.go
new file mode 100644
index 0000000000..c74fc20fcb
--- /dev/null
+++ b/vendor/golang.org/x/crypto/sha3/hashes_generic.go
@@ -0,0 +1,28 @@
+// Copyright 2017 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.
+
+//go:build !gc || purego || !s390x
+// +build !gc purego !s390x
+
+package sha3
+
+import (
+	"hash"
+)
+
+// new224Asm returns an assembly implementation of SHA3-224 if available,
+// otherwise it returns nil.
+func new224Asm() hash.Hash { return nil }
+
+// new256Asm returns an assembly implementation of SHA3-256 if available,
+// otherwise it returns nil.
+func new256Asm() hash.Hash { return nil }
+
+// new384Asm returns an assembly implementation of SHA3-384 if available,
+// otherwise it returns nil.
+func new384Asm() hash.Hash { return nil }
+
+// new512Asm returns an assembly implementation of SHA3-512 if available,
+// otherwise it returns nil.
+func new512Asm() hash.Hash { return nil }
diff --git a/vendor/golang.org/x/crypto/sha3/keccakf.go b/vendor/golang.org/x/crypto/sha3/keccakf.go
new file mode 100644
index 0000000000..0f4ae8bacf
--- /dev/null
+++ b/vendor/golang.org/x/crypto/sha3/keccakf.go
@@ -0,0 +1,413 @@
+// Copyright 2014 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.
+
+//go:build !amd64 || purego || !gc
+// +build !amd64 purego !gc
+
+package sha3
+
+// rc stores the round constants for use in the ι step.
+var rc = [24]uint64{
+	0x0000000000000001,
+	0x0000000000008082,
+	0x800000000000808A,
+	0x8000000080008000,
+	0x000000000000808B,
+	0x0000000080000001,
+	0x8000000080008081,
+	0x8000000000008009,
+	0x000000000000008A,
+	0x0000000000000088,
+	0x0000000080008009,
+	0x000000008000000A,
+	0x000000008000808B,
+	0x800000000000008B,
+	0x8000000000008089,
+	0x8000000000008003,
+	0x8000000000008002,
+	0x8000000000000080,
+	0x000000000000800A,
+	0x800000008000000A,
+	0x8000000080008081,
+	0x8000000000008080,
+	0x0000000080000001,
+	0x8000000080008008,
+}
+
+// keccakF1600 applies the Keccak permutation to a 1600b-wide
+// state represented as a slice of 25 uint64s.
+func keccakF1600(a *[25]uint64) {
+	// Implementation translated from Keccak-inplace.c
+	// in the keccak reference code.
+	var t, bc0, bc1, bc2, bc3, bc4, d0, d1, d2, d3, d4 uint64
+
+	for i := 0; i < 24; i += 4 {
+		// Combines the 5 steps in each round into 2 steps.
+		// Unrolls 4 rounds per loop and spreads some steps across rounds.
+
+		// Round 1
+		bc0 = a[0] ^ a[5] ^ a[10] ^ a[15] ^ a[20]
+		bc1 = a[1] ^ a[6] ^ a[11] ^ a[16] ^ a[21]
+		bc2 = a[2] ^ a[7] ^ a[12] ^ a[17] ^ a[22]
+		bc3 = a[3] ^ a[8] ^ a[13] ^ a[18] ^ a[23]
+		bc4 = a[4] ^ a[9] ^ a[14] ^ a[19] ^ a[24]
+		d0 = bc4 ^ (bc1<<1 | bc1>>63)
+		d1 = bc0 ^ (bc2<<1 | bc2>>63)
+		d2 = bc1 ^ (bc3<<1 | bc3>>63)
+		d3 = bc2 ^ (bc4<<1 | bc4>>63)
+		d4 = bc3 ^ (bc0<<1 | bc0>>63)
+
+		bc0 = a[0] ^ d0
+		t = a[6] ^ d1
+		bc1 = t<<44 | t>>(64-44)
+		t = a[12] ^ d2
+		bc2 = t<<43 | t>>(64-43)
+		t = a[18] ^ d3
+		bc3 = t<<21 | t>>(64-21)
+		t = a[24] ^ d4
+		bc4 = t<<14 | t>>(64-14)
+		a[0] = bc0 ^ (bc2 &^ bc1) ^ rc[i]
+		a[6] = bc1 ^ (bc3 &^ bc2)
+		a[12] = bc2 ^ (bc4 &^ bc3)
+		a[18] = bc3 ^ (bc0 &^ bc4)
+		a[24] = bc4 ^ (bc1 &^ bc0)
+
+		t = a[10] ^ d0
+		bc2 = t<<3 | t>>(64-3)
+		t = a[16] ^ d1
+		bc3 = t<<45 | t>>(64-45)
+		t = a[22] ^ d2
+		bc4 = t<<61 | t>>(64-61)
+		t = a[3] ^ d3
+		bc0 = t<<28 | t>>(64-28)
+		t = a[9] ^ d4
+		bc1 = t<<20 | t>>(64-20)
+		a[10] = bc0 ^ (bc2 &^ bc1)
+		a[16] = bc1 ^ (bc3 &^ bc2)
+		a[22] = bc2 ^ (bc4 &^ bc3)
+		a[3] = bc3 ^ (bc0 &^ bc4)
+		a[9] = bc4 ^ (bc1 &^ bc0)
+
+		t = a[20] ^ d0
+		bc4 = t<<18 | t>>(64-18)
+		t = a[1] ^ d1
+		bc0 = t<<1 | t>>(64-1)
+		t = a[7] ^ d2
+		bc1 = t<<6 | t>>(64-6)
+		t = a[13] ^ d3
+		bc2 = t<<25 | t>>(64-25)
+		t = a[19] ^ d4
+		bc3 = t<<8 | t>>(64-8)
+		a[20] = bc0 ^ (bc2 &^ bc1)
+		a[1] = bc1 ^ (bc3 &^ bc2)
+		a[7] = bc2 ^ (bc4 &^ bc3)
+		a[13] = bc3 ^ (bc0 &^ bc4)
+		a[19] = bc4 ^ (bc1 &^ bc0)
+
+		t = a[5] ^ d0
+		bc1 = t<<36 | t>>(64-36)
+		t = a[11] ^ d1
+		bc2 = t<<10 | t>>(64-10)
+		t = a[17] ^ d2
+		bc3 = t<<15 | t>>(64-15)
+		t = a[23] ^ d3
+		bc4 = t<<56 | t>>(64-56)
+		t = a[4] ^ d4
+		bc0 = t<<27 | t>>(64-27)
+		a[5] = bc0 ^ (bc2 &^ bc1)
+		a[11] = bc1 ^ (bc3 &^ bc2)
+		a[17] = bc2 ^ (bc4 &^ bc3)
+		a[23] = bc3 ^ (bc0 &^ bc4)
+		a[4] = bc4 ^ (bc1 &^ bc0)
+
+		t = a[15] ^ d0
+		bc3 = t<<41 | t>>(64-41)
+		t = a[21] ^ d1
+		bc4 = t<<2 | t>>(64-2)
+		t = a[2] ^ d2
+		bc0 = t<<62 | t>>(64-62)
+		t = a[8] ^ d3
+		bc1 = t<<55 | t>>(64-55)
+		t = a[14] ^ d4
+		bc2 = t<<39 | t>>(64-39)
+		a[15] = bc0 ^ (bc2 &^ bc1)
+		a[21] = bc1 ^ (bc3 &^ bc2)
+		a[2] = bc2 ^ (bc4 &^ bc3)
+		a[8] = bc3 ^ (bc0 &^ bc4)
+		a[14] = bc4 ^ (bc1 &^ bc0)
+
+		// Round 2
+		bc0 = a[0] ^ a[5] ^ a[10] ^ a[15] ^ a[20]
+		bc1 = a[1] ^ a[6] ^ a[11] ^ a[16] ^ a[21]
+		bc2 = a[2] ^ a[7] ^ a[12] ^ a[17] ^ a[22]
+		bc3 = a[3] ^ a[8] ^ a[13] ^ a[18] ^ a[23]
+		bc4 = a[4] ^ a[9] ^ a[14] ^ a[19] ^ a[24]
+		d0 = bc4 ^ (bc1<<1 | bc1>>63)
+		d1 = bc0 ^ (bc2<<1 | bc2>>63)
+		d2 = bc1 ^ (bc3<<1 | bc3>>63)
+		d3 = bc2 ^ (bc4<<1 | bc4>>63)
+		d4 = bc3 ^ (bc0<<1 | bc0>>63)
+
+		bc0 = a[0] ^ d0
+		t = a[16] ^ d1
+		bc1 = t<<44 | t>>(64-44)
+		t = a[7] ^ d2
+		bc2 = t<<43 | t>>(64-43)
+		t = a[23] ^ d3
+		bc3 = t<<21 | t>>(64-21)
+		t = a[14] ^ d4
+		bc4 = t<<14 | t>>(64-14)
+		a[0] = bc0 ^ (bc2 &^ bc1) ^ rc[i+1]
+		a[16] = bc1 ^ (bc3 &^ bc2)
+		a[7] = bc2 ^ (bc4 &^ bc3)
+		a[23] = bc3 ^ (bc0 &^ bc4)
+		a[14] = bc4 ^ (bc1 &^ bc0)
+
+		t = a[20] ^ d0
+		bc2 = t<<3 | t>>(64-3)
+		t = a[11] ^ d1
+		bc3 = t<<45 | t>>(64-45)
+		t = a[2] ^ d2
+		bc4 = t<<61 | t>>(64-61)
+		t = a[18] ^ d3
+		bc0 = t<<28 | t>>(64-28)
+		t = a[9] ^ d4
+		bc1 = t<<20 | t>>(64-20)
+		a[20] = bc0 ^ (bc2 &^ bc1)
+		a[11] = bc1 ^ (bc3 &^ bc2)
+		a[2] = bc2 ^ (bc4 &^ bc3)
+		a[18] = bc3 ^ (bc0 &^ bc4)
+		a[9] = bc4 ^ (bc1 &^ bc0)
+
+		t = a[15] ^ d0
+		bc4 = t<<18 | t>>(64-18)
+		t = a[6] ^ d1
+		bc0 = t<<1 | t>>(64-1)
+		t = a[22] ^ d2
+		bc1 = t<<6 | t>>(64-6)
+		t = a[13] ^ d3
+		bc2 = t<<25 | t>>(64-25)
+		t = a[4] ^ d4
+		bc3 = t<<8 | t>>(64-8)
+		a[15] = bc0 ^ (bc2 &^ bc1)
+		a[6] = bc1 ^ (bc3 &^ bc2)
+		a[22] = bc2 ^ (bc4 &^ bc3)
+		a[13] = bc3 ^ (bc0 &^ bc4)
+		a[4] = bc4 ^ (bc1 &^ bc0)
+
+		t = a[10] ^ d0
+		bc1 = t<<36 | t>>(64-36)
+		t = a[1] ^ d1
+		bc2 = t<<10 | t>>(64-10)
+		t = a[17] ^ d2
+		bc3 = t<<15 | t>>(64-15)
+		t = a[8] ^ d3
+		bc4 = t<<56 | t>>(64-56)
+		t = a[24] ^ d4
+		bc0 = t<<27 | t>>(64-27)
+		a[10] = bc0 ^ (bc2 &^ bc1)
+		a[1] = bc1 ^ (bc3 &^ bc2)
+		a[17] = bc2 ^ (bc4 &^ bc3)
+		a[8] = bc3 ^ (bc0 &^ bc4)
+		a[24] = bc4 ^ (bc1 &^ bc0)
+
+		t = a[5] ^ d0
+		bc3 = t<<41 | t>>(64-41)
+		t = a[21] ^ d1
+		bc4 = t<<2 | t>>(64-2)
+		t = a[12] ^ d2
+		bc0 = t<<62 | t>>(64-62)
+		t = a[3] ^ d3
+		bc1 = t<<55 | t>>(64-55)
+		t = a[19] ^ d4
+		bc2 = t<<39 | t>>(64-39)
+		a[5] = bc0 ^ (bc2 &^ bc1)
+		a[21] = bc1 ^ (bc3 &^ bc2)
+		a[12] = bc2 ^ (bc4 &^ bc3)
+		a[3] = bc3 ^ (bc0 &^ bc4)
+		a[19] = bc4 ^ (bc1 &^ bc0)
+
+		// Round 3
+		bc0 = a[0] ^ a[5] ^ a[10] ^ a[15] ^ a[20]
+		bc1 = a[1] ^ a[6] ^ a[11] ^ a[16] ^ a[21]
+		bc2 = a[2] ^ a[7] ^ a[12] ^ a[17] ^ a[22]
+		bc3 = a[3] ^ a[8] ^ a[13] ^ a[18] ^ a[23]
+		bc4 = a[4] ^ a[9] ^ a[14] ^ a[19] ^ a[24]
+		d0 = bc4 ^ (bc1<<1 | bc1>>63)
+		d1 = bc0 ^ (bc2<<1 | bc2>>63)
+		d2 = bc1 ^ (bc3<<1 | bc3>>63)
+		d3 = bc2 ^ (bc4<<1 | bc4>>63)
+		d4 = bc3 ^ (bc0<<1 | bc0>>63)
+
+		bc0 = a[0] ^ d0
+		t = a[11] ^ d1
+		bc1 = t<<44 | t>>(64-44)
+		t = a[22] ^ d2
+		bc2 = t<<43 | t>>(64-43)
+		t = a[8] ^ d3
+		bc3 = t<<21 | t>>(64-21)
+		t = a[19] ^ d4
+		bc4 = t<<14 | t>>(64-14)
+		a[0] = bc0 ^ (bc2 &^ bc1) ^ rc[i+2]
+		a[11] = bc1 ^ (bc3 &^ bc2)
+		a[22] = bc2 ^ (bc4 &^ bc3)
+		a[8] = bc3 ^ (bc0 &^ bc4)
+		a[19] = bc4 ^ (bc1 &^ bc0)
+
+		t = a[15] ^ d0
+		bc2 = t<<3 | t>>(64-3)
+		t = a[1] ^ d1
+		bc3 = t<<45 | t>>(64-45)
+		t = a[12] ^ d2
+		bc4 = t<<61 | t>>(64-61)
+		t = a[23] ^ d3
+		bc0 = t<<28 | t>>(64-28)
+		t = a[9] ^ d4
+		bc1 = t<<20 | t>>(64-20)
+		a[15] = bc0 ^ (bc2 &^ bc1)
+		a[1] = bc1 ^ (bc3 &^ bc2)
+		a[12] = bc2 ^ (bc4 &^ bc3)
+		a[23] = bc3 ^ (bc0 &^ bc4)
+		a[9] = bc4 ^ (bc1 &^ bc0)
+
+		t = a[5] ^ d0
+		bc4 = t<<18 | t>>(64-18)
+		t = a[16] ^ d1
+		bc0 = t<<1 | t>>(64-1)
+		t = a[2] ^ d2
+		bc1 = t<<6 | t>>(64-6)
+		t = a[13] ^ d3
+		bc2 = t<<25 | t>>(64-25)
+		t = a[24] ^ d4
+		bc3 = t<<8 | t>>(64-8)
+		a[5] = bc0 ^ (bc2 &^ bc1)
+		a[16] = bc1 ^ (bc3 &^ bc2)
+		a[2] = bc2 ^ (bc4 &^ bc3)
+		a[13] = bc3 ^ (bc0 &^ bc4)
+		a[24] = bc4 ^ (bc1 &^ bc0)
+
+		t = a[20] ^ d0
+		bc1 = t<<36 | t>>(64-36)
+		t = a[6] ^ d1
+		bc2 = t<<10 | t>>(64-10)
+		t = a[17] ^ d2
+		bc3 = t<<15 | t>>(64-15)
+		t = a[3] ^ d3
+		bc4 = t<<56 | t>>(64-56)
+		t = a[14] ^ d4
+		bc0 = t<<27 | t>>(64-27)
+		a[20] = bc0 ^ (bc2 &^ bc1)
+		a[6] = bc1 ^ (bc3 &^ bc2)
+		a[17] = bc2 ^ (bc4 &^ bc3)
+		a[3] = bc3 ^ (bc0 &^ bc4)
+		a[14] = bc4 ^ (bc1 &^ bc0)
+
+		t = a[10] ^ d0
+		bc3 = t<<41 | t>>(64-41)
+		t = a[21] ^ d1
+		bc4 = t<<2 | t>>(64-2)
+		t = a[7] ^ d2
+		bc0 = t<<62 | t>>(64-62)
+		t = a[18] ^ d3
+		bc1 = t<<55 | t>>(64-55)
+		t = a[4] ^ d4
+		bc2 = t<<39 | t>>(64-39)
+		a[10] = bc0 ^ (bc2 &^ bc1)
+		a[21] = bc1 ^ (bc3 &^ bc2)
+		a[7] = bc2 ^ (bc4 &^ bc3)
+		a[18] = bc3 ^ (bc0 &^ bc4)
+		a[4] = bc4 ^ (bc1 &^ bc0)
+
+		// Round 4
+		bc0 = a[0] ^ a[5] ^ a[10] ^ a[15] ^ a[20]
+		bc1 = a[1] ^ a[6] ^ a[11] ^ a[16] ^ a[21]
+		bc2 = a[2] ^ a[7] ^ a[12] ^ a[17] ^ a[22]
+		bc3 = a[3] ^ a[8] ^ a[13] ^ a[18] ^ a[23]
+		bc4 = a[4] ^ a[9] ^ a[14] ^ a[19] ^ a[24]
+		d0 = bc4 ^ (bc1<<1 | bc1>>63)
+		d1 = bc0 ^ (bc2<<1 | bc2>>63)
+		d2 = bc1 ^ (bc3<<1 | bc3>>63)
+		d3 = bc2 ^ (bc4<<1 | bc4>>63)
+		d4 = bc3 ^ (bc0<<1 | bc0>>63)
+
+		bc0 = a[0] ^ d0
+		t = a[1] ^ d1
+		bc1 = t<<44 | t>>(64-44)
+		t = a[2] ^ d2
+		bc2 = t<<43 | t>>(64-43)
+		t = a[3] ^ d3
+		bc3 = t<<21 | t>>(64-21)
+		t = a[4] ^ d4
+		bc4 = t<<14 | t>>(64-14)
+		a[0] = bc0 ^ (bc2 &^ bc1) ^ rc[i+3]
+		a[1] = bc1 ^ (bc3 &^ bc2)
+		a[2] = bc2 ^ (bc4 &^ bc3)
+		a[3] = bc3 ^ (bc0 &^ bc4)
+		a[4] = bc4 ^ (bc1 &^ bc0)
+
+		t = a[5] ^ d0
+		bc2 = t<<3 | t>>(64-3)
+		t = a[6] ^ d1
+		bc3 = t<<45 | t>>(64-45)
+		t = a[7] ^ d2
+		bc4 = t<<61 | t>>(64-61)
+		t = a[8] ^ d3
+		bc0 = t<<28 | t>>(64-28)
+		t = a[9] ^ d4
+		bc1 = t<<20 | t>>(64-20)
+		a[5] = bc0 ^ (bc2 &^ bc1)
+		a[6] = bc1 ^ (bc3 &^ bc2)
+		a[7] = bc2 ^ (bc4 &^ bc3)
+		a[8] = bc3 ^ (bc0 &^ bc4)
+		a[9] = bc4 ^ (bc1 &^ bc0)
+
+		t = a[10] ^ d0
+		bc4 = t<<18 | t>>(64-18)
+		t = a[11] ^ d1
+		bc0 = t<<1 | t>>(64-1)
+		t = a[12] ^ d2
+		bc1 = t<<6 | t>>(64-6)
+		t = a[13] ^ d3
+		bc2 = t<<25 | t>>(64-25)
+		t = a[14] ^ d4
+		bc3 = t<<8 | t>>(64-8)
+		a[10] = bc0 ^ (bc2 &^ bc1)
+		a[11] = bc1 ^ (bc3 &^ bc2)
+		a[12] = bc2 ^ (bc4 &^ bc3)
+		a[13] = bc3 ^ (bc0 &^ bc4)
+		a[14] = bc4 ^ (bc1 &^ bc0)
+
+		t = a[15] ^ d0
+		bc1 = t<<36 | t>>(64-36)
+		t = a[16] ^ d1
+		bc2 = t<<10 | t>>(64-10)
+		t = a[17] ^ d2
+		bc3 = t<<15 | t>>(64-15)
+		t = a[18] ^ d3
+		bc4 = t<<56 | t>>(64-56)
+		t = a[19] ^ d4
+		bc0 = t<<27 | t>>(64-27)
+		a[15] = bc0 ^ (bc2 &^ bc1)
+		a[16] = bc1 ^ (bc3 &^ bc2)
+		a[17] = bc2 ^ (bc4 &^ bc3)
+		a[18] = bc3 ^ (bc0 &^ bc4)
+		a[19] = bc4 ^ (bc1 &^ bc0)
+
+		t = a[20] ^ d0
+		bc3 = t<<41 | t>>(64-41)
+		t = a[21] ^ d1
+		bc4 = t<<2 | t>>(64-2)
+		t = a[22] ^ d2
+		bc0 = t<<62 | t>>(64-62)
+		t = a[23] ^ d3
+		bc1 = t<<55 | t>>(64-55)
+		t = a[24] ^ d4
+		bc2 = t<<39 | t>>(64-39)
+		a[20] = bc0 ^ (bc2 &^ bc1)
+		a[21] = bc1 ^ (bc3 &^ bc2)
+		a[22] = bc2 ^ (bc4 &^ bc3)
+		a[23] = bc3 ^ (bc0 &^ bc4)
+		a[24] = bc4 ^ (bc1 &^ bc0)
+	}
+}
diff --git a/vendor/golang.org/x/crypto/sha3/keccakf_amd64.go b/vendor/golang.org/x/crypto/sha3/keccakf_amd64.go
new file mode 100644
index 0000000000..248a38241f
--- /dev/null
+++ b/vendor/golang.org/x/crypto/sha3/keccakf_amd64.go
@@ -0,0 +1,14 @@
+// Copyright 2015 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.
+
+//go:build amd64 && !purego && gc
+// +build amd64,!purego,gc
+
+package sha3
+
+// This function is implemented in keccakf_amd64.s.
+
+//go:noescape
+
+func keccakF1600(a *[25]uint64)
diff --git a/vendor/golang.org/x/crypto/sha3/keccakf_amd64.s b/vendor/golang.org/x/crypto/sha3/keccakf_amd64.s
new file mode 100644
index 0000000000..4cfa54383b
--- /dev/null
+++ b/vendor/golang.org/x/crypto/sha3/keccakf_amd64.s
@@ -0,0 +1,391 @@
+// Copyright 2015 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.
+
+//go:build amd64 && !purego && gc
+// +build amd64,!purego,gc
+
+// This code was translated into a form compatible with 6a from the public
+// domain sources at https://github.com/gvanas/KeccakCodePackage
+
+// Offsets in state
+#define _ba  (0*8)
+#define _be  (1*8)
+#define _bi  (2*8)
+#define _bo  (3*8)
+#define _bu  (4*8)
+#define _ga  (5*8)
+#define _ge  (6*8)
+#define _gi  (7*8)
+#define _go  (8*8)
+#define _gu  (9*8)
+#define _ka (10*8)
+#define _ke (11*8)
+#define _ki (12*8)
+#define _ko (13*8)
+#define _ku (14*8)
+#define _ma (15*8)
+#define _me (16*8)
+#define _mi (17*8)
+#define _mo (18*8)
+#define _mu (19*8)
+#define _sa (20*8)
+#define _se (21*8)
+#define _si (22*8)
+#define _so (23*8)
+#define _su (24*8)
+
+// Temporary registers
+#define rT1  AX
+
+// Round vars
+#define rpState DI
+#define rpStack SP
+
+#define rDa BX
+#define rDe CX
+#define rDi DX
+#define rDo R8
+#define rDu R9
+
+#define rBa R10
+#define rBe R11
+#define rBi R12
+#define rBo R13
+#define rBu R14
+
+#define rCa SI
+#define rCe BP
+#define rCi rBi
+#define rCo rBo
+#define rCu R15
+
+#define MOVQ_RBI_RCE MOVQ rBi, rCe
+#define XORQ_RT1_RCA XORQ rT1, rCa
+#define XORQ_RT1_RCE XORQ rT1, rCe
+#define XORQ_RBA_RCU XORQ rBa, rCu
+#define XORQ_RBE_RCU XORQ rBe, rCu
+#define XORQ_RDU_RCU XORQ rDu, rCu
+#define XORQ_RDA_RCA XORQ rDa, rCa
+#define XORQ_RDE_RCE XORQ rDe, rCe
+
+#define mKeccakRound(iState, oState, rc, B_RBI_RCE, G_RT1_RCA, G_RT1_RCE, G_RBA_RCU, K_RT1_RCA, K_RT1_RCE, K_RBA_RCU, M_RT1_RCA, M_RT1_RCE, M_RBE_RCU, S_RDU_RCU, S_RDA_RCA, S_RDE_RCE) \
+	/* Prepare round */    \
+	MOVQ rCe, rDa;         \
+	ROLQ $1, rDa;          \
+	                       \
+	MOVQ _bi(iState), rCi; \
+	XORQ _gi(iState), rDi; \
+	XORQ rCu, rDa;         \
+	XORQ _ki(iState), rCi; \
+	XORQ _mi(iState), rDi; \
+	XORQ rDi, rCi;         \
+	                       \
+	MOVQ rCi, rDe;         \
+	ROLQ $1, rDe;          \
+	                       \
+	MOVQ _bo(iState), rCo; \
+	XORQ _go(iState), rDo; \
+	XORQ rCa, rDe;         \
+	XORQ _ko(iState), rCo; \
+	XORQ _mo(iState), rDo; \
+	XORQ rDo, rCo;         \
+	                       \
+	MOVQ rCo, rDi;         \
+	ROLQ $1, rDi;          \
+	                       \
+	MOVQ rCu, rDo;         \
+	XORQ rCe, rDi;         \
+	ROLQ $1, rDo;          \
+	                       \
+	MOVQ rCa, rDu;         \
+	XORQ rCi, rDo;         \
+	ROLQ $1, rDu;          \
+	                       \
+	/* Result b */         \
+	MOVQ _ba(iState), rBa; \
+	MOVQ _ge(iState), rBe; \
+	XORQ rCo, rDu;         \
+	MOVQ _ki(iState), rBi; \
+	MOVQ _mo(iState), rBo; \
+	MOVQ _su(iState), rBu; \
+	XORQ rDe, rBe;         \
+	ROLQ $44, rBe;         \
+	XORQ rDi, rBi;         \
+	XORQ rDa, rBa;         \
+	ROLQ $43, rBi;         \
+	                       \
+	MOVQ rBe, rCa;         \
+	MOVQ rc, rT1;          \
+	ORQ  rBi, rCa;         \
+	XORQ rBa, rT1;         \
+	XORQ rT1, rCa;         \
+	MOVQ rCa, _ba(oState); \
+	                       \
+	XORQ rDu, rBu;         \
+	ROLQ $14, rBu;         \
+	MOVQ rBa, rCu;         \
+	ANDQ rBe, rCu;         \
+	XORQ rBu, rCu;         \
+	MOVQ rCu, _bu(oState); \
+	                       \
+	XORQ rDo, rBo;         \
+	ROLQ $21, rBo;         \
+	MOVQ rBo, rT1;         \
+	ANDQ rBu, rT1;         \
+	XORQ rBi, rT1;         \
+	MOVQ rT1, _bi(oState); \
+	                       \
+	NOTQ rBi;              \
+	ORQ  rBa, rBu;         \
+	ORQ  rBo, rBi;         \
+	XORQ rBo, rBu;         \
+	XORQ rBe, rBi;         \
+	MOVQ rBu, _bo(oState); \
+	MOVQ rBi, _be(oState); \
+	B_RBI_RCE;             \
+	                       \
+	/* Result g */         \
+	MOVQ _gu(iState), rBe; \
+	XORQ rDu, rBe;         \
+	MOVQ _ka(iState), rBi; \
+	ROLQ $20, rBe;         \
+	XORQ rDa, rBi;         \
+	ROLQ $3, rBi;          \
+	MOVQ _bo(iState), rBa; \
+	MOVQ rBe, rT1;         \
+	ORQ  rBi, rT1;         \
+	XORQ rDo, rBa;         \
+	MOVQ _me(iState), rBo; \
+	MOVQ _si(iState), rBu; \
+	ROLQ $28, rBa;         \
+	XORQ rBa, rT1;         \
+	MOVQ rT1, _ga(oState); \
+	G_RT1_RCA;             \
+	                       \
+	XORQ rDe, rBo;         \
+	ROLQ $45, rBo;         \
+	MOVQ rBi, rT1;         \
+	ANDQ rBo, rT1;         \
+	XORQ rBe, rT1;         \
+	MOVQ rT1, _ge(oState); \
+	G_RT1_RCE;             \
+	                       \
+	XORQ rDi, rBu;         \
+	ROLQ $61, rBu;         \
+	MOVQ rBu, rT1;         \
+	ORQ  rBa, rT1;         \
+	XORQ rBo, rT1;         \
+	MOVQ rT1, _go(oState); \
+	                       \
+	ANDQ rBe, rBa;         \
+	XORQ rBu, rBa;         \
+	MOVQ rBa, _gu(oState); \
+	NOTQ rBu;              \
+	G_RBA_RCU;             \
+	                       \
+	ORQ  rBu, rBo;         \
+	XORQ rBi, rBo;         \
+	MOVQ rBo, _gi(oState); \
+	                       \
+	/* Result k */         \
+	MOVQ _be(iState), rBa; \
+	MOVQ _gi(iState), rBe; \
+	MOVQ _ko(iState), rBi; \
+	MOVQ _mu(iState), rBo; \
+	MOVQ _sa(iState), rBu; \
+	XORQ rDi, rBe;         \
+	ROLQ $6, rBe;          \
+	XORQ rDo, rBi;         \
+	ROLQ $25, rBi;         \
+	MOVQ rBe, rT1;         \
+	ORQ  rBi, rT1;         \
+	XORQ rDe, rBa;         \
+	ROLQ $1, rBa;          \
+	XORQ rBa, rT1;         \
+	MOVQ rT1, _ka(oState); \
+	K_RT1_RCA;             \
+	                       \
+	XORQ rDu, rBo;         \
+	ROLQ $8, rBo;          \
+	MOVQ rBi, rT1;         \
+	ANDQ rBo, rT1;         \
+	XORQ rBe, rT1;         \
+	MOVQ rT1, _ke(oState); \
+	K_RT1_RCE;             \
+	                       \
+	XORQ rDa, rBu;         \
+	ROLQ $18, rBu;         \
+	NOTQ rBo;              \
+	MOVQ rBo, rT1;         \
+	ANDQ rBu, rT1;         \
+	XORQ rBi, rT1;         \
+	MOVQ rT1, _ki(oState); \
+	                       \
+	MOVQ rBu, rT1;         \
+	ORQ  rBa, rT1;         \
+	XORQ rBo, rT1;         \
+	MOVQ rT1, _ko(oState); \
+	                       \
+	ANDQ rBe, rBa;         \
+	XORQ rBu, rBa;         \
+	MOVQ rBa, _ku(oState); \
+	K_RBA_RCU;             \
+	                       \
+	/* Result m */         \
+	MOVQ _ga(iState), rBe; \
+	XORQ rDa, rBe;         \
+	MOVQ _ke(iState), rBi; \
+	ROLQ $36, rBe;         \
+	XORQ rDe, rBi;         \
+	MOVQ _bu(iState), rBa; \
+	ROLQ $10, rBi;         \
+	MOVQ rBe, rT1;         \
+	MOVQ _mi(iState), rBo; \
+	ANDQ rBi, rT1;         \
+	XORQ rDu, rBa;         \
+	MOVQ _so(iState), rBu; \
+	ROLQ $27, rBa;         \
+	XORQ rBa, rT1;         \
+	MOVQ rT1, _ma(oState); \
+	M_RT1_RCA;             \
+	                       \
+	XORQ rDi, rBo;         \
+	ROLQ $15, rBo;         \
+	MOVQ rBi, rT1;         \
+	ORQ  rBo, rT1;         \
+	XORQ rBe, rT1;         \
+	MOVQ rT1, _me(oState); \
+	M_RT1_RCE;             \
+	                       \
+	XORQ rDo, rBu;         \
+	ROLQ $56, rBu;         \
+	NOTQ rBo;              \
+	MOVQ rBo, rT1;         \
+	ORQ  rBu, rT1;         \
+	XORQ rBi, rT1;         \
+	MOVQ rT1, _mi(oState); \
+	                       \
+	ORQ  rBa, rBe;         \
+	XORQ rBu, rBe;         \
+	MOVQ rBe, _mu(oState); \
+	                       \
+	ANDQ rBa, rBu;         \
+	XORQ rBo, rBu;         \
+	MOVQ rBu, _mo(oState); \
+	M_RBE_RCU;             \
+	                       \
+	/* Result s */         \
+	MOVQ _bi(iState), rBa; \
+	MOVQ _go(iState), rBe; \
+	MOVQ _ku(iState), rBi; \
+	XORQ rDi, rBa;         \
+	MOVQ _ma(iState), rBo; \
+	ROLQ $62, rBa;         \
+	XORQ rDo, rBe;         \
+	MOVQ _se(iState), rBu; \
+	ROLQ $55, rBe;         \
+	                       \
+	XORQ rDu, rBi;         \
+	MOVQ rBa, rDu;         \
+	XORQ rDe, rBu;         \
+	ROLQ $2, rBu;          \
+	ANDQ rBe, rDu;         \
+	XORQ rBu, rDu;         \
+	MOVQ rDu, _su(oState); \
+	                       \
+	ROLQ $39, rBi;         \
+	S_RDU_RCU;             \
+	NOTQ rBe;              \
+	XORQ rDa, rBo;         \
+	MOVQ rBe, rDa;         \
+	ANDQ rBi, rDa;         \
+	XORQ rBa, rDa;         \
+	MOVQ rDa, _sa(oState); \
+	S_RDA_RCA;             \
+	                       \
+	ROLQ $41, rBo;         \
+	MOVQ rBi, rDe;         \
+	ORQ  rBo, rDe;         \
+	XORQ rBe, rDe;         \
+	MOVQ rDe, _se(oState); \
+	S_RDE_RCE;             \
+	                       \
+	MOVQ rBo, rDi;         \
+	MOVQ rBu, rDo;         \
+	ANDQ rBu, rDi;         \
+	ORQ  rBa, rDo;         \
+	XORQ rBi, rDi;         \
+	XORQ rBo, rDo;         \
+	MOVQ rDi, _si(oState); \
+	MOVQ rDo, _so(oState)  \
+
+// func keccakF1600(state *[25]uint64)
+TEXT ·keccakF1600(SB), 0, $200-8
+	MOVQ state+0(FP), rpState
+
+	// Convert the user state into an internal state
+	NOTQ _be(rpState)
+	NOTQ _bi(rpState)
+	NOTQ _go(rpState)
+	NOTQ _ki(rpState)
+	NOTQ _mi(rpState)
+	NOTQ _sa(rpState)
+
+	// Execute the KeccakF permutation
+	MOVQ _ba(rpState), rCa
+	MOVQ _be(rpState), rCe
+	MOVQ _bu(rpState), rCu
+
+	XORQ _ga(rpState), rCa
+	XORQ _ge(rpState), rCe
+	XORQ _gu(rpState), rCu
+
+	XORQ _ka(rpState), rCa
+	XORQ _ke(rpState), rCe
+	XORQ _ku(rpState), rCu
+
+	XORQ _ma(rpState), rCa
+	XORQ _me(rpState), rCe
+	XORQ _mu(rpState), rCu
+
+	XORQ _sa(rpState), rCa
+	XORQ _se(rpState), rCe
+	MOVQ _si(rpState), rDi
+	MOVQ _so(rpState), rDo
+	XORQ _su(rpState), rCu
+
+	mKeccakRound(rpState, rpStack, $0x0000000000000001, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
+	mKeccakRound(rpStack, rpState, $0x0000000000008082, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
+	mKeccakRound(rpState, rpStack, $0x800000000000808a, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
+	mKeccakRound(rpStack, rpState, $0x8000000080008000, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
+	mKeccakRound(rpState, rpStack, $0x000000000000808b, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
+	mKeccakRound(rpStack, rpState, $0x0000000080000001, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
+	mKeccakRound(rpState, rpStack, $0x8000000080008081, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
+	mKeccakRound(rpStack, rpState, $0x8000000000008009, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
+	mKeccakRound(rpState, rpStack, $0x000000000000008a, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
+	mKeccakRound(rpStack, rpState, $0x0000000000000088, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
+	mKeccakRound(rpState, rpStack, $0x0000000080008009, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
+	mKeccakRound(rpStack, rpState, $0x000000008000000a, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
+	mKeccakRound(rpState, rpStack, $0x000000008000808b, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
+	mKeccakRound(rpStack, rpState, $0x800000000000008b, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
+	mKeccakRound(rpState, rpStack, $0x8000000000008089, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
+	mKeccakRound(rpStack, rpState, $0x8000000000008003, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
+	mKeccakRound(rpState, rpStack, $0x8000000000008002, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
+	mKeccakRound(rpStack, rpState, $0x8000000000000080, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
+	mKeccakRound(rpState, rpStack, $0x000000000000800a, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
+	mKeccakRound(rpStack, rpState, $0x800000008000000a, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
+	mKeccakRound(rpState, rpStack, $0x8000000080008081, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
+	mKeccakRound(rpStack, rpState, $0x8000000000008080, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
+	mKeccakRound(rpState, rpStack, $0x0000000080000001, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
+	mKeccakRound(rpStack, rpState, $0x8000000080008008, NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP)
+
+	// Revert the internal state to the user state
+	NOTQ _be(rpState)
+	NOTQ _bi(rpState)
+	NOTQ _go(rpState)
+	NOTQ _ki(rpState)
+	NOTQ _mi(rpState)
+	NOTQ _sa(rpState)
+
+	RET
diff --git a/vendor/golang.org/x/crypto/sha3/register.go b/vendor/golang.org/x/crypto/sha3/register.go
new file mode 100644
index 0000000000..8b4453aac3
--- /dev/null
+++ b/vendor/golang.org/x/crypto/sha3/register.go
@@ -0,0 +1,19 @@
+// Copyright 2014 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.
+
+//go:build go1.4
+// +build go1.4
+
+package sha3
+
+import (
+	"crypto"
+)
+
+func init() {
+	crypto.RegisterHash(crypto.SHA3_224, New224)
+	crypto.RegisterHash(crypto.SHA3_256, New256)
+	crypto.RegisterHash(crypto.SHA3_384, New384)
+	crypto.RegisterHash(crypto.SHA3_512, New512)
+}
diff --git a/vendor/golang.org/x/crypto/sha3/sha3.go b/vendor/golang.org/x/crypto/sha3/sha3.go
new file mode 100644
index 0000000000..fa182beb40
--- /dev/null
+++ b/vendor/golang.org/x/crypto/sha3/sha3.go
@@ -0,0 +1,193 @@
+// Copyright 2014 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 sha3
+
+// spongeDirection indicates the direction bytes are flowing through the sponge.
+type spongeDirection int
+
+const (
+	// spongeAbsorbing indicates that the sponge is absorbing input.
+	spongeAbsorbing spongeDirection = iota
+	// spongeSqueezing indicates that the sponge is being squeezed.
+	spongeSqueezing
+)
+
+const (
+	// maxRate is the maximum size of the internal buffer. SHAKE-256
+	// currently needs the largest buffer.
+	maxRate = 168
+)
+
+type state struct {
+	// Generic sponge components.
+	a    [25]uint64 // main state of the hash
+	buf  []byte     // points into storage
+	rate int        // the number of bytes of state to use
+
+	// dsbyte contains the "domain separation" bits and the first bit of
+	// the padding. Sections 6.1 and 6.2 of [1] separate the outputs of the
+	// SHA-3 and SHAKE functions by appending bitstrings to the message.
+	// Using a little-endian bit-ordering convention, these are "01" for SHA-3
+	// and "1111" for SHAKE, or 00000010b and 00001111b, respectively. Then the
+	// padding rule from section 5.1 is applied to pad the message to a multiple
+	// of the rate, which involves adding a "1" bit, zero or more "0" bits, and
+	// a final "1" bit. We merge the first "1" bit from the padding into dsbyte,
+	// giving 00000110b (0x06) and 00011111b (0x1f).
+	// [1] http://csrc.nist.gov/publications/drafts/fips-202/fips_202_draft.pdf
+	//     "Draft FIPS 202: SHA-3 Standard: Permutation-Based Hash and
+	//      Extendable-Output Functions (May 2014)"
+	dsbyte byte
+
+	storage storageBuf
+
+	// Specific to SHA-3 and SHAKE.
+	outputLen int             // the default output size in bytes
+	state     spongeDirection // whether the sponge is absorbing or squeezing
+}
+
+// BlockSize returns the rate of sponge underlying this hash function.
+func (d *state) BlockSize() int { return d.rate }
+
+// Size returns the output size of the hash function in bytes.
+func (d *state) Size() int { return d.outputLen }
+
+// Reset clears the internal state by zeroing the sponge state and
+// the byte buffer, and setting Sponge.state to absorbing.
+func (d *state) Reset() {
+	// Zero the permutation's state.
+	for i := range d.a {
+		d.a[i] = 0
+	}
+	d.state = spongeAbsorbing
+	d.buf = d.storage.asBytes()[:0]
+}
+
+func (d *state) clone() *state {
+	ret := *d
+	if ret.state == spongeAbsorbing {
+		ret.buf = ret.storage.asBytes()[:len(ret.buf)]
+	} else {
+		ret.buf = ret.storage.asBytes()[d.rate-cap(d.buf) : d.rate]
+	}
+
+	return &ret
+}
+
+// permute applies the KeccakF-1600 permutation. It handles
+// any input-output buffering.
+func (d *state) permute() {
+	switch d.state {
+	case spongeAbsorbing:
+		// If we're absorbing, we need to xor the input into the state
+		// before applying the permutation.
+		xorIn(d, d.buf)
+		d.buf = d.storage.asBytes()[:0]
+		keccakF1600(&d.a)
+	case spongeSqueezing:
+		// If we're squeezing, we need to apply the permutation before
+		// copying more output.
+		keccakF1600(&d.a)
+		d.buf = d.storage.asBytes()[:d.rate]
+		copyOut(d, d.buf)
+	}
+}
+
+// pads appends the domain separation bits in dsbyte, applies
+// the multi-bitrate 10..1 padding rule, and permutes the state.
+func (d *state) padAndPermute(dsbyte byte) {
+	if d.buf == nil {
+		d.buf = d.storage.asBytes()[:0]
+	}
+	// Pad with this instance's domain-separator bits. We know that there's
+	// at least one byte of space in d.buf because, if it were full,
+	// permute would have been called to empty it. dsbyte also contains the
+	// first one bit for the padding. See the comment in the state struct.
+	d.buf = append(d.buf, dsbyte)
+	zerosStart := len(d.buf)
+	d.buf = d.storage.asBytes()[:d.rate]
+	for i := zerosStart; i < d.rate; i++ {
+		d.buf[i] = 0
+	}
+	// This adds the final one bit for the padding. Because of the way that
+	// bits are numbered from the LSB upwards, the final bit is the MSB of
+	// the last byte.
+	d.buf[d.rate-1] ^= 0x80
+	// Apply the permutation
+	d.permute()
+	d.state = spongeSqueezing
+	d.buf = d.storage.asBytes()[:d.rate]
+	copyOut(d, d.buf)
+}
+
+// Write absorbs more data into the hash's state. It produces an error
+// if more data is written to the ShakeHash after writing
+func (d *state) Write(p []byte) (written int, err error) {
+	if d.state != spongeAbsorbing {
+		panic("sha3: write to sponge after read")
+	}
+	if d.buf == nil {
+		d.buf = d.storage.asBytes()[:0]
+	}
+	written = len(p)
+
+	for len(p) > 0 {
+		if len(d.buf) == 0 && len(p) >= d.rate {
+			// The fast path; absorb a full "rate" bytes of input and apply the permutation.
+			xorIn(d, p[:d.rate])
+			p = p[d.rate:]
+			keccakF1600(&d.a)
+		} else {
+			// The slow path; buffer the input until we can fill the sponge, and then xor it in.
+			todo := d.rate - len(d.buf)
+			if todo > len(p) {
+				todo = len(p)
+			}
+			d.buf = append(d.buf, p[:todo]...)
+			p = p[todo:]
+
+			// If the sponge is full, apply the permutation.
+			if len(d.buf) == d.rate {
+				d.permute()
+			}
+		}
+	}
+
+	return
+}
+
+// Read squeezes an arbitrary number of bytes from the sponge.
+func (d *state) Read(out []byte) (n int, err error) {
+	// If we're still absorbing, pad and apply the permutation.
+	if d.state == spongeAbsorbing {
+		d.padAndPermute(d.dsbyte)
+	}
+
+	n = len(out)
+
+	// Now, do the squeezing.
+	for len(out) > 0 {
+		n := copy(out, d.buf)
+		d.buf = d.buf[n:]
+		out = out[n:]
+
+		// Apply the permutation if we've squeezed the sponge dry.
+		if len(d.buf) == 0 {
+			d.permute()
+		}
+	}
+
+	return
+}
+
+// Sum applies padding to the hash state and then squeezes out the desired
+// number of output bytes.
+func (d *state) Sum(in []byte) []byte {
+	// Make a copy of the original hash so that caller can keep writing
+	// and summing.
+	dup := d.clone()
+	hash := make([]byte, dup.outputLen)
+	dup.Read(hash)
+	return append(in, hash...)
+}
diff --git a/vendor/golang.org/x/crypto/sha3/sha3_s390x.go b/vendor/golang.org/x/crypto/sha3/sha3_s390x.go
new file mode 100644
index 0000000000..4fcfc924ef
--- /dev/null
+++ b/vendor/golang.org/x/crypto/sha3/sha3_s390x.go
@@ -0,0 +1,285 @@
+// Copyright 2017 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.
+
+//go:build gc && !purego
+// +build gc,!purego
+
+package sha3
+
+// This file contains code for using the 'compute intermediate
+// message digest' (KIMD) and 'compute last message digest' (KLMD)
+// instructions to compute SHA-3 and SHAKE hashes on IBM Z.
+
+import (
+	"hash"
+
+	"golang.org/x/sys/cpu"
+)
+
+// codes represent 7-bit KIMD/KLMD function codes as defined in
+// the Principles of Operation.
+type code uint64
+
+const (
+	// function codes for KIMD/KLMD
+	sha3_224  code = 32
+	sha3_256       = 33
+	sha3_384       = 34
+	sha3_512       = 35
+	shake_128      = 36
+	shake_256      = 37
+	nopad          = 0x100
+)
+
+// kimd is a wrapper for the 'compute intermediate message digest' instruction.
+// src must be a multiple of the rate for the given function code.
+//go:noescape
+func kimd(function code, chain *[200]byte, src []byte)
+
+// klmd is a wrapper for the 'compute last message digest' instruction.
+// src padding is handled by the instruction.
+//go:noescape
+func klmd(function code, chain *[200]byte, dst, src []byte)
+
+type asmState struct {
+	a         [200]byte       // 1600 bit state
+	buf       []byte          // care must be taken to ensure cap(buf) is a multiple of rate
+	rate      int             // equivalent to block size
+	storage   [3072]byte      // underlying storage for buf
+	outputLen int             // output length if fixed, 0 if not
+	function  code            // KIMD/KLMD function code
+	state     spongeDirection // whether the sponge is absorbing or squeezing
+}
+
+func newAsmState(function code) *asmState {
+	var s asmState
+	s.function = function
+	switch function {
+	case sha3_224:
+		s.rate = 144
+		s.outputLen = 28
+	case sha3_256:
+		s.rate = 136
+		s.outputLen = 32
+	case sha3_384:
+		s.rate = 104
+		s.outputLen = 48
+	case sha3_512:
+		s.rate = 72
+		s.outputLen = 64
+	case shake_128:
+		s.rate = 168
+	case shake_256:
+		s.rate = 136
+	default:
+		panic("sha3: unrecognized function code")
+	}
+
+	// limit s.buf size to a multiple of s.rate
+	s.resetBuf()
+	return &s
+}
+
+func (s *asmState) clone() *asmState {
+	c := *s
+	c.buf = c.storage[:len(s.buf):cap(s.buf)]
+	return &c
+}
+
+// copyIntoBuf copies b into buf. It will panic if there is not enough space to
+// store all of b.
+func (s *asmState) copyIntoBuf(b []byte) {
+	bufLen := len(s.buf)
+	s.buf = s.buf[:len(s.buf)+len(b)]
+	copy(s.buf[bufLen:], b)
+}
+
+// resetBuf points buf at storage, sets the length to 0 and sets cap to be a
+// multiple of the rate.
+func (s *asmState) resetBuf() {
+	max := (cap(s.storage) / s.rate) * s.rate
+	s.buf = s.storage[:0:max]
+}
+
+// Write (via the embedded io.Writer interface) adds more data to the running hash.
+// It never returns an error.
+func (s *asmState) Write(b []byte) (int, error) {
+	if s.state != spongeAbsorbing {
+		panic("sha3: write to sponge after read")
+	}
+	length := len(b)
+	for len(b) > 0 {
+		if len(s.buf) == 0 && len(b) >= cap(s.buf) {
+			// Hash the data directly and push any remaining bytes
+			// into the buffer.
+			remainder := len(b) % s.rate
+			kimd(s.function, &s.a, b[:len(b)-remainder])
+			if remainder != 0 {
+				s.copyIntoBuf(b[len(b)-remainder:])
+			}
+			return length, nil
+		}
+
+		if len(s.buf) == cap(s.buf) {
+			// flush the buffer
+			kimd(s.function, &s.a, s.buf)
+			s.buf = s.buf[:0]
+		}
+
+		// copy as much as we can into the buffer
+		n := len(b)
+		if len(b) > cap(s.buf)-len(s.buf) {
+			n = cap(s.buf) - len(s.buf)
+		}
+		s.copyIntoBuf(b[:n])
+		b = b[n:]
+	}
+	return length, nil
+}
+
+// Read squeezes an arbitrary number of bytes from the sponge.
+func (s *asmState) Read(out []byte) (n int, err error) {
+	n = len(out)
+
+	// need to pad if we were absorbing
+	if s.state == spongeAbsorbing {
+		s.state = spongeSqueezing
+
+		// write hash directly into out if possible
+		if len(out)%s.rate == 0 {
+			klmd(s.function, &s.a, out, s.buf) // len(out) may be 0
+			s.buf = s.buf[:0]
+			return
+		}
+
+		// write hash into buffer
+		max := cap(s.buf)
+		if max > len(out) {
+			max = (len(out)/s.rate)*s.rate + s.rate
+		}
+		klmd(s.function, &s.a, s.buf[:max], s.buf)
+		s.buf = s.buf[:max]
+	}
+
+	for len(out) > 0 {
+		// flush the buffer
+		if len(s.buf) != 0 {
+			c := copy(out, s.buf)
+			out = out[c:]
+			s.buf = s.buf[c:]
+			continue
+		}
+
+		// write hash directly into out if possible
+		if len(out)%s.rate == 0 {
+			klmd(s.function|nopad, &s.a, out, nil)
+			return
+		}
+
+		// write hash into buffer
+		s.resetBuf()
+		if cap(s.buf) > len(out) {
+			s.buf = s.buf[:(len(out)/s.rate)*s.rate+s.rate]
+		}
+		klmd(s.function|nopad, &s.a, s.buf, nil)
+	}
+	return
+}
+
+// Sum appends the current hash to b and returns the resulting slice.
+// It does not change the underlying hash state.
+func (s *asmState) Sum(b []byte) []byte {
+	if s.outputLen == 0 {
+		panic("sha3: cannot call Sum on SHAKE functions")
+	}
+
+	// Copy the state to preserve the original.
+	a := s.a
+
+	// Hash the buffer. Note that we don't clear it because we
+	// aren't updating the state.
+	klmd(s.function, &a, nil, s.buf)
+	return append(b, a[:s.outputLen]...)
+}
+
+// Reset resets the Hash to its initial state.
+func (s *asmState) Reset() {
+	for i := range s.a {
+		s.a[i] = 0
+	}
+	s.resetBuf()
+	s.state = spongeAbsorbing
+}
+
+// Size returns the number of bytes Sum will return.
+func (s *asmState) Size() int {
+	return s.outputLen
+}
+
+// BlockSize returns the hash's underlying block size.
+// The Write method must be able to accept any amount
+// of data, but it may operate more efficiently if all writes
+// are a multiple of the block size.
+func (s *asmState) BlockSize() int {
+	return s.rate
+}
+
+// Clone returns a copy of the ShakeHash in its current state.
+func (s *asmState) Clone() ShakeHash {
+	return s.clone()
+}
+
+// new224Asm returns an assembly implementation of SHA3-224 if available,
+// otherwise it returns nil.
+func new224Asm() hash.Hash {
+	if cpu.S390X.HasSHA3 {
+		return newAsmState(sha3_224)
+	}
+	return nil
+}
+
+// new256Asm returns an assembly implementation of SHA3-256 if available,
+// otherwise it returns nil.
+func new256Asm() hash.Hash {
+	if cpu.S390X.HasSHA3 {
+		return newAsmState(sha3_256)
+	}
+	return nil
+}
+
+// new384Asm returns an assembly implementation of SHA3-384 if available,
+// otherwise it returns nil.
+func new384Asm() hash.Hash {
+	if cpu.S390X.HasSHA3 {
+		return newAsmState(sha3_384)
+	}
+	return nil
+}
+
+// new512Asm returns an assembly implementation of SHA3-512 if available,
+// otherwise it returns nil.
+func new512Asm() hash.Hash {
+	if cpu.S390X.HasSHA3 {
+		return newAsmState(sha3_512)
+	}
+	return nil
+}
+
+// newShake128Asm returns an assembly implementation of SHAKE-128 if available,
+// otherwise it returns nil.
+func newShake128Asm() ShakeHash {
+	if cpu.S390X.HasSHA3 {
+		return newAsmState(shake_128)
+	}
+	return nil
+}
+
+// newShake256Asm returns an assembly implementation of SHAKE-256 if available,
+// otherwise it returns nil.
+func newShake256Asm() ShakeHash {
+	if cpu.S390X.HasSHA3 {
+		return newAsmState(shake_256)
+	}
+	return nil
+}
diff --git a/vendor/golang.org/x/crypto/sha3/sha3_s390x.s b/vendor/golang.org/x/crypto/sha3/sha3_s390x.s
new file mode 100644
index 0000000000..a0e051b045
--- /dev/null
+++ b/vendor/golang.org/x/crypto/sha3/sha3_s390x.s
@@ -0,0 +1,34 @@
+// Copyright 2017 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.
+
+//go:build gc && !purego
+// +build gc,!purego
+
+#include "textflag.h"
+
+// func kimd(function code, chain *[200]byte, src []byte)
+TEXT ·kimd(SB), NOFRAME|NOSPLIT, $0-40
+	MOVD function+0(FP), R0
+	MOVD chain+8(FP), R1
+	LMG  src+16(FP), R2, R3 // R2=base, R3=len
+
+continue:
+	WORD $0xB93E0002 // KIMD --, R2
+	BVS  continue    // continue if interrupted
+	MOVD $0, R0      // reset R0 for pre-go1.8 compilers
+	RET
+
+// func klmd(function code, chain *[200]byte, dst, src []byte)
+TEXT ·klmd(SB), NOFRAME|NOSPLIT, $0-64
+	// TODO: SHAKE support
+	MOVD function+0(FP), R0
+	MOVD chain+8(FP), R1
+	LMG  dst+16(FP), R2, R3 // R2=base, R3=len
+	LMG  src+40(FP), R4, R5 // R4=base, R5=len
+
+continue:
+	WORD $0xB93F0024 // KLMD R2, R4
+	BVS  continue    // continue if interrupted
+	MOVD $0, R0      // reset R0 for pre-go1.8 compilers
+	RET
diff --git a/vendor/golang.org/x/crypto/sha3/shake.go b/vendor/golang.org/x/crypto/sha3/shake.go
new file mode 100644
index 0000000000..d7be2954ab
--- /dev/null
+++ b/vendor/golang.org/x/crypto/sha3/shake.go
@@ -0,0 +1,173 @@
+// Copyright 2014 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 sha3
+
+// This file defines the ShakeHash interface, and provides
+// functions for creating SHAKE and cSHAKE instances, as well as utility
+// functions for hashing bytes to arbitrary-length output.
+//
+//
+// SHAKE implementation is based on FIPS PUB 202 [1]
+// cSHAKE implementations is based on NIST SP 800-185 [2]
+//
+// [1] https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf
+// [2] https://doi.org/10.6028/NIST.SP.800-185
+
+import (
+	"encoding/binary"
+	"io"
+)
+
+// ShakeHash defines the interface to hash functions that
+// support arbitrary-length output.
+type ShakeHash interface {
+	// Write absorbs more data into the hash's state. It panics if input is
+	// written to it after output has been read from it.
+	io.Writer
+
+	// Read reads more output from the hash; reading affects the hash's
+	// state. (ShakeHash.Read is thus very different from Hash.Sum)
+	// It never returns an error.
+	io.Reader
+
+	// Clone returns a copy of the ShakeHash in its current state.
+	Clone() ShakeHash
+
+	// Reset resets the ShakeHash to its initial state.
+	Reset()
+}
+
+// cSHAKE specific context
+type cshakeState struct {
+	*state // SHA-3 state context and Read/Write operations
+
+	// initBlock is the cSHAKE specific initialization set of bytes. It is initialized
+	// by newCShake function and stores concatenation of N followed by S, encoded
+	// by the method specified in 3.3 of [1].
+	// It is stored here in order for Reset() to be able to put context into
+	// initial state.
+	initBlock []byte
+}
+
+// Consts for configuring initial SHA-3 state
+const (
+	dsbyteShake  = 0x1f
+	dsbyteCShake = 0x04
+	rate128      = 168
+	rate256      = 136
+)
+
+func bytepad(input []byte, w int) []byte {
+	// leftEncode always returns max 9 bytes
+	buf := make([]byte, 0, 9+len(input)+w)
+	buf = append(buf, leftEncode(uint64(w))...)
+	buf = append(buf, input...)
+	padlen := w - (len(buf) % w)
+	return append(buf, make([]byte, padlen)...)
+}
+
+func leftEncode(value uint64) []byte {
+	var b [9]byte
+	binary.BigEndian.PutUint64(b[1:], value)
+	// Trim all but last leading zero bytes
+	i := byte(1)
+	for i < 8 && b[i] == 0 {
+		i++
+	}
+	// Prepend number of encoded bytes
+	b[i-1] = 9 - i
+	return b[i-1:]
+}
+
+func newCShake(N, S []byte, rate int, dsbyte byte) ShakeHash {
+	c := cshakeState{state: &state{rate: rate, dsbyte: dsbyte}}
+
+	// leftEncode returns max 9 bytes
+	c.initBlock = make([]byte, 0, 9*2+len(N)+len(S))
+	c.initBlock = append(c.initBlock, leftEncode(uint64(len(N)*8))...)
+	c.initBlock = append(c.initBlock, N...)
+	c.initBlock = append(c.initBlock, leftEncode(uint64(len(S)*8))...)
+	c.initBlock = append(c.initBlock, S...)
+	c.Write(bytepad(c.initBlock, c.rate))
+	return &c
+}
+
+// Reset resets the hash to initial state.
+func (c *cshakeState) Reset() {
+	c.state.Reset()
+	c.Write(bytepad(c.initBlock, c.rate))
+}
+
+// Clone returns copy of a cSHAKE context within its current state.
+func (c *cshakeState) Clone() ShakeHash {
+	b := make([]byte, len(c.initBlock))
+	copy(b, c.initBlock)
+	return &cshakeState{state: c.clone(), initBlock: b}
+}
+
+// Clone returns copy of SHAKE context within its current state.
+func (c *state) Clone() ShakeHash {
+	return c.clone()
+}
+
+// NewShake128 creates a new SHAKE128 variable-output-length ShakeHash.
+// Its generic security strength is 128 bits against all attacks if at
+// least 32 bytes of its output are used.
+func NewShake128() ShakeHash {
+	if h := newShake128Asm(); h != nil {
+		return h
+	}
+	return &state{rate: rate128, dsbyte: dsbyteShake}
+}
+
+// NewShake256 creates a new SHAKE256 variable-output-length ShakeHash.
+// Its generic security strength is 256 bits against all attacks if
+// at least 64 bytes of its output are used.
+func NewShake256() ShakeHash {
+	if h := newShake256Asm(); h != nil {
+		return h
+	}
+	return &state{rate: rate256, dsbyte: dsbyteShake}
+}
+
+// NewCShake128 creates a new instance of cSHAKE128 variable-output-length ShakeHash,
+// a customizable variant of SHAKE128.
+// N is used to define functions based on cSHAKE, it can be empty when plain cSHAKE is
+// desired. S is a customization byte string used for domain separation - two cSHAKE
+// computations on same input with different S yield unrelated outputs.
+// When N and S are both empty, this is equivalent to NewShake128.
+func NewCShake128(N, S []byte) ShakeHash {
+	if len(N) == 0 && len(S) == 0 {
+		return NewShake128()
+	}
+	return newCShake(N, S, rate128, dsbyteCShake)
+}
+
+// NewCShake256 creates a new instance of cSHAKE256 variable-output-length ShakeHash,
+// a customizable variant of SHAKE256.
+// N is used to define functions based on cSHAKE, it can be empty when plain cSHAKE is
+// desired. S is a customization byte string used for domain separation - two cSHAKE
+// computations on same input with different S yield unrelated outputs.
+// When N and S are both empty, this is equivalent to NewShake256.
+func NewCShake256(N, S []byte) ShakeHash {
+	if len(N) == 0 && len(S) == 0 {
+		return NewShake256()
+	}
+	return newCShake(N, S, rate256, dsbyteCShake)
+}
+
+// ShakeSum128 writes an arbitrary-length digest of data into hash.
+func ShakeSum128(hash, data []byte) {
+	h := NewShake128()
+	h.Write(data)
+	h.Read(hash)
+}
+
+// ShakeSum256 writes an arbitrary-length digest of data into hash.
+func ShakeSum256(hash, data []byte) {
+	h := NewShake256()
+	h.Write(data)
+	h.Read(hash)
+}
diff --git a/vendor/golang.org/x/crypto/sha3/shake_generic.go b/vendor/golang.org/x/crypto/sha3/shake_generic.go
new file mode 100644
index 0000000000..5c0710ef98
--- /dev/null
+++ b/vendor/golang.org/x/crypto/sha3/shake_generic.go
@@ -0,0 +1,20 @@
+// Copyright 2017 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.
+
+//go:build !gc || purego || !s390x
+// +build !gc purego !s390x
+
+package sha3
+
+// newShake128Asm returns an assembly implementation of SHAKE-128 if available,
+// otherwise it returns nil.
+func newShake128Asm() ShakeHash {
+	return nil
+}
+
+// newShake256Asm returns an assembly implementation of SHAKE-256 if available,
+// otherwise it returns nil.
+func newShake256Asm() ShakeHash {
+	return nil
+}
diff --git a/vendor/golang.org/x/crypto/sha3/xor.go b/vendor/golang.org/x/crypto/sha3/xor.go
new file mode 100644
index 0000000000..59c8eb9418
--- /dev/null
+++ b/vendor/golang.org/x/crypto/sha3/xor.go
@@ -0,0 +1,24 @@
+// Copyright 2015 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.
+
+//go:build (!amd64 && !386 && !ppc64le) || purego
+// +build !amd64,!386,!ppc64le purego
+
+package sha3
+
+// A storageBuf is an aligned array of maxRate bytes.
+type storageBuf [maxRate]byte
+
+func (b *storageBuf) asBytes() *[maxRate]byte {
+	return (*[maxRate]byte)(b)
+}
+
+var (
+	xorIn            = xorInGeneric
+	copyOut          = copyOutGeneric
+	xorInUnaligned   = xorInGeneric
+	copyOutUnaligned = copyOutGeneric
+)
+
+const xorImplementationUnaligned = "generic"
diff --git a/vendor/golang.org/x/crypto/sha3/xor_generic.go b/vendor/golang.org/x/crypto/sha3/xor_generic.go
new file mode 100644
index 0000000000..8d94771127
--- /dev/null
+++ b/vendor/golang.org/x/crypto/sha3/xor_generic.go
@@ -0,0 +1,28 @@
+// Copyright 2015 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 sha3
+
+import "encoding/binary"
+
+// xorInGeneric xors the bytes in buf into the state; it
+// makes no non-portable assumptions about memory layout
+// or alignment.
+func xorInGeneric(d *state, buf []byte) {
+	n := len(buf) / 8
+
+	for i := 0; i < n; i++ {
+		a := binary.LittleEndian.Uint64(buf)
+		d.a[i] ^= a
+		buf = buf[8:]
+	}
+}
+
+// copyOutGeneric copies uint64s to a byte buffer.
+func copyOutGeneric(d *state, b []byte) {
+	for i := 0; len(b) >= 8; i++ {
+		binary.LittleEndian.PutUint64(b, d.a[i])
+		b = b[8:]
+	}
+}
diff --git a/vendor/golang.org/x/crypto/sha3/xor_unaligned.go b/vendor/golang.org/x/crypto/sha3/xor_unaligned.go
new file mode 100644
index 0000000000..1ce606246d
--- /dev/null
+++ b/vendor/golang.org/x/crypto/sha3/xor_unaligned.go
@@ -0,0 +1,68 @@
+// Copyright 2015 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.
+
+//go:build (amd64 || 386 || ppc64le) && !purego
+// +build amd64 386 ppc64le
+// +build !purego
+
+package sha3
+
+import "unsafe"
+
+// A storageBuf is an aligned array of maxRate bytes.
+type storageBuf [maxRate / 8]uint64
+
+func (b *storageBuf) asBytes() *[maxRate]byte {
+	return (*[maxRate]byte)(unsafe.Pointer(b))
+}
+
+// xorInUnaligned uses unaligned reads and writes to update d.a to contain d.a
+// XOR buf.
+func xorInUnaligned(d *state, buf []byte) {
+	n := len(buf)
+	bw := (*[maxRate / 8]uint64)(unsafe.Pointer(&buf[0]))[: n/8 : n/8]
+	if n >= 72 {
+		d.a[0] ^= bw[0]
+		d.a[1] ^= bw[1]
+		d.a[2] ^= bw[2]
+		d.a[3] ^= bw[3]
+		d.a[4] ^= bw[4]
+		d.a[5] ^= bw[5]
+		d.a[6] ^= bw[6]
+		d.a[7] ^= bw[7]
+		d.a[8] ^= bw[8]
+	}
+	if n >= 104 {
+		d.a[9] ^= bw[9]
+		d.a[10] ^= bw[10]
+		d.a[11] ^= bw[11]
+		d.a[12] ^= bw[12]
+	}
+	if n >= 136 {
+		d.a[13] ^= bw[13]
+		d.a[14] ^= bw[14]
+		d.a[15] ^= bw[15]
+		d.a[16] ^= bw[16]
+	}
+	if n >= 144 {
+		d.a[17] ^= bw[17]
+	}
+	if n >= 168 {
+		d.a[18] ^= bw[18]
+		d.a[19] ^= bw[19]
+		d.a[20] ^= bw[20]
+	}
+}
+
+func copyOutUnaligned(d *state, buf []byte) {
+	ab := (*[maxRate]uint8)(unsafe.Pointer(&d.a[0]))
+	copy(buf, ab[:])
+}
+
+var (
+	xorIn   = xorInUnaligned
+	copyOut = copyOutUnaligned
+)
+
+const xorImplementationUnaligned = "unaligned"
diff --git a/vendor/golang.org/x/crypto/ssh/agent/client.go b/vendor/golang.org/x/crypto/ssh/agent/client.go
new file mode 100644
index 0000000000..3cfe723d29
--- /dev/null
+++ b/vendor/golang.org/x/crypto/ssh/agent/client.go
@@ -0,0 +1,819 @@
+// 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 agent implements the ssh-agent protocol, and provides both
+// a client and a server. The client can talk to a standard ssh-agent
+// that uses UNIX sockets, and one could implement an alternative
+// ssh-agent process using the sample server.
+//
+// References:
+//  [PROTOCOL.agent]: https://tools.ietf.org/html/draft-miller-ssh-agent-00
+package agent // import "golang.org/x/crypto/ssh/agent"
+
+import (
+	"bytes"
+	"crypto/dsa"
+	"crypto/ecdsa"
+	"crypto/elliptic"
+	"crypto/rsa"
+	"encoding/base64"
+	"encoding/binary"
+	"errors"
+	"fmt"
+	"io"
+	"math/big"
+	"sync"
+
+	"golang.org/x/crypto/ed25519"
+	"golang.org/x/crypto/ssh"
+)
+
+// SignatureFlags represent additional flags that can be passed to the signature
+// requests an defined in [PROTOCOL.agent] section 4.5.1.
+type SignatureFlags uint32
+
+// SignatureFlag values as defined in [PROTOCOL.agent] section 5.3.
+const (
+	SignatureFlagReserved SignatureFlags = 1 << iota
+	SignatureFlagRsaSha256
+	SignatureFlagRsaSha512
+)
+
+// Agent represents the capabilities of an ssh-agent.
+type Agent interface {
+	// List returns the identities known to the agent.
+	List() ([]*Key, error)
+
+	// Sign has the agent sign the data using a protocol 2 key as defined
+	// in [PROTOCOL.agent] section 2.6.2.
+	Sign(key ssh.PublicKey, data []byte) (*ssh.Signature, error)
+
+	// Add adds a private key to the agent.
+	Add(key AddedKey) error
+
+	// Remove removes all identities with the given public key.
+	Remove(key ssh.PublicKey) error
+
+	// RemoveAll removes all identities.
+	RemoveAll() error
+
+	// Lock locks the agent. Sign and Remove will fail, and List will empty an empty list.
+	Lock(passphrase []byte) error
+
+	// Unlock undoes the effect of Lock
+	Unlock(passphrase []byte) error
+
+	// Signers returns signers for all the known keys.
+	Signers() ([]ssh.Signer, error)
+}
+
+type ExtendedAgent interface {
+	Agent
+
+	// SignWithFlags signs like Sign, but allows for additional flags to be sent/received
+	SignWithFlags(key ssh.PublicKey, data []byte, flags SignatureFlags) (*ssh.Signature, error)
+
+	// Extension processes a custom extension request. Standard-compliant agents are not
+	// required to support any extensions, but this method allows agents to implement
+	// vendor-specific methods or add experimental features. See [PROTOCOL.agent] section 4.7.
+	// If agent extensions are unsupported entirely this method MUST return an
+	// ErrExtensionUnsupported error. Similarly, if just the specific extensionType in
+	// the request is unsupported by the agent then ErrExtensionUnsupported MUST be
+	// returned.
+	//
+	// In the case of success, since [PROTOCOL.agent] section 4.7 specifies that the contents
+	// of the response are unspecified (including the type of the message), the complete
+	// response will be returned as a []byte slice, including the "type" byte of the message.
+	Extension(extensionType string, contents []byte) ([]byte, error)
+}
+
+// ConstraintExtension describes an optional constraint defined by users.
+type ConstraintExtension struct {
+	// ExtensionName consist of a UTF-8 string suffixed by the
+	// implementation domain following the naming scheme defined
+	// in Section 4.2 of [RFC4251], e.g.  "foo@example.com".
+	ExtensionName string
+	// ExtensionDetails contains the actual content of the extended
+	// constraint.
+	ExtensionDetails []byte
+}
+
+// AddedKey describes an SSH key to be added to an Agent.
+type AddedKey struct {
+	// PrivateKey must be a *rsa.PrivateKey, *dsa.PrivateKey,
+	// ed25519.PrivateKey or *ecdsa.PrivateKey, which will be inserted into the
+	// agent.
+	PrivateKey interface{}
+	// Certificate, if not nil, is communicated to the agent and will be
+	// stored with the key.
+	Certificate *ssh.Certificate
+	// Comment is an optional, free-form string.
+	Comment string
+	// LifetimeSecs, if not zero, is the number of seconds that the
+	// agent will store the key for.
+	LifetimeSecs uint32
+	// ConfirmBeforeUse, if true, requests that the agent confirm with the
+	// user before each use of this key.
+	ConfirmBeforeUse bool
+	// ConstraintExtensions are the experimental or private-use constraints
+	// defined by users.
+	ConstraintExtensions []ConstraintExtension
+}
+
+// See [PROTOCOL.agent], section 3.
+const (
+	agentRequestV1Identities   = 1
+	agentRemoveAllV1Identities = 9
+
+	// 3.2 Requests from client to agent for protocol 2 key operations
+	agentAddIdentity         = 17
+	agentRemoveIdentity      = 18
+	agentRemoveAllIdentities = 19
+	agentAddIDConstrained    = 25
+
+	// 3.3 Key-type independent requests from client to agent
+	agentAddSmartcardKey            = 20
+	agentRemoveSmartcardKey         = 21
+	agentLock                       = 22
+	agentUnlock                     = 23
+	agentAddSmartcardKeyConstrained = 26
+
+	// 3.7 Key constraint identifiers
+	agentConstrainLifetime  = 1
+	agentConstrainConfirm   = 2
+	agentConstrainExtension = 3
+)
+
+// maxAgentResponseBytes is the maximum agent reply size that is accepted. This
+// is a sanity check, not a limit in the spec.
+const maxAgentResponseBytes = 16 << 20
+
+// Agent messages:
+// These structures mirror the wire format of the corresponding ssh agent
+// messages found in [PROTOCOL.agent].
+
+// 3.4 Generic replies from agent to client
+const agentFailure = 5
+
+type failureAgentMsg struct{}
+
+const agentSuccess = 6
+
+type successAgentMsg struct{}
+
+// See [PROTOCOL.agent], section 2.5.2.
+const agentRequestIdentities = 11
+
+type requestIdentitiesAgentMsg struct{}
+
+// See [PROTOCOL.agent], section 2.5.2.
+const agentIdentitiesAnswer = 12
+
+type identitiesAnswerAgentMsg struct {
+	NumKeys uint32 `sshtype:"12"`
+	Keys    []byte `ssh:"rest"`
+}
+
+// See [PROTOCOL.agent], section 2.6.2.
+const agentSignRequest = 13
+
+type signRequestAgentMsg struct {
+	KeyBlob []byte `sshtype:"13"`
+	Data    []byte
+	Flags   uint32
+}
+
+// See [PROTOCOL.agent], section 2.6.2.
+
+// 3.6 Replies from agent to client for protocol 2 key operations
+const agentSignResponse = 14
+
+type signResponseAgentMsg struct {
+	SigBlob []byte `sshtype:"14"`
+}
+
+type publicKey struct {
+	Format string
+	Rest   []byte `ssh:"rest"`
+}
+
+// 3.7 Key constraint identifiers
+type constrainLifetimeAgentMsg struct {
+	LifetimeSecs uint32 `sshtype:"1"`
+}
+
+type constrainExtensionAgentMsg struct {
+	ExtensionName    string `sshtype:"3"`
+	ExtensionDetails []byte
+
+	// Rest is a field used for parsing, not part of message
+	Rest []byte `ssh:"rest"`
+}
+
+// See [PROTOCOL.agent], section 4.7
+const agentExtension = 27
+const agentExtensionFailure = 28
+
+// ErrExtensionUnsupported indicates that an extension defined in
+// [PROTOCOL.agent] section 4.7 is unsupported by the agent. Specifically this
+// error indicates that the agent returned a standard SSH_AGENT_FAILURE message
+// as the result of a SSH_AGENTC_EXTENSION request. Note that the protocol
+// specification (and therefore this error) does not distinguish between a
+// specific extension being unsupported and extensions being unsupported entirely.
+var ErrExtensionUnsupported = errors.New("agent: extension unsupported")
+
+type extensionAgentMsg struct {
+	ExtensionType string `sshtype:"27"`
+	Contents      []byte
+}
+
+// Key represents a protocol 2 public key as defined in
+// [PROTOCOL.agent], section 2.5.2.
+type Key struct {
+	Format  string
+	Blob    []byte
+	Comment string
+}
+
+func clientErr(err error) error {
+	return fmt.Errorf("agent: client error: %v", err)
+}
+
+// String returns the storage form of an agent key with the format, base64
+// encoded serialized key, and the comment if it is not empty.
+func (k *Key) String() string {
+	s := string(k.Format) + " " + base64.StdEncoding.EncodeToString(k.Blob)
+
+	if k.Comment != "" {
+		s += " " + k.Comment
+	}
+
+	return s
+}
+
+// Type returns the public key type.
+func (k *Key) Type() string {
+	return k.Format
+}
+
+// Marshal returns key blob to satisfy the ssh.PublicKey interface.
+func (k *Key) Marshal() []byte {
+	return k.Blob
+}
+
+// Verify satisfies the ssh.PublicKey interface.
+func (k *Key) Verify(data []byte, sig *ssh.Signature) error {
+	pubKey, err := ssh.ParsePublicKey(k.Blob)
+	if err != nil {
+		return fmt.Errorf("agent: bad public key: %v", err)
+	}
+	return pubKey.Verify(data, sig)
+}
+
+type wireKey struct {
+	Format string
+	Rest   []byte `ssh:"rest"`
+}
+
+func parseKey(in []byte) (out *Key, rest []byte, err error) {
+	var record struct {
+		Blob    []byte
+		Comment string
+		Rest    []byte `ssh:"rest"`
+	}
+
+	if err := ssh.Unmarshal(in, &record); err != nil {
+		return nil, nil, err
+	}
+
+	var wk wireKey
+	if err := ssh.Unmarshal(record.Blob, &wk); err != nil {
+		return nil, nil, err
+	}
+
+	return &Key{
+		Format:  wk.Format,
+		Blob:    record.Blob,
+		Comment: record.Comment,
+	}, record.Rest, nil
+}
+
+// client is a client for an ssh-agent process.
+type client struct {
+	// conn is typically a *net.UnixConn
+	conn io.ReadWriter
+	// mu is used to prevent concurrent access to the agent
+	mu sync.Mutex
+}
+
+// NewClient returns an Agent that talks to an ssh-agent process over
+// the given connection.
+func NewClient(rw io.ReadWriter) ExtendedAgent {
+	return &client{conn: rw}
+}
+
+// call sends an RPC to the agent. On success, the reply is
+// unmarshaled into reply and replyType is set to the first byte of
+// the reply, which contains the type of the message.
+func (c *client) call(req []byte) (reply interface{}, err error) {
+	buf, err := c.callRaw(req)
+	if err != nil {
+		return nil, err
+	}
+	reply, err = unmarshal(buf)
+	if err != nil {
+		return nil, clientErr(err)
+	}
+	return reply, nil
+}
+
+// callRaw sends an RPC to the agent. On success, the raw
+// bytes of the response are returned; no unmarshalling is
+// performed on the response.
+func (c *client) callRaw(req []byte) (reply []byte, err error) {
+	c.mu.Lock()
+	defer c.mu.Unlock()
+
+	msg := make([]byte, 4+len(req))
+	binary.BigEndian.PutUint32(msg, uint32(len(req)))
+	copy(msg[4:], req)
+	if _, err = c.conn.Write(msg); err != nil {
+		return nil, clientErr(err)
+	}
+
+	var respSizeBuf [4]byte
+	if _, err = io.ReadFull(c.conn, respSizeBuf[:]); err != nil {
+		return nil, clientErr(err)
+	}
+	respSize := binary.BigEndian.Uint32(respSizeBuf[:])
+	if respSize > maxAgentResponseBytes {
+		return nil, clientErr(errors.New("response too large"))
+	}
+
+	buf := make([]byte, respSize)
+	if _, err = io.ReadFull(c.conn, buf); err != nil {
+		return nil, clientErr(err)
+	}
+	return buf, nil
+}
+
+func (c *client) simpleCall(req []byte) error {
+	resp, err := c.call(req)
+	if err != nil {
+		return err
+	}
+	if _, ok := resp.(*successAgentMsg); ok {
+		return nil
+	}
+	return errors.New("agent: failure")
+}
+
+func (c *client) RemoveAll() error {
+	return c.simpleCall([]byte{agentRemoveAllIdentities})
+}
+
+func (c *client) Remove(key ssh.PublicKey) error {
+	req := ssh.Marshal(&agentRemoveIdentityMsg{
+		KeyBlob: key.Marshal(),
+	})
+	return c.simpleCall(req)
+}
+
+func (c *client) Lock(passphrase []byte) error {
+	req := ssh.Marshal(&agentLockMsg{
+		Passphrase: passphrase,
+	})
+	return c.simpleCall(req)
+}
+
+func (c *client) Unlock(passphrase []byte) error {
+	req := ssh.Marshal(&agentUnlockMsg{
+		Passphrase: passphrase,
+	})
+	return c.simpleCall(req)
+}
+
+// List returns the identities known to the agent.
+func (c *client) List() ([]*Key, error) {
+	// see [PROTOCOL.agent] section 2.5.2.
+	req := []byte{agentRequestIdentities}
+
+	msg, err := c.call(req)
+	if err != nil {
+		return nil, err
+	}
+
+	switch msg := msg.(type) {
+	case *identitiesAnswerAgentMsg:
+		if msg.NumKeys > maxAgentResponseBytes/8 {
+			return nil, errors.New("agent: too many keys in agent reply")
+		}
+		keys := make([]*Key, msg.NumKeys)
+		data := msg.Keys
+		for i := uint32(0); i < msg.NumKeys; i++ {
+			var key *Key
+			var err error
+			if key, data, err = parseKey(data); err != nil {
+				return nil, err
+			}
+			keys[i] = key
+		}
+		return keys, nil
+	case *failureAgentMsg:
+		return nil, errors.New("agent: failed to list keys")
+	}
+	panic("unreachable")
+}
+
+// Sign has the agent sign the data using a protocol 2 key as defined
+// in [PROTOCOL.agent] section 2.6.2.
+func (c *client) Sign(key ssh.PublicKey, data []byte) (*ssh.Signature, error) {
+	return c.SignWithFlags(key, data, 0)
+}
+
+func (c *client) SignWithFlags(key ssh.PublicKey, data []byte, flags SignatureFlags) (*ssh.Signature, error) {
+	req := ssh.Marshal(signRequestAgentMsg{
+		KeyBlob: key.Marshal(),
+		Data:    data,
+		Flags:   uint32(flags),
+	})
+
+	msg, err := c.call(req)
+	if err != nil {
+		return nil, err
+	}
+
+	switch msg := msg.(type) {
+	case *signResponseAgentMsg:
+		var sig ssh.Signature
+		if err := ssh.Unmarshal(msg.SigBlob, &sig); err != nil {
+			return nil, err
+		}
+
+		return &sig, nil
+	case *failureAgentMsg:
+		return nil, errors.New("agent: failed to sign challenge")
+	}
+	panic("unreachable")
+}
+
+// unmarshal parses an agent message in packet, returning the parsed
+// form and the message type of packet.
+func unmarshal(packet []byte) (interface{}, error) {
+	if len(packet) < 1 {
+		return nil, errors.New("agent: empty packet")
+	}
+	var msg interface{}
+	switch packet[0] {
+	case agentFailure:
+		return new(failureAgentMsg), nil
+	case agentSuccess:
+		return new(successAgentMsg), nil
+	case agentIdentitiesAnswer:
+		msg = new(identitiesAnswerAgentMsg)
+	case agentSignResponse:
+		msg = new(signResponseAgentMsg)
+	case agentV1IdentitiesAnswer:
+		msg = new(agentV1IdentityMsg)
+	default:
+		return nil, fmt.Errorf("agent: unknown type tag %d", packet[0])
+	}
+	if err := ssh.Unmarshal(packet, msg); err != nil {
+		return nil, err
+	}
+	return msg, nil
+}
+
+type rsaKeyMsg struct {
+	Type        string `sshtype:"17|25"`
+	N           *big.Int
+	E           *big.Int
+	D           *big.Int
+	Iqmp        *big.Int // IQMP = Inverse Q Mod P
+	P           *big.Int
+	Q           *big.Int
+	Comments    string
+	Constraints []byte `ssh:"rest"`
+}
+
+type dsaKeyMsg struct {
+	Type        string `sshtype:"17|25"`
+	P           *big.Int
+	Q           *big.Int
+	G           *big.Int
+	Y           *big.Int
+	X           *big.Int
+	Comments    string
+	Constraints []byte `ssh:"rest"`
+}
+
+type ecdsaKeyMsg struct {
+	Type        string `sshtype:"17|25"`
+	Curve       string
+	KeyBytes    []byte
+	D           *big.Int
+	Comments    string
+	Constraints []byte `ssh:"rest"`
+}
+
+type ed25519KeyMsg struct {
+	Type        string `sshtype:"17|25"`
+	Pub         []byte
+	Priv        []byte
+	Comments    string
+	Constraints []byte `ssh:"rest"`
+}
+
+// Insert adds a private key to the agent.
+func (c *client) insertKey(s interface{}, comment string, constraints []byte) error {
+	var req []byte
+	switch k := s.(type) {
+	case *rsa.PrivateKey:
+		if len(k.Primes) != 2 {
+			return fmt.Errorf("agent: unsupported RSA key with %d primes", len(k.Primes))
+		}
+		k.Precompute()
+		req = ssh.Marshal(rsaKeyMsg{
+			Type:        ssh.KeyAlgoRSA,
+			N:           k.N,
+			E:           big.NewInt(int64(k.E)),
+			D:           k.D,
+			Iqmp:        k.Precomputed.Qinv,
+			P:           k.Primes[0],
+			Q:           k.Primes[1],
+			Comments:    comment,
+			Constraints: constraints,
+		})
+	case *dsa.PrivateKey:
+		req = ssh.Marshal(dsaKeyMsg{
+			Type:        ssh.KeyAlgoDSA,
+			P:           k.P,
+			Q:           k.Q,
+			G:           k.G,
+			Y:           k.Y,
+			X:           k.X,
+			Comments:    comment,
+			Constraints: constraints,
+		})
+	case *ecdsa.PrivateKey:
+		nistID := fmt.Sprintf("nistp%d", k.Params().BitSize)
+		req = ssh.Marshal(ecdsaKeyMsg{
+			Type:        "ecdsa-sha2-" + nistID,
+			Curve:       nistID,
+			KeyBytes:    elliptic.Marshal(k.Curve, k.X, k.Y),
+			D:           k.D,
+			Comments:    comment,
+			Constraints: constraints,
+		})
+	case ed25519.PrivateKey:
+		req = ssh.Marshal(ed25519KeyMsg{
+			Type:        ssh.KeyAlgoED25519,
+			Pub:         []byte(k)[32:],
+			Priv:        []byte(k),
+			Comments:    comment,
+			Constraints: constraints,
+		})
+	// This function originally supported only *ed25519.PrivateKey, however the
+	// general idiom is to pass ed25519.PrivateKey by value, not by pointer.
+	// We still support the pointer variant for backwards compatibility.
+	case *ed25519.PrivateKey:
+		req = ssh.Marshal(ed25519KeyMsg{
+			Type:        ssh.KeyAlgoED25519,
+			Pub:         []byte(*k)[32:],
+			Priv:        []byte(*k),
+			Comments:    comment,
+			Constraints: constraints,
+		})
+	default:
+		return fmt.Errorf("agent: unsupported key type %T", s)
+	}
+
+	// if constraints are present then the message type needs to be changed.
+	if len(constraints) != 0 {
+		req[0] = agentAddIDConstrained
+	}
+
+	resp, err := c.call(req)
+	if err != nil {
+		return err
+	}
+	if _, ok := resp.(*successAgentMsg); ok {
+		return nil
+	}
+	return errors.New("agent: failure")
+}
+
+type rsaCertMsg struct {
+	Type        string `sshtype:"17|25"`
+	CertBytes   []byte
+	D           *big.Int
+	Iqmp        *big.Int // IQMP = Inverse Q Mod P
+	P           *big.Int
+	Q           *big.Int
+	Comments    string
+	Constraints []byte `ssh:"rest"`
+}
+
+type dsaCertMsg struct {
+	Type        string `sshtype:"17|25"`
+	CertBytes   []byte
+	X           *big.Int
+	Comments    string
+	Constraints []byte `ssh:"rest"`
+}
+
+type ecdsaCertMsg struct {
+	Type        string `sshtype:"17|25"`
+	CertBytes   []byte
+	D           *big.Int
+	Comments    string
+	Constraints []byte `ssh:"rest"`
+}
+
+type ed25519CertMsg struct {
+	Type        string `sshtype:"17|25"`
+	CertBytes   []byte
+	Pub         []byte
+	Priv        []byte
+	Comments    string
+	Constraints []byte `ssh:"rest"`
+}
+
+// Add adds a private key to the agent. If a certificate is given,
+// that certificate is added instead as public key.
+func (c *client) Add(key AddedKey) error {
+	var constraints []byte
+
+	if secs := key.LifetimeSecs; secs != 0 {
+		constraints = append(constraints, ssh.Marshal(constrainLifetimeAgentMsg{secs})...)
+	}
+
+	if key.ConfirmBeforeUse {
+		constraints = append(constraints, agentConstrainConfirm)
+	}
+
+	cert := key.Certificate
+	if cert == nil {
+		return c.insertKey(key.PrivateKey, key.Comment, constraints)
+	}
+	return c.insertCert(key.PrivateKey, cert, key.Comment, constraints)
+}
+
+func (c *client) insertCert(s interface{}, cert *ssh.Certificate, comment string, constraints []byte) error {
+	var req []byte
+	switch k := s.(type) {
+	case *rsa.PrivateKey:
+		if len(k.Primes) != 2 {
+			return fmt.Errorf("agent: unsupported RSA key with %d primes", len(k.Primes))
+		}
+		k.Precompute()
+		req = ssh.Marshal(rsaCertMsg{
+			Type:        cert.Type(),
+			CertBytes:   cert.Marshal(),
+			D:           k.D,
+			Iqmp:        k.Precomputed.Qinv,
+			P:           k.Primes[0],
+			Q:           k.Primes[1],
+			Comments:    comment,
+			Constraints: constraints,
+		})
+	case *dsa.PrivateKey:
+		req = ssh.Marshal(dsaCertMsg{
+			Type:        cert.Type(),
+			CertBytes:   cert.Marshal(),
+			X:           k.X,
+			Comments:    comment,
+			Constraints: constraints,
+		})
+	case *ecdsa.PrivateKey:
+		req = ssh.Marshal(ecdsaCertMsg{
+			Type:        cert.Type(),
+			CertBytes:   cert.Marshal(),
+			D:           k.D,
+			Comments:    comment,
+			Constraints: constraints,
+		})
+	case ed25519.PrivateKey:
+		req = ssh.Marshal(ed25519CertMsg{
+			Type:        cert.Type(),
+			CertBytes:   cert.Marshal(),
+			Pub:         []byte(k)[32:],
+			Priv:        []byte(k),
+			Comments:    comment,
+			Constraints: constraints,
+		})
+	// This function originally supported only *ed25519.PrivateKey, however the
+	// general idiom is to pass ed25519.PrivateKey by value, not by pointer.
+	// We still support the pointer variant for backwards compatibility.
+	case *ed25519.PrivateKey:
+		req = ssh.Marshal(ed25519CertMsg{
+			Type:        cert.Type(),
+			CertBytes:   cert.Marshal(),
+			Pub:         []byte(*k)[32:],
+			Priv:        []byte(*k),
+			Comments:    comment,
+			Constraints: constraints,
+		})
+	default:
+		return fmt.Errorf("agent: unsupported key type %T", s)
+	}
+
+	// if constraints are present then the message type needs to be changed.
+	if len(constraints) != 0 {
+		req[0] = agentAddIDConstrained
+	}
+
+	signer, err := ssh.NewSignerFromKey(s)
+	if err != nil {
+		return err
+	}
+	if bytes.Compare(cert.Key.Marshal(), signer.PublicKey().Marshal()) != 0 {
+		return errors.New("agent: signer and cert have different public key")
+	}
+
+	resp, err := c.call(req)
+	if err != nil {
+		return err
+	}
+	if _, ok := resp.(*successAgentMsg); ok {
+		return nil
+	}
+	return errors.New("agent: failure")
+}
+
+// Signers provides a callback for client authentication.
+func (c *client) Signers() ([]ssh.Signer, error) {
+	keys, err := c.List()
+	if err != nil {
+		return nil, err
+	}
+
+	var result []ssh.Signer
+	for _, k := range keys {
+		result = append(result, &agentKeyringSigner{c, k})
+	}
+	return result, nil
+}
+
+type agentKeyringSigner struct {
+	agent *client
+	pub   ssh.PublicKey
+}
+
+func (s *agentKeyringSigner) PublicKey() ssh.PublicKey {
+	return s.pub
+}
+
+func (s *agentKeyringSigner) Sign(rand io.Reader, data []byte) (*ssh.Signature, error) {
+	// The agent has its own entropy source, so the rand argument is ignored.
+	return s.agent.Sign(s.pub, data)
+}
+
+func (s *agentKeyringSigner) SignWithAlgorithm(rand io.Reader, data []byte, algorithm string) (*ssh.Signature, error) {
+	if algorithm == "" || algorithm == s.pub.Type() {
+		return s.Sign(rand, data)
+	}
+
+	var flags SignatureFlags
+	switch algorithm {
+	case ssh.KeyAlgoRSASHA256:
+		flags = SignatureFlagRsaSha256
+	case ssh.KeyAlgoRSASHA512:
+		flags = SignatureFlagRsaSha512
+	default:
+		return nil, fmt.Errorf("agent: unsupported algorithm %q", algorithm)
+	}
+
+	return s.agent.SignWithFlags(s.pub, data, flags)
+}
+
+var _ ssh.AlgorithmSigner = &agentKeyringSigner{}
+
+// Calls an extension method. It is up to the agent implementation as to whether or not
+// any particular extension is supported and may always return an error. Because the
+// type of the response is up to the implementation, this returns the bytes of the
+// response and does not attempt any type of unmarshalling.
+func (c *client) Extension(extensionType string, contents []byte) ([]byte, error) {
+	req := ssh.Marshal(extensionAgentMsg{
+		ExtensionType: extensionType,
+		Contents:      contents,
+	})
+	buf, err := c.callRaw(req)
+	if err != nil {
+		return nil, err
+	}
+	if len(buf) == 0 {
+		return nil, errors.New("agent: failure; empty response")
+	}
+	// [PROTOCOL.agent] section 4.7 indicates that an SSH_AGENT_FAILURE message
+	// represents an agent that does not support the extension
+	if buf[0] == agentFailure {
+		return nil, ErrExtensionUnsupported
+	}
+	if buf[0] == agentExtensionFailure {
+		return nil, errors.New("agent: generic extension failure")
+	}
+
+	return buf, nil
+}
diff --git a/vendor/golang.org/x/crypto/ssh/agent/forward.go b/vendor/golang.org/x/crypto/ssh/agent/forward.go
new file mode 100644
index 0000000000..fd24ba900d
--- /dev/null
+++ b/vendor/golang.org/x/crypto/ssh/agent/forward.go
@@ -0,0 +1,103 @@
+// Copyright 2014 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 agent
+
+import (
+	"errors"
+	"io"
+	"net"
+	"sync"
+
+	"golang.org/x/crypto/ssh"
+)
+
+// RequestAgentForwarding sets up agent forwarding for the session.
+// ForwardToAgent or ForwardToRemote should be called to route
+// the authentication requests.
+func RequestAgentForwarding(session *ssh.Session) error {
+	ok, err := session.SendRequest("auth-agent-req@openssh.com", true, nil)
+	if err != nil {
+		return err
+	}
+	if !ok {
+		return errors.New("forwarding request denied")
+	}
+	return nil
+}
+
+// ForwardToAgent routes authentication requests to the given keyring.
+func ForwardToAgent(client *ssh.Client, keyring Agent) error {
+	channels := client.HandleChannelOpen(channelType)
+	if channels == nil {
+		return errors.New("agent: already have handler for " + channelType)
+	}
+
+	go func() {
+		for ch := range channels {
+			channel, reqs, err := ch.Accept()
+			if err != nil {
+				continue
+			}
+			go ssh.DiscardRequests(reqs)
+			go func() {
+				ServeAgent(keyring, channel)
+				channel.Close()
+			}()
+		}
+	}()
+	return nil
+}
+
+const channelType = "auth-agent@openssh.com"
+
+// ForwardToRemote routes authentication requests to the ssh-agent
+// process serving on the given unix socket.
+func ForwardToRemote(client *ssh.Client, addr string) error {
+	channels := client.HandleChannelOpen(channelType)
+	if channels == nil {
+		return errors.New("agent: already have handler for " + channelType)
+	}
+	conn, err := net.Dial("unix", addr)
+	if err != nil {
+		return err
+	}
+	conn.Close()
+
+	go func() {
+		for ch := range channels {
+			channel, reqs, err := ch.Accept()
+			if err != nil {
+				continue
+			}
+			go ssh.DiscardRequests(reqs)
+			go forwardUnixSocket(channel, addr)
+		}
+	}()
+	return nil
+}
+
+func forwardUnixSocket(channel ssh.Channel, addr string) {
+	conn, err := net.Dial("unix", addr)
+	if err != nil {
+		return
+	}
+
+	var wg sync.WaitGroup
+	wg.Add(2)
+	go func() {
+		io.Copy(conn, channel)
+		conn.(*net.UnixConn).CloseWrite()
+		wg.Done()
+	}()
+	go func() {
+		io.Copy(channel, conn)
+		channel.CloseWrite()
+		wg.Done()
+	}()
+
+	wg.Wait()
+	conn.Close()
+	channel.Close()
+}
diff --git a/vendor/golang.org/x/crypto/ssh/agent/keyring.go b/vendor/golang.org/x/crypto/ssh/agent/keyring.go
new file mode 100644
index 0000000000..21bfa870fa
--- /dev/null
+++ b/vendor/golang.org/x/crypto/ssh/agent/keyring.go
@@ -0,0 +1,241 @@
+// Copyright 2014 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 agent
+
+import (
+	"bytes"
+	"crypto/rand"
+	"crypto/subtle"
+	"errors"
+	"fmt"
+	"sync"
+	"time"
+
+	"golang.org/x/crypto/ssh"
+)
+
+type privKey struct {
+	signer  ssh.Signer
+	comment string
+	expire  *time.Time
+}
+
+type keyring struct {
+	mu   sync.Mutex
+	keys []privKey
+
+	locked     bool
+	passphrase []byte
+}
+
+var errLocked = errors.New("agent: locked")
+
+// NewKeyring returns an Agent that holds keys in memory.  It is safe
+// for concurrent use by multiple goroutines.
+func NewKeyring() Agent {
+	return &keyring{}
+}
+
+// RemoveAll removes all identities.
+func (r *keyring) RemoveAll() error {
+	r.mu.Lock()
+	defer r.mu.Unlock()
+	if r.locked {
+		return errLocked
+	}
+
+	r.keys = nil
+	return nil
+}
+
+// removeLocked does the actual key removal. The caller must already be holding the
+// keyring mutex.
+func (r *keyring) removeLocked(want []byte) error {
+	found := false
+	for i := 0; i < len(r.keys); {
+		if bytes.Equal(r.keys[i].signer.PublicKey().Marshal(), want) {
+			found = true
+			r.keys[i] = r.keys[len(r.keys)-1]
+			r.keys = r.keys[:len(r.keys)-1]
+			continue
+		} else {
+			i++
+		}
+	}
+
+	if !found {
+		return errors.New("agent: key not found")
+	}
+	return nil
+}
+
+// Remove removes all identities with the given public key.
+func (r *keyring) Remove(key ssh.PublicKey) error {
+	r.mu.Lock()
+	defer r.mu.Unlock()
+	if r.locked {
+		return errLocked
+	}
+
+	return r.removeLocked(key.Marshal())
+}
+
+// Lock locks the agent. Sign and Remove will fail, and List will return an empty list.
+func (r *keyring) Lock(passphrase []byte) error {
+	r.mu.Lock()
+	defer r.mu.Unlock()
+	if r.locked {
+		return errLocked
+	}
+
+	r.locked = true
+	r.passphrase = passphrase
+	return nil
+}
+
+// Unlock undoes the effect of Lock
+func (r *keyring) Unlock(passphrase []byte) error {
+	r.mu.Lock()
+	defer r.mu.Unlock()
+	if !r.locked {
+		return errors.New("agent: not locked")
+	}
+	if 1 != subtle.ConstantTimeCompare(passphrase, r.passphrase) {
+		return fmt.Errorf("agent: incorrect passphrase")
+	}
+
+	r.locked = false
+	r.passphrase = nil
+	return nil
+}
+
+// expireKeysLocked removes expired keys from the keyring. If a key was added
+// with a lifetimesecs contraint and seconds >= lifetimesecs seconds have
+// elapsed, it is removed. The caller *must* be holding the keyring mutex.
+func (r *keyring) expireKeysLocked() {
+	for _, k := range r.keys {
+		if k.expire != nil && time.Now().After(*k.expire) {
+			r.removeLocked(k.signer.PublicKey().Marshal())
+		}
+	}
+}
+
+// List returns the identities known to the agent.
+func (r *keyring) List() ([]*Key, error) {
+	r.mu.Lock()
+	defer r.mu.Unlock()
+	if r.locked {
+		// section 2.7: locked agents return empty.
+		return nil, nil
+	}
+
+	r.expireKeysLocked()
+	var ids []*Key
+	for _, k := range r.keys {
+		pub := k.signer.PublicKey()
+		ids = append(ids, &Key{
+			Format:  pub.Type(),
+			Blob:    pub.Marshal(),
+			Comment: k.comment})
+	}
+	return ids, nil
+}
+
+// Insert adds a private key to the keyring. If a certificate
+// is given, that certificate is added as public key. Note that
+// any constraints given are ignored.
+func (r *keyring) Add(key AddedKey) error {
+	r.mu.Lock()
+	defer r.mu.Unlock()
+	if r.locked {
+		return errLocked
+	}
+	signer, err := ssh.NewSignerFromKey(key.PrivateKey)
+
+	if err != nil {
+		return err
+	}
+
+	if cert := key.Certificate; cert != nil {
+		signer, err = ssh.NewCertSigner(cert, signer)
+		if err != nil {
+			return err
+		}
+	}
+
+	p := privKey{
+		signer:  signer,
+		comment: key.Comment,
+	}
+
+	if key.LifetimeSecs > 0 {
+		t := time.Now().Add(time.Duration(key.LifetimeSecs) * time.Second)
+		p.expire = &t
+	}
+
+	r.keys = append(r.keys, p)
+
+	return nil
+}
+
+// Sign returns a signature for the data.
+func (r *keyring) Sign(key ssh.PublicKey, data []byte) (*ssh.Signature, error) {
+	return r.SignWithFlags(key, data, 0)
+}
+
+func (r *keyring) SignWithFlags(key ssh.PublicKey, data []byte, flags SignatureFlags) (*ssh.Signature, error) {
+	r.mu.Lock()
+	defer r.mu.Unlock()
+	if r.locked {
+		return nil, errLocked
+	}
+
+	r.expireKeysLocked()
+	wanted := key.Marshal()
+	for _, k := range r.keys {
+		if bytes.Equal(k.signer.PublicKey().Marshal(), wanted) {
+			if flags == 0 {
+				return k.signer.Sign(rand.Reader, data)
+			} else {
+				if algorithmSigner, ok := k.signer.(ssh.AlgorithmSigner); !ok {
+					return nil, fmt.Errorf("agent: signature does not support non-default signature algorithm: %T", k.signer)
+				} else {
+					var algorithm string
+					switch flags {
+					case SignatureFlagRsaSha256:
+						algorithm = ssh.KeyAlgoRSASHA256
+					case SignatureFlagRsaSha512:
+						algorithm = ssh.KeyAlgoRSASHA512
+					default:
+						return nil, fmt.Errorf("agent: unsupported signature flags: %d", flags)
+					}
+					return algorithmSigner.SignWithAlgorithm(rand.Reader, data, algorithm)
+				}
+			}
+		}
+	}
+	return nil, errors.New("not found")
+}
+
+// Signers returns signers for all the known keys.
+func (r *keyring) Signers() ([]ssh.Signer, error) {
+	r.mu.Lock()
+	defer r.mu.Unlock()
+	if r.locked {
+		return nil, errLocked
+	}
+
+	r.expireKeysLocked()
+	s := make([]ssh.Signer, 0, len(r.keys))
+	for _, k := range r.keys {
+		s = append(s, k.signer)
+	}
+	return s, nil
+}
+
+// The keyring does not support any extensions
+func (r *keyring) Extension(extensionType string, contents []byte) ([]byte, error) {
+	return nil, ErrExtensionUnsupported
+}
diff --git a/vendor/golang.org/x/crypto/ssh/agent/server.go b/vendor/golang.org/x/crypto/ssh/agent/server.go
new file mode 100644
index 0000000000..6e7a1e02f2
--- /dev/null
+++ b/vendor/golang.org/x/crypto/ssh/agent/server.go
@@ -0,0 +1,570 @@
+// 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 agent
+
+import (
+	"crypto/dsa"
+	"crypto/ecdsa"
+	"crypto/elliptic"
+	"crypto/rsa"
+	"encoding/binary"
+	"errors"
+	"fmt"
+	"io"
+	"log"
+	"math/big"
+
+	"golang.org/x/crypto/ed25519"
+	"golang.org/x/crypto/ssh"
+)
+
+// Server wraps an Agent and uses it to implement the agent side of
+// the SSH-agent, wire protocol.
+type server struct {
+	agent Agent
+}
+
+func (s *server) processRequestBytes(reqData []byte) []byte {
+	rep, err := s.processRequest(reqData)
+	if err != nil {
+		if err != errLocked {
+			// TODO(hanwen): provide better logging interface?
+			log.Printf("agent %d: %v", reqData[0], err)
+		}
+		return []byte{agentFailure}
+	}
+
+	if err == nil && rep == nil {
+		return []byte{agentSuccess}
+	}
+
+	return ssh.Marshal(rep)
+}
+
+func marshalKey(k *Key) []byte {
+	var record struct {
+		Blob    []byte
+		Comment string
+	}
+	record.Blob = k.Marshal()
+	record.Comment = k.Comment
+
+	return ssh.Marshal(&record)
+}
+
+// See [PROTOCOL.agent], section 2.5.1.
+const agentV1IdentitiesAnswer = 2
+
+type agentV1IdentityMsg struct {
+	Numkeys uint32 `sshtype:"2"`
+}
+
+type agentRemoveIdentityMsg struct {
+	KeyBlob []byte `sshtype:"18"`
+}
+
+type agentLockMsg struct {
+	Passphrase []byte `sshtype:"22"`
+}
+
+type agentUnlockMsg struct {
+	Passphrase []byte `sshtype:"23"`
+}
+
+func (s *server) processRequest(data []byte) (interface{}, error) {
+	switch data[0] {
+	case agentRequestV1Identities:
+		return &agentV1IdentityMsg{0}, nil
+
+	case agentRemoveAllV1Identities:
+		return nil, nil
+
+	case agentRemoveIdentity:
+		var req agentRemoveIdentityMsg
+		if err := ssh.Unmarshal(data, &req); err != nil {
+			return nil, err
+		}
+
+		var wk wireKey
+		if err := ssh.Unmarshal(req.KeyBlob, &wk); err != nil {
+			return nil, err
+		}
+
+		return nil, s.agent.Remove(&Key{Format: wk.Format, Blob: req.KeyBlob})
+
+	case agentRemoveAllIdentities:
+		return nil, s.agent.RemoveAll()
+
+	case agentLock:
+		var req agentLockMsg
+		if err := ssh.Unmarshal(data, &req); err != nil {
+			return nil, err
+		}
+
+		return nil, s.agent.Lock(req.Passphrase)
+
+	case agentUnlock:
+		var req agentUnlockMsg
+		if err := ssh.Unmarshal(data, &req); err != nil {
+			return nil, err
+		}
+		return nil, s.agent.Unlock(req.Passphrase)
+
+	case agentSignRequest:
+		var req signRequestAgentMsg
+		if err := ssh.Unmarshal(data, &req); err != nil {
+			return nil, err
+		}
+
+		var wk wireKey
+		if err := ssh.Unmarshal(req.KeyBlob, &wk); err != nil {
+			return nil, err
+		}
+
+		k := &Key{
+			Format: wk.Format,
+			Blob:   req.KeyBlob,
+		}
+
+		var sig *ssh.Signature
+		var err error
+		if extendedAgent, ok := s.agent.(ExtendedAgent); ok {
+			sig, err = extendedAgent.SignWithFlags(k, req.Data, SignatureFlags(req.Flags))
+		} else {
+			sig, err = s.agent.Sign(k, req.Data)
+		}
+
+		if err != nil {
+			return nil, err
+		}
+		return &signResponseAgentMsg{SigBlob: ssh.Marshal(sig)}, nil
+
+	case agentRequestIdentities:
+		keys, err := s.agent.List()
+		if err != nil {
+			return nil, err
+		}
+
+		rep := identitiesAnswerAgentMsg{
+			NumKeys: uint32(len(keys)),
+		}
+		for _, k := range keys {
+			rep.Keys = append(rep.Keys, marshalKey(k)...)
+		}
+		return rep, nil
+
+	case agentAddIDConstrained, agentAddIdentity:
+		return nil, s.insertIdentity(data)
+
+	case agentExtension:
+		// Return a stub object where the whole contents of the response gets marshaled.
+		var responseStub struct {
+			Rest []byte `ssh:"rest"`
+		}
+
+		if extendedAgent, ok := s.agent.(ExtendedAgent); !ok {
+			// If this agent doesn't implement extensions, [PROTOCOL.agent] section 4.7
+			// requires that we return a standard SSH_AGENT_FAILURE message.
+			responseStub.Rest = []byte{agentFailure}
+		} else {
+			var req extensionAgentMsg
+			if err := ssh.Unmarshal(data, &req); err != nil {
+				return nil, err
+			}
+			res, err := extendedAgent.Extension(req.ExtensionType, req.Contents)
+			if err != nil {
+				// If agent extensions are unsupported, return a standard SSH_AGENT_FAILURE
+				// message as required by [PROTOCOL.agent] section 4.7.
+				if err == ErrExtensionUnsupported {
+					responseStub.Rest = []byte{agentFailure}
+				} else {
+					// As the result of any other error processing an extension request,
+					// [PROTOCOL.agent] section 4.7 requires that we return a
+					// SSH_AGENT_EXTENSION_FAILURE code.
+					responseStub.Rest = []byte{agentExtensionFailure}
+				}
+			} else {
+				if len(res) == 0 {
+					return nil, nil
+				}
+				responseStub.Rest = res
+			}
+		}
+
+		return responseStub, nil
+	}
+
+	return nil, fmt.Errorf("unknown opcode %d", data[0])
+}
+
+func parseConstraints(constraints []byte) (lifetimeSecs uint32, confirmBeforeUse bool, extensions []ConstraintExtension, err error) {
+	for len(constraints) != 0 {
+		switch constraints[0] {
+		case agentConstrainLifetime:
+			lifetimeSecs = binary.BigEndian.Uint32(constraints[1:5])
+			constraints = constraints[5:]
+		case agentConstrainConfirm:
+			confirmBeforeUse = true
+			constraints = constraints[1:]
+		case agentConstrainExtension:
+			var msg constrainExtensionAgentMsg
+			if err = ssh.Unmarshal(constraints, &msg); err != nil {
+				return 0, false, nil, err
+			}
+			extensions = append(extensions, ConstraintExtension{
+				ExtensionName:    msg.ExtensionName,
+				ExtensionDetails: msg.ExtensionDetails,
+			})
+			constraints = msg.Rest
+		default:
+			return 0, false, nil, fmt.Errorf("unknown constraint type: %d", constraints[0])
+		}
+	}
+	return
+}
+
+func setConstraints(key *AddedKey, constraintBytes []byte) error {
+	lifetimeSecs, confirmBeforeUse, constraintExtensions, err := parseConstraints(constraintBytes)
+	if err != nil {
+		return err
+	}
+
+	key.LifetimeSecs = lifetimeSecs
+	key.ConfirmBeforeUse = confirmBeforeUse
+	key.ConstraintExtensions = constraintExtensions
+	return nil
+}
+
+func parseRSAKey(req []byte) (*AddedKey, error) {
+	var k rsaKeyMsg
+	if err := ssh.Unmarshal(req, &k); err != nil {
+		return nil, err
+	}
+	if k.E.BitLen() > 30 {
+		return nil, errors.New("agent: RSA public exponent too large")
+	}
+	priv := &rsa.PrivateKey{
+		PublicKey: rsa.PublicKey{
+			E: int(k.E.Int64()),
+			N: k.N,
+		},
+		D:      k.D,
+		Primes: []*big.Int{k.P, k.Q},
+	}
+	priv.Precompute()
+
+	addedKey := &AddedKey{PrivateKey: priv, Comment: k.Comments}
+	if err := setConstraints(addedKey, k.Constraints); err != nil {
+		return nil, err
+	}
+	return addedKey, nil
+}
+
+func parseEd25519Key(req []byte) (*AddedKey, error) {
+	var k ed25519KeyMsg
+	if err := ssh.Unmarshal(req, &k); err != nil {
+		return nil, err
+	}
+	priv := ed25519.PrivateKey(k.Priv)
+
+	addedKey := &AddedKey{PrivateKey: &priv, Comment: k.Comments}
+	if err := setConstraints(addedKey, k.Constraints); err != nil {
+		return nil, err
+	}
+	return addedKey, nil
+}
+
+func parseDSAKey(req []byte) (*AddedKey, error) {
+	var k dsaKeyMsg
+	if err := ssh.Unmarshal(req, &k); err != nil {
+		return nil, err
+	}
+	priv := &dsa.PrivateKey{
+		PublicKey: dsa.PublicKey{
+			Parameters: dsa.Parameters{
+				P: k.P,
+				Q: k.Q,
+				G: k.G,
+			},
+			Y: k.Y,
+		},
+		X: k.X,
+	}
+
+	addedKey := &AddedKey{PrivateKey: priv, Comment: k.Comments}
+	if err := setConstraints(addedKey, k.Constraints); err != nil {
+		return nil, err
+	}
+	return addedKey, nil
+}
+
+func unmarshalECDSA(curveName string, keyBytes []byte, privScalar *big.Int) (priv *ecdsa.PrivateKey, err error) {
+	priv = &ecdsa.PrivateKey{
+		D: privScalar,
+	}
+
+	switch curveName {
+	case "nistp256":
+		priv.Curve = elliptic.P256()
+	case "nistp384":
+		priv.Curve = elliptic.P384()
+	case "nistp521":
+		priv.Curve = elliptic.P521()
+	default:
+		return nil, fmt.Errorf("agent: unknown curve %q", curveName)
+	}
+
+	priv.X, priv.Y = elliptic.Unmarshal(priv.Curve, keyBytes)
+	if priv.X == nil || priv.Y == nil {
+		return nil, errors.New("agent: point not on curve")
+	}
+
+	return priv, nil
+}
+
+func parseEd25519Cert(req []byte) (*AddedKey, error) {
+	var k ed25519CertMsg
+	if err := ssh.Unmarshal(req, &k); err != nil {
+		return nil, err
+	}
+	pubKey, err := ssh.ParsePublicKey(k.CertBytes)
+	if err != nil {
+		return nil, err
+	}
+	priv := ed25519.PrivateKey(k.Priv)
+	cert, ok := pubKey.(*ssh.Certificate)
+	if !ok {
+		return nil, errors.New("agent: bad ED25519 certificate")
+	}
+
+	addedKey := &AddedKey{PrivateKey: &priv, Certificate: cert, Comment: k.Comments}
+	if err := setConstraints(addedKey, k.Constraints); err != nil {
+		return nil, err
+	}
+	return addedKey, nil
+}
+
+func parseECDSAKey(req []byte) (*AddedKey, error) {
+	var k ecdsaKeyMsg
+	if err := ssh.Unmarshal(req, &k); err != nil {
+		return nil, err
+	}
+
+	priv, err := unmarshalECDSA(k.Curve, k.KeyBytes, k.D)
+	if err != nil {
+		return nil, err
+	}
+
+	addedKey := &AddedKey{PrivateKey: priv, Comment: k.Comments}
+	if err := setConstraints(addedKey, k.Constraints); err != nil {
+		return nil, err
+	}
+	return addedKey, nil
+}
+
+func parseRSACert(req []byte) (*AddedKey, error) {
+	var k rsaCertMsg
+	if err := ssh.Unmarshal(req, &k); err != nil {
+		return nil, err
+	}
+
+	pubKey, err := ssh.ParsePublicKey(k.CertBytes)
+	if err != nil {
+		return nil, err
+	}
+
+	cert, ok := pubKey.(*ssh.Certificate)
+	if !ok {
+		return nil, errors.New("agent: bad RSA certificate")
+	}
+
+	// An RSA publickey as marshaled by rsaPublicKey.Marshal() in keys.go
+	var rsaPub struct {
+		Name string
+		E    *big.Int
+		N    *big.Int
+	}
+	if err := ssh.Unmarshal(cert.Key.Marshal(), &rsaPub); err != nil {
+		return nil, fmt.Errorf("agent: Unmarshal failed to parse public key: %v", err)
+	}
+
+	if rsaPub.E.BitLen() > 30 {
+		return nil, errors.New("agent: RSA public exponent too large")
+	}
+
+	priv := rsa.PrivateKey{
+		PublicKey: rsa.PublicKey{
+			E: int(rsaPub.E.Int64()),
+			N: rsaPub.N,
+		},
+		D:      k.D,
+		Primes: []*big.Int{k.Q, k.P},
+	}
+	priv.Precompute()
+
+	addedKey := &AddedKey{PrivateKey: &priv, Certificate: cert, Comment: k.Comments}
+	if err := setConstraints(addedKey, k.Constraints); err != nil {
+		return nil, err
+	}
+	return addedKey, nil
+}
+
+func parseDSACert(req []byte) (*AddedKey, error) {
+	var k dsaCertMsg
+	if err := ssh.Unmarshal(req, &k); err != nil {
+		return nil, err
+	}
+	pubKey, err := ssh.ParsePublicKey(k.CertBytes)
+	if err != nil {
+		return nil, err
+	}
+	cert, ok := pubKey.(*ssh.Certificate)
+	if !ok {
+		return nil, errors.New("agent: bad DSA certificate")
+	}
+
+	// A DSA publickey as marshaled by dsaPublicKey.Marshal() in keys.go
+	var w struct {
+		Name       string
+		P, Q, G, Y *big.Int
+	}
+	if err := ssh.Unmarshal(cert.Key.Marshal(), &w); err != nil {
+		return nil, fmt.Errorf("agent: Unmarshal failed to parse public key: %v", err)
+	}
+
+	priv := &dsa.PrivateKey{
+		PublicKey: dsa.PublicKey{
+			Parameters: dsa.Parameters{
+				P: w.P,
+				Q: w.Q,
+				G: w.G,
+			},
+			Y: w.Y,
+		},
+		X: k.X,
+	}
+
+	addedKey := &AddedKey{PrivateKey: priv, Certificate: cert, Comment: k.Comments}
+	if err := setConstraints(addedKey, k.Constraints); err != nil {
+		return nil, err
+	}
+	return addedKey, nil
+}
+
+func parseECDSACert(req []byte) (*AddedKey, error) {
+	var k ecdsaCertMsg
+	if err := ssh.Unmarshal(req, &k); err != nil {
+		return nil, err
+	}
+
+	pubKey, err := ssh.ParsePublicKey(k.CertBytes)
+	if err != nil {
+		return nil, err
+	}
+	cert, ok := pubKey.(*ssh.Certificate)
+	if !ok {
+		return nil, errors.New("agent: bad ECDSA certificate")
+	}
+
+	// An ECDSA publickey as marshaled by ecdsaPublicKey.Marshal() in keys.go
+	var ecdsaPub struct {
+		Name string
+		ID   string
+		Key  []byte
+	}
+	if err := ssh.Unmarshal(cert.Key.Marshal(), &ecdsaPub); err != nil {
+		return nil, err
+	}
+
+	priv, err := unmarshalECDSA(ecdsaPub.ID, ecdsaPub.Key, k.D)
+	if err != nil {
+		return nil, err
+	}
+
+	addedKey := &AddedKey{PrivateKey: priv, Certificate: cert, Comment: k.Comments}
+	if err := setConstraints(addedKey, k.Constraints); err != nil {
+		return nil, err
+	}
+	return addedKey, nil
+}
+
+func (s *server) insertIdentity(req []byte) error {
+	var record struct {
+		Type string `sshtype:"17|25"`
+		Rest []byte `ssh:"rest"`
+	}
+
+	if err := ssh.Unmarshal(req, &record); err != nil {
+		return err
+	}
+
+	var addedKey *AddedKey
+	var err error
+
+	switch record.Type {
+	case ssh.KeyAlgoRSA:
+		addedKey, err = parseRSAKey(req)
+	case ssh.KeyAlgoDSA:
+		addedKey, err = parseDSAKey(req)
+	case ssh.KeyAlgoECDSA256, ssh.KeyAlgoECDSA384, ssh.KeyAlgoECDSA521:
+		addedKey, err = parseECDSAKey(req)
+	case ssh.KeyAlgoED25519:
+		addedKey, err = parseEd25519Key(req)
+	case ssh.CertAlgoRSAv01:
+		addedKey, err = parseRSACert(req)
+	case ssh.CertAlgoDSAv01:
+		addedKey, err = parseDSACert(req)
+	case ssh.CertAlgoECDSA256v01, ssh.CertAlgoECDSA384v01, ssh.CertAlgoECDSA521v01:
+		addedKey, err = parseECDSACert(req)
+	case ssh.CertAlgoED25519v01:
+		addedKey, err = parseEd25519Cert(req)
+	default:
+		return fmt.Errorf("agent: not implemented: %q", record.Type)
+	}
+
+	if err != nil {
+		return err
+	}
+	return s.agent.Add(*addedKey)
+}
+
+// ServeAgent serves the agent protocol on the given connection. It
+// returns when an I/O error occurs.
+func ServeAgent(agent Agent, c io.ReadWriter) error {
+	s := &server{agent}
+
+	var length [4]byte
+	for {
+		if _, err := io.ReadFull(c, length[:]); err != nil {
+			return err
+		}
+		l := binary.BigEndian.Uint32(length[:])
+		if l == 0 {
+			return fmt.Errorf("agent: request size is 0")
+		}
+		if l > maxAgentResponseBytes {
+			// We also cap requests.
+			return fmt.Errorf("agent: request too large: %d", l)
+		}
+
+		req := make([]byte, l)
+		if _, err := io.ReadFull(c, req); err != nil {
+			return err
+		}
+
+		repData := s.processRequestBytes(req)
+		if len(repData) > maxAgentResponseBytes {
+			return fmt.Errorf("agent: reply too large: %d bytes", len(repData))
+		}
+
+		binary.BigEndian.PutUint32(length[:], uint32(len(repData)))
+		if _, err := c.Write(length[:]); err != nil {
+			return err
+		}
+		if _, err := c.Write(repData); err != nil {
+			return err
+		}
+	}
+}
diff --git a/vendor/golang.org/x/crypto/ssh/certs.go b/vendor/golang.org/x/crypto/ssh/certs.go
index 916c840b69..a69e22491d 100644
--- a/vendor/golang.org/x/crypto/ssh/certs.go
+++ b/vendor/golang.org/x/crypto/ssh/certs.go
@@ -14,8 +14,10 @@ import (
 	"time"
 )
 
-// These constants from [PROTOCOL.certkeys] represent the algorithm names
-// for certificate types supported by this package.
+// Certificate algorithm names from [PROTOCOL.certkeys]. These values can appear
+// in Certificate.Type, PublicKey.Type, and ClientConfig.HostKeyAlgorithms.
+// Unlike key algorithm names, these are not passed to AlgorithmSigner and don't
+// appear in the Signature.Format field.
 const (
 	CertAlgoRSAv01        = "ssh-rsa-cert-v01@openssh.com"
 	CertAlgoDSAv01        = "ssh-dss-cert-v01@openssh.com"
@@ -25,6 +27,21 @@ const (
 	CertAlgoSKECDSA256v01 = "sk-ecdsa-sha2-nistp256-cert-v01@openssh.com"
 	CertAlgoED25519v01    = "ssh-ed25519-cert-v01@openssh.com"
 	CertAlgoSKED25519v01  = "sk-ssh-ed25519-cert-v01@openssh.com"
+
+	// CertAlgoRSASHA256v01 and CertAlgoRSASHA512v01 can't appear as a
+	// Certificate.Type (or PublicKey.Type), but only in
+	// ClientConfig.HostKeyAlgorithms.
+	CertAlgoRSASHA256v01 = "rsa-sha2-256-cert-v01@openssh.com"
+	CertAlgoRSASHA512v01 = "rsa-sha2-512-cert-v01@openssh.com"
+)
+
+const (
+	// Deprecated: use CertAlgoRSAv01.
+	CertSigAlgoRSAv01 = CertAlgoRSAv01
+	// Deprecated: use CertAlgoRSASHA256v01.
+	CertSigAlgoRSASHA2256v01 = CertAlgoRSASHA256v01
+	// Deprecated: use CertAlgoRSASHA512v01.
+	CertSigAlgoRSASHA2512v01 = CertAlgoRSASHA512v01
 )
 
 // Certificate types distinguish between host and user
@@ -423,6 +440,16 @@ func (c *Certificate) SignCert(rand io.Reader, authority Signer) error {
 	}
 	c.SignatureKey = authority.PublicKey()
 
+	// Default to KeyAlgoRSASHA512 for ssh-rsa signers.
+	if v, ok := authority.(AlgorithmSigner); ok && v.PublicKey().Type() == KeyAlgoRSA {
+		sig, err := v.SignWithAlgorithm(rand, c.bytesForSigning(), KeyAlgoRSASHA512)
+		if err != nil {
+			return err
+		}
+		c.Signature = sig
+		return nil
+	}
+
 	sig, err := authority.Sign(rand, c.bytesForSigning())
 	if err != nil {
 		return err
@@ -431,26 +458,40 @@ func (c *Certificate) SignCert(rand io.Reader, authority Signer) error {
 	return nil
 }
 
-var certAlgoNames = map[string]string{
-	KeyAlgoRSA:        CertAlgoRSAv01,
-	KeyAlgoDSA:        CertAlgoDSAv01,
-	KeyAlgoECDSA256:   CertAlgoECDSA256v01,
-	KeyAlgoECDSA384:   CertAlgoECDSA384v01,
-	KeyAlgoECDSA521:   CertAlgoECDSA521v01,
-	KeyAlgoSKECDSA256: CertAlgoSKECDSA256v01,
-	KeyAlgoED25519:    CertAlgoED25519v01,
-	KeyAlgoSKED25519:  CertAlgoSKED25519v01,
+// certKeyAlgoNames is a mapping from known certificate algorithm names to the
+// corresponding public key signature algorithm.
+var certKeyAlgoNames = map[string]string{
+	CertAlgoRSAv01:        KeyAlgoRSA,
+	CertAlgoRSASHA256v01:  KeyAlgoRSASHA256,
+	CertAlgoRSASHA512v01:  KeyAlgoRSASHA512,
+	CertAlgoDSAv01:        KeyAlgoDSA,
+	CertAlgoECDSA256v01:   KeyAlgoECDSA256,
+	CertAlgoECDSA384v01:   KeyAlgoECDSA384,
+	CertAlgoECDSA521v01:   KeyAlgoECDSA521,
+	CertAlgoSKECDSA256v01: KeyAlgoSKECDSA256,
+	CertAlgoED25519v01:    KeyAlgoED25519,
+	CertAlgoSKED25519v01:  KeyAlgoSKED25519,
 }
 
-// certToPrivAlgo returns the underlying algorithm for a certificate algorithm.
-// Panics if a non-certificate algorithm is passed.
-func certToPrivAlgo(algo string) string {
-	for privAlgo, pubAlgo := range certAlgoNames {
-		if pubAlgo == algo {
-			return privAlgo
+// underlyingAlgo returns the signature algorithm associated with algo (which is
+// an advertised or negotiated public key or host key algorithm). These are
+// usually the same, except for certificate algorithms.
+func underlyingAlgo(algo string) string {
+	if a, ok := certKeyAlgoNames[algo]; ok {
+		return a
+	}
+	return algo
+}
+
+// certificateAlgo returns the certificate algorithms that uses the provided
+// underlying signature algorithm.
+func certificateAlgo(algo string) (certAlgo string, ok bool) {
+	for certName, algoName := range certKeyAlgoNames {
+		if algoName == algo {
+			return certName, true
 		}
 	}
-	panic("unknown cert algorithm")
+	return "", false
 }
 
 func (cert *Certificate) bytesForSigning() []byte {
@@ -494,13 +535,13 @@ func (c *Certificate) Marshal() []byte {
 	return result
 }
 
-// Type returns the key name. It is part of the PublicKey interface.
+// Type returns the certificate algorithm name. It is part of the PublicKey interface.
 func (c *Certificate) Type() string {
-	algo, ok := certAlgoNames[c.Key.Type()]
+	certName, ok := certificateAlgo(c.Key.Type())
 	if !ok {
-		panic("unknown cert key type " + c.Key.Type())
+		panic("unknown certificate type for key type " + c.Key.Type())
 	}
-	return algo
+	return certName
 }
 
 // Verify verifies a signature against the certificate's public
diff --git a/vendor/golang.org/x/crypto/ssh/cipher.go b/vendor/golang.org/x/crypto/ssh/cipher.go
index 8bd6b3daff..f8bdf4984c 100644
--- a/vendor/golang.org/x/crypto/ssh/cipher.go
+++ b/vendor/golang.org/x/crypto/ssh/cipher.go
@@ -18,7 +18,7 @@ import (
 	"io/ioutil"
 
 	"golang.org/x/crypto/chacha20"
-	"golang.org/x/crypto/poly1305"
+	"golang.org/x/crypto/internal/poly1305"
 )
 
 const (
@@ -394,6 +394,10 @@ func (c *gcmCipher) readCipherPacket(seqNum uint32, r io.Reader) ([]byte, error)
 	}
 	c.incIV()
 
+	if len(plain) == 0 {
+		return nil, errors.New("ssh: empty packet")
+	}
+
 	padding := plain[0]
 	if padding < 4 {
 		// padding is a byte, so it automatically satisfies
@@ -710,6 +714,10 @@ func (c *chacha20Poly1305Cipher) readCipherPacket(seqNum uint32, r io.Reader) ([
 	plain := c.buf[4:contentEnd]
 	s.XORKeyStream(plain, plain)
 
+	if len(plain) == 0 {
+		return nil, errors.New("ssh: empty packet")
+	}
+
 	padding := plain[0]
 	if padding < 4 {
 		// padding is a byte, so it automatically satisfies
diff --git a/vendor/golang.org/x/crypto/ssh/client.go b/vendor/golang.org/x/crypto/ssh/client.go
index 7b00bff1ca..bdc356cbdf 100644
--- a/vendor/golang.org/x/crypto/ssh/client.go
+++ b/vendor/golang.org/x/crypto/ssh/client.go
@@ -77,7 +77,7 @@ func NewClientConn(c net.Conn, addr string, config *ClientConfig) (Conn, <-chan
 	}
 
 	conn := &connection{
-		sshConn: sshConn{conn: c},
+		sshConn: sshConn{conn: c, user: fullConf.User},
 	}
 
 	if err := conn.clientHandshake(addr, &fullConf); err != nil {
@@ -113,14 +113,18 @@ func (c *connection) clientHandshake(dialAddress string, config *ClientConfig) e
 	return c.clientAuthenticate(config)
 }
 
-// verifyHostKeySignature verifies the host key obtained in the key
-// exchange.
-func verifyHostKeySignature(hostKey PublicKey, result *kexResult) error {
+// verifyHostKeySignature verifies the host key obtained in the key exchange.
+// algo is the negotiated algorithm, and may be a certificate type.
+func verifyHostKeySignature(hostKey PublicKey, algo string, result *kexResult) error {
 	sig, rest, ok := parseSignatureBody(result.Signature)
 	if len(rest) > 0 || !ok {
 		return errors.New("ssh: signature parse error")
 	}
 
+	if a := underlyingAlgo(algo); sig.Format != a {
+		return fmt.Errorf("ssh: invalid signature algorithm %q, expected %q", sig.Format, a)
+	}
+
 	return hostKey.Verify(result.H, sig)
 }
 
@@ -224,11 +228,11 @@ type ClientConfig struct {
 	// be used for the connection. If empty, a reasonable default is used.
 	ClientVersion string
 
-	// HostKeyAlgorithms lists the key types that the client will
-	// accept from the server as host key, in order of
+	// HostKeyAlgorithms lists the public key algorithms that the client will
+	// accept from the server for host key authentication, in order of
 	// preference. If empty, a reasonable default is used. Any
-	// string returned from PublicKey.Type method may be used, or
-	// any of the CertAlgoXxxx and KeyAlgoXxxx constants.
+	// string returned from a PublicKey.Type method may be used, or
+	// any of the CertAlgo and KeyAlgo constants.
 	HostKeyAlgorithms []string
 
 	// Timeout is the maximum amount of time for the TCP connection to establish.
diff --git a/vendor/golang.org/x/crypto/ssh/client_auth.go b/vendor/golang.org/x/crypto/ssh/client_auth.go
index c611aeb684..409b5ea1d4 100644
--- a/vendor/golang.org/x/crypto/ssh/client_auth.go
+++ b/vendor/golang.org/x/crypto/ssh/client_auth.go
@@ -9,6 +9,7 @@ import (
 	"errors"
 	"fmt"
 	"io"
+	"strings"
 )
 
 type authResult int
@@ -29,6 +30,33 @@ func (c *connection) clientAuthenticate(config *ClientConfig) error {
 	if err != nil {
 		return err
 	}
+	// The server may choose to send a SSH_MSG_EXT_INFO at this point (if we
+	// advertised willingness to receive one, which we always do) or not. See
+	// RFC 8308, Section 2.4.
+	extensions := make(map[string][]byte)
+	if len(packet) > 0 && packet[0] == msgExtInfo {
+		var extInfo extInfoMsg
+		if err := Unmarshal(packet, &extInfo); err != nil {
+			return err
+		}
+		payload := extInfo.Payload
+		for i := uint32(0); i < extInfo.NumExtensions; i++ {
+			name, rest, ok := parseString(payload)
+			if !ok {
+				return parseError(msgExtInfo)
+			}
+			value, rest, ok := parseString(rest)
+			if !ok {
+				return parseError(msgExtInfo)
+			}
+			extensions[string(name)] = value
+			payload = rest
+		}
+		packet, err = c.transport.readPacket()
+		if err != nil {
+			return err
+		}
+	}
 	var serviceAccept serviceAcceptMsg
 	if err := Unmarshal(packet, &serviceAccept); err != nil {
 		return err
@@ -41,7 +69,7 @@ func (c *connection) clientAuthenticate(config *ClientConfig) error {
 
 	sessionID := c.transport.getSessionID()
 	for auth := AuthMethod(new(noneAuth)); auth != nil; {
-		ok, methods, err := auth.auth(sessionID, config.User, c.transport, config.Rand)
+		ok, methods, err := auth.auth(sessionID, config.User, c.transport, config.Rand, extensions)
 		if err != nil {
 			return err
 		}
@@ -93,7 +121,7 @@ type AuthMethod interface {
 	// If authentication is not successful, a []string of alternative
 	// method names is returned. If the slice is nil, it will be ignored
 	// and the previous set of possible methods will be reused.
-	auth(session []byte, user string, p packetConn, rand io.Reader) (authResult, []string, error)
+	auth(session []byte, user string, p packetConn, rand io.Reader, extensions map[string][]byte) (authResult, []string, error)
 
 	// method returns the RFC 4252 method name.
 	method() string
@@ -102,7 +130,7 @@ type AuthMethod interface {
 // "none" authentication, RFC 4252 section 5.2.
 type noneAuth int
 
-func (n *noneAuth) auth(session []byte, user string, c packetConn, rand io.Reader) (authResult, []string, error) {
+func (n *noneAuth) auth(session []byte, user string, c packetConn, rand io.Reader, _ map[string][]byte) (authResult, []string, error) {
 	if err := c.writePacket(Marshal(&userAuthRequestMsg{
 		User:    user,
 		Service: serviceSSH,
@@ -122,7 +150,7 @@ func (n *noneAuth) method() string {
 // a function call, e.g. by prompting the user.
 type passwordCallback func() (password string, err error)
 
-func (cb passwordCallback) auth(session []byte, user string, c packetConn, rand io.Reader) (authResult, []string, error) {
+func (cb passwordCallback) auth(session []byte, user string, c packetConn, rand io.Reader, _ map[string][]byte) (authResult, []string, error) {
 	type passwordAuthMsg struct {
 		User     string `sshtype:"50"`
 		Service  string
@@ -189,7 +217,46 @@ func (cb publicKeyCallback) method() string {
 	return "publickey"
 }
 
-func (cb publicKeyCallback) auth(session []byte, user string, c packetConn, rand io.Reader) (authResult, []string, error) {
+func pickSignatureAlgorithm(signer Signer, extensions map[string][]byte) (as AlgorithmSigner, algo string) {
+	keyFormat := signer.PublicKey().Type()
+
+	// Like in sendKexInit, if the public key implements AlgorithmSigner we
+	// assume it supports all algorithms, otherwise only the key format one.
+	as, ok := signer.(AlgorithmSigner)
+	if !ok {
+		return algorithmSignerWrapper{signer}, keyFormat
+	}
+
+	extPayload, ok := extensions["server-sig-algs"]
+	if !ok {
+		// If there is no "server-sig-algs" extension, fall back to the key
+		// format algorithm.
+		return as, keyFormat
+	}
+
+	// The server-sig-algs extension only carries underlying signature
+	// algorithm, but we are trying to select a protocol-level public key
+	// algorithm, which might be a certificate type. Extend the list of server
+	// supported algorithms to include the corresponding certificate algorithms.
+	serverAlgos := strings.Split(string(extPayload), ",")
+	for _, algo := range serverAlgos {
+		if certAlgo, ok := certificateAlgo(algo); ok {
+			serverAlgos = append(serverAlgos, certAlgo)
+		}
+	}
+
+	keyAlgos := algorithmsForKeyFormat(keyFormat)
+	algo, err := findCommon("public key signature algorithm", keyAlgos, serverAlgos)
+	if err != nil {
+		// If there is no overlap, try the key anyway with the key format
+		// algorithm, to support servers that fail to list all supported
+		// algorithms.
+		return as, keyFormat
+	}
+	return as, algo
+}
+
+func (cb publicKeyCallback) auth(session []byte, user string, c packetConn, rand io.Reader, extensions map[string][]byte) (authResult, []string, error) {
 	// Authentication is performed by sending an enquiry to test if a key is
 	// acceptable to the remote. If the key is acceptable, the client will
 	// attempt to authenticate with the valid key.  If not the client will repeat
@@ -201,7 +268,10 @@ func (cb publicKeyCallback) auth(session []byte, user string, c packetConn, rand
 	}
 	var methods []string
 	for _, signer := range signers {
-		ok, err := validateKey(signer.PublicKey(), user, c)
+		pub := signer.PublicKey()
+		as, algo := pickSignatureAlgorithm(signer, extensions)
+
+		ok, err := validateKey(pub, algo, user, c)
 		if err != nil {
 			return authFailure, nil, err
 		}
@@ -209,13 +279,13 @@ func (cb publicKeyCallback) auth(session []byte, user string, c packetConn, rand
 			continue
 		}
 
-		pub := signer.PublicKey()
 		pubKey := pub.Marshal()
-		sign, err := signer.Sign(rand, buildDataSignedForAuth(session, userAuthRequestMsg{
+		data := buildDataSignedForAuth(session, userAuthRequestMsg{
 			User:    user,
 			Service: serviceSSH,
 			Method:  cb.method(),
-		}, []byte(pub.Type()), pubKey))
+		}, algo, pubKey)
+		sign, err := as.SignWithAlgorithm(rand, data, underlyingAlgo(algo))
 		if err != nil {
 			return authFailure, nil, err
 		}
@@ -229,7 +299,7 @@ func (cb publicKeyCallback) auth(session []byte, user string, c packetConn, rand
 			Service:  serviceSSH,
 			Method:   cb.method(),
 			HasSig:   true,
-			Algoname: pub.Type(),
+			Algoname: algo,
 			PubKey:   pubKey,
 			Sig:      sig,
 		}
@@ -266,26 +336,25 @@ func containsMethod(methods []string, method string) bool {
 }
 
 // validateKey validates the key provided is acceptable to the server.
-func validateKey(key PublicKey, user string, c packetConn) (bool, error) {
+func validateKey(key PublicKey, algo string, user string, c packetConn) (bool, error) {
 	pubKey := key.Marshal()
 	msg := publickeyAuthMsg{
 		User:     user,
 		Service:  serviceSSH,
 		Method:   "publickey",
 		HasSig:   false,
-		Algoname: key.Type(),
+		Algoname: algo,
 		PubKey:   pubKey,
 	}
 	if err := c.writePacket(Marshal(&msg)); err != nil {
 		return false, err
 	}
 
-	return confirmKeyAck(key, c)
+	return confirmKeyAck(key, algo, c)
 }
 
-func confirmKeyAck(key PublicKey, c packetConn) (bool, error) {
+func confirmKeyAck(key PublicKey, algo string, c packetConn) (bool, error) {
 	pubKey := key.Marshal()
-	algoname := key.Type()
 
 	for {
 		packet, err := c.readPacket()
@@ -302,14 +371,14 @@ func confirmKeyAck(key PublicKey, c packetConn) (bool, error) {
 			if err := Unmarshal(packet, &msg); err != nil {
 				return false, err
 			}
-			if msg.Algo != algoname || !bytes.Equal(msg.PubKey, pubKey) {
+			if msg.Algo != algo || !bytes.Equal(msg.PubKey, pubKey) {
 				return false, nil
 			}
 			return true, nil
 		case msgUserAuthFailure:
 			return false, nil
 		default:
-			return false, unexpectedMessageError(msgUserAuthSuccess, packet[0])
+			return false, unexpectedMessageError(msgUserAuthPubKeyOk, packet[0])
 		}
 	}
 }
@@ -330,6 +399,7 @@ func PublicKeysCallback(getSigners func() (signers []Signer, err error)) AuthMet
 // along with a list of remaining authentication methods to try next and
 // an error if an unexpected response was received.
 func handleAuthResponse(c packetConn) (authResult, []string, error) {
+	gotMsgExtInfo := false
 	for {
 		packet, err := c.readPacket()
 		if err != nil {
@@ -341,6 +411,12 @@ func handleAuthResponse(c packetConn) (authResult, []string, error) {
 			if err := handleBannerResponse(c, packet); err != nil {
 				return authFailure, nil, err
 			}
+		case msgExtInfo:
+			// Ignore post-authentication RFC 8308 extensions, once.
+			if gotMsgExtInfo {
+				return authFailure, nil, unexpectedMessageError(msgUserAuthSuccess, packet[0])
+			}
+			gotMsgExtInfo = true
 		case msgUserAuthFailure:
 			var msg userAuthFailureMsg
 			if err := Unmarshal(packet, &msg); err != nil {
@@ -380,10 +456,10 @@ func handleBannerResponse(c packetConn, packet []byte) error {
 // disabling echoing (e.g. for passwords), and return all the answers.
 // Challenge may be called multiple times in a single session. After
 // successful authentication, the server may send a challenge with no
-// questions, for which the user and instruction messages should be
+// questions, for which the name and instruction messages should be
 // printed.  RFC 4256 section 3.3 details how the UI should behave for
 // both CLI and GUI environments.
-type KeyboardInteractiveChallenge func(user, instruction string, questions []string, echos []bool) (answers []string, err error)
+type KeyboardInteractiveChallenge func(name, instruction string, questions []string, echos []bool) (answers []string, err error)
 
 // KeyboardInteractive returns an AuthMethod using a prompt/response
 // sequence controlled by the server.
@@ -395,7 +471,7 @@ func (cb KeyboardInteractiveChallenge) method() string {
 	return "keyboard-interactive"
 }
 
-func (cb KeyboardInteractiveChallenge) auth(session []byte, user string, c packetConn, rand io.Reader) (authResult, []string, error) {
+func (cb KeyboardInteractiveChallenge) auth(session []byte, user string, c packetConn, rand io.Reader, _ map[string][]byte) (authResult, []string, error) {
 	type initiateMsg struct {
 		User       string `sshtype:"50"`
 		Service    string
@@ -412,6 +488,7 @@ func (cb KeyboardInteractiveChallenge) auth(session []byte, user string, c packe
 		return authFailure, nil, err
 	}
 
+	gotMsgExtInfo := false
 	for {
 		packet, err := c.readPacket()
 		if err != nil {
@@ -425,6 +502,13 @@ func (cb KeyboardInteractiveChallenge) auth(session []byte, user string, c packe
 				return authFailure, nil, err
 			}
 			continue
+		case msgExtInfo:
+			// Ignore post-authentication RFC 8308 extensions, once.
+			if gotMsgExtInfo {
+				return authFailure, nil, unexpectedMessageError(msgUserAuthInfoRequest, packet[0])
+			}
+			gotMsgExtInfo = true
+			continue
 		case msgUserAuthInfoRequest:
 			// OK
 		case msgUserAuthFailure:
@@ -465,7 +549,7 @@ func (cb KeyboardInteractiveChallenge) auth(session []byte, user string, c packe
 			return authFailure, nil, errors.New("ssh: extra data following keyboard-interactive pairs")
 		}
 
-		answers, err := cb(msg.User, msg.Instruction, prompts, echos)
+		answers, err := cb(msg.Name, msg.Instruction, prompts, echos)
 		if err != nil {
 			return authFailure, nil, err
 		}
@@ -497,9 +581,9 @@ type retryableAuthMethod struct {
 	maxTries   int
 }
 
-func (r *retryableAuthMethod) auth(session []byte, user string, c packetConn, rand io.Reader) (ok authResult, methods []string, err error) {
+func (r *retryableAuthMethod) auth(session []byte, user string, c packetConn, rand io.Reader, extensions map[string][]byte) (ok authResult, methods []string, err error) {
 	for i := 0; r.maxTries <= 0 || i < r.maxTries; i++ {
-		ok, methods, err = r.authMethod.auth(session, user, c, rand)
+		ok, methods, err = r.authMethod.auth(session, user, c, rand, extensions)
 		if ok != authFailure || err != nil { // either success, partial success or error terminate
 			return ok, methods, err
 		}
@@ -542,7 +626,7 @@ type gssAPIWithMICCallback struct {
 	target       string
 }
 
-func (g *gssAPIWithMICCallback) auth(session []byte, user string, c packetConn, rand io.Reader) (authResult, []string, error) {
+func (g *gssAPIWithMICCallback) auth(session []byte, user string, c packetConn, rand io.Reader, _ map[string][]byte) (authResult, []string, error) {
 	m := &userAuthRequestMsg{
 		User:    user,
 		Service: serviceSSH,
diff --git a/vendor/golang.org/x/crypto/ssh/common.go b/vendor/golang.org/x/crypto/ssh/common.go
index 290382d059..2a47a61ded 100644
--- a/vendor/golang.org/x/crypto/ssh/common.go
+++ b/vendor/golang.org/x/crypto/ssh/common.go
@@ -44,11 +44,11 @@ var preferredCiphers = []string{
 // supportedKexAlgos specifies the supported key-exchange algorithms in
 // preference order.
 var supportedKexAlgos = []string{
-	kexAlgoCurve25519SHA256,
+	kexAlgoCurve25519SHA256, kexAlgoCurve25519SHA256LibSSH,
 	// P384 and P521 are not constant-time yet, but since we don't
 	// reuse ephemeral keys, using them for ECDH should be OK.
 	kexAlgoECDH256, kexAlgoECDH384, kexAlgoECDH521,
-	kexAlgoDH14SHA1, kexAlgoDH1SHA1,
+	kexAlgoDH14SHA256, kexAlgoDH14SHA1, kexAlgoDH1SHA1,
 }
 
 // serverForbiddenKexAlgos contains key exchange algorithms, that are forbidden
@@ -61,18 +61,20 @@ var serverForbiddenKexAlgos = map[string]struct{}{
 // preferredKexAlgos specifies the default preference for key-exchange algorithms
 // in preference order.
 var preferredKexAlgos = []string{
-	kexAlgoCurve25519SHA256,
+	kexAlgoCurve25519SHA256, kexAlgoCurve25519SHA256LibSSH,
 	kexAlgoECDH256, kexAlgoECDH384, kexAlgoECDH521,
-	kexAlgoDH14SHA1,
+	kexAlgoDH14SHA256, kexAlgoDH14SHA1,
 }
 
 // supportedHostKeyAlgos specifies the supported host-key algorithms (i.e. methods
 // of authenticating servers) in preference order.
 var supportedHostKeyAlgos = []string{
+	CertAlgoRSASHA512v01, CertAlgoRSASHA256v01,
 	CertAlgoRSAv01, CertAlgoDSAv01, CertAlgoECDSA256v01,
 	CertAlgoECDSA384v01, CertAlgoECDSA521v01, CertAlgoED25519v01,
 
 	KeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoECDSA521,
+	KeyAlgoRSASHA512, KeyAlgoRSASHA256,
 	KeyAlgoRSA, KeyAlgoDSA,
 
 	KeyAlgoED25519,
@@ -87,19 +89,33 @@ var supportedMACs = []string{
 
 var supportedCompressions = []string{compressionNone}
 
-// hashFuncs keeps the mapping of supported algorithms to their respective
-// hashes needed for signature verification.
+// hashFuncs keeps the mapping of supported signature algorithms to their
+// respective hashes needed for signing and verification.
 var hashFuncs = map[string]crypto.Hash{
-	KeyAlgoRSA:          crypto.SHA1,
-	KeyAlgoDSA:          crypto.SHA1,
-	KeyAlgoECDSA256:     crypto.SHA256,
-	KeyAlgoECDSA384:     crypto.SHA384,
-	KeyAlgoECDSA521:     crypto.SHA512,
-	CertAlgoRSAv01:      crypto.SHA1,
-	CertAlgoDSAv01:      crypto.SHA1,
-	CertAlgoECDSA256v01: crypto.SHA256,
-	CertAlgoECDSA384v01: crypto.SHA384,
-	CertAlgoECDSA521v01: crypto.SHA512,
+	KeyAlgoRSA:       crypto.SHA1,
+	KeyAlgoRSASHA256: crypto.SHA256,
+	KeyAlgoRSASHA512: crypto.SHA512,
+	KeyAlgoDSA:       crypto.SHA1,
+	KeyAlgoECDSA256:  crypto.SHA256,
+	KeyAlgoECDSA384:  crypto.SHA384,
+	KeyAlgoECDSA521:  crypto.SHA512,
+	// KeyAlgoED25519 doesn't pre-hash.
+	KeyAlgoSKECDSA256: crypto.SHA256,
+	KeyAlgoSKED25519:  crypto.SHA256,
+}
+
+// algorithmsForKeyFormat returns the supported signature algorithms for a given
+// public key format (PublicKey.Type), in order of preference. See RFC 8332,
+// Section 2. See also the note in sendKexInit on backwards compatibility.
+func algorithmsForKeyFormat(keyFormat string) []string {
+	switch keyFormat {
+	case KeyAlgoRSA:
+		return []string{KeyAlgoRSASHA256, KeyAlgoRSASHA512, KeyAlgoRSA}
+	case CertAlgoRSAv01:
+		return []string{CertAlgoRSASHA256v01, CertAlgoRSASHA512v01, CertAlgoRSAv01}
+	default:
+		return []string{keyFormat}
+	}
 }
 
 // unexpectedMessageError results when the SSH message that we received didn't
@@ -146,6 +162,11 @@ func (a *directionAlgorithms) rekeyBytes() int64 {
 	return 1 << 30
 }
 
+var aeadCiphers = map[string]bool{
+	gcmCipherID:        true,
+	chacha20Poly1305ID: true,
+}
+
 type algorithms struct {
 	kex     string
 	hostKey string
@@ -181,14 +202,18 @@ func findAgreedAlgorithms(isClient bool, clientKexInit, serverKexInit *kexInitMs
 		return
 	}
 
-	ctos.MAC, err = findCommon("client to server MAC", clientKexInit.MACsClientServer, serverKexInit.MACsClientServer)
-	if err != nil {
-		return
+	if !aeadCiphers[ctos.Cipher] {
+		ctos.MAC, err = findCommon("client to server MAC", clientKexInit.MACsClientServer, serverKexInit.MACsClientServer)
+		if err != nil {
+			return
+		}
 	}
 
-	stoc.MAC, err = findCommon("server to client MAC", clientKexInit.MACsServerClient, serverKexInit.MACsServerClient)
-	if err != nil {
-		return
+	if !aeadCiphers[stoc.Cipher] {
+		stoc.MAC, err = findCommon("server to client MAC", clientKexInit.MACsServerClient, serverKexInit.MACsServerClient)
+		if err != nil {
+			return
+		}
 	}
 
 	ctos.Compression, err = findCommon("client to server compression", clientKexInit.CompressionClientServer, serverKexInit.CompressionClientServer)
@@ -272,8 +297,9 @@ func (c *Config) SetDefaults() {
 }
 
 // buildDataSignedForAuth returns the data that is signed in order to prove
-// possession of a private key. See RFC 4252, section 7.
-func buildDataSignedForAuth(sessionID []byte, req userAuthRequestMsg, algo, pubKey []byte) []byte {
+// possession of a private key. See RFC 4252, section 7. algo is the advertised
+// algorithm, and may be a certificate type.
+func buildDataSignedForAuth(sessionID []byte, req userAuthRequestMsg, algo string, pubKey []byte) []byte {
 	data := struct {
 		Session []byte
 		Type    byte
@@ -281,7 +307,7 @@ func buildDataSignedForAuth(sessionID []byte, req userAuthRequestMsg, algo, pubK
 		Service string
 		Method  string
 		Sign    bool
-		Algo    []byte
+		Algo    string
 		PubKey  []byte
 	}{
 		sessionID,
diff --git a/vendor/golang.org/x/crypto/ssh/handshake.go b/vendor/golang.org/x/crypto/ssh/handshake.go
index 2b10b05a49..f815cdb4c9 100644
--- a/vendor/golang.org/x/crypto/ssh/handshake.go
+++ b/vendor/golang.org/x/crypto/ssh/handshake.go
@@ -455,14 +455,36 @@ func (t *handshakeTransport) sendKexInit() error {
 	}
 	io.ReadFull(rand.Reader, msg.Cookie[:])
 
-	if len(t.hostKeys) > 0 {
+	isServer := len(t.hostKeys) > 0
+	if isServer {
 		for _, k := range t.hostKeys {
-			msg.ServerHostKeyAlgos = append(
-				msg.ServerHostKeyAlgos, k.PublicKey().Type())
+			// If k is an AlgorithmSigner, presume it supports all signature algorithms
+			// associated with the key format. (Ideally AlgorithmSigner would have a
+			// method to advertise supported algorithms, but it doesn't. This means that
+			// adding support for a new algorithm is a breaking change, as we will
+			// immediately negotiate it even if existing implementations don't support
+			// it. If that ever happens, we'll have to figure something out.)
+			// If k is not an AlgorithmSigner, we can only assume it only supports the
+			// algorithms that matches the key format. (This means that Sign can't pick
+			// a different default.)
+			keyFormat := k.PublicKey().Type()
+			if _, ok := k.(AlgorithmSigner); ok {
+				msg.ServerHostKeyAlgos = append(msg.ServerHostKeyAlgos, algorithmsForKeyFormat(keyFormat)...)
+			} else {
+				msg.ServerHostKeyAlgos = append(msg.ServerHostKeyAlgos, keyFormat)
+			}
 		}
 	} else {
 		msg.ServerHostKeyAlgos = t.hostKeyAlgorithms
+
+		// As a client we opt in to receiving SSH_MSG_EXT_INFO so we know what
+		// algorithms the server supports for public key authentication. See RFC
+		// 8303, Section 2.1.
+		msg.KexAlgos = make([]string, 0, len(t.config.KeyExchanges)+1)
+		msg.KexAlgos = append(msg.KexAlgos, t.config.KeyExchanges...)
+		msg.KexAlgos = append(msg.KexAlgos, "ext-info-c")
 	}
+
 	packet := Marshal(msg)
 
 	// writePacket destroys the contents, so save a copy.
@@ -582,9 +604,9 @@ func (t *handshakeTransport) enterKeyExchange(otherInitPacket []byte) error {
 
 	var result *kexResult
 	if len(t.hostKeys) > 0 {
-		result, err = t.server(kex, t.algorithms, &magics)
+		result, err = t.server(kex, &magics)
 	} else {
-		result, err = t.client(kex, t.algorithms, &magics)
+		result, err = t.client(kex, &magics)
 	}
 
 	if err != nil {
@@ -611,19 +633,52 @@ func (t *handshakeTransport) enterKeyExchange(otherInitPacket []byte) error {
 	return nil
 }
 
-func (t *handshakeTransport) server(kex kexAlgorithm, algs *algorithms, magics *handshakeMagics) (*kexResult, error) {
-	var hostKey Signer
-	for _, k := range t.hostKeys {
-		if algs.hostKey == k.PublicKey().Type() {
-			hostKey = k
+// algorithmSignerWrapper is an AlgorithmSigner that only supports the default
+// key format algorithm.
+//
+// This is technically a violation of the AlgorithmSigner interface, but it
+// should be unreachable given where we use this. Anyway, at least it returns an
+// error instead of panicing or producing an incorrect signature.
+type algorithmSignerWrapper struct {
+	Signer
+}
+
+func (a algorithmSignerWrapper) SignWithAlgorithm(rand io.Reader, data []byte, algorithm string) (*Signature, error) {
+	if algorithm != underlyingAlgo(a.PublicKey().Type()) {
+		return nil, errors.New("ssh: internal error: algorithmSignerWrapper invoked with non-default algorithm")
+	}
+	return a.Sign(rand, data)
+}
+
+func pickHostKey(hostKeys []Signer, algo string) AlgorithmSigner {
+	for _, k := range hostKeys {
+		if algo == k.PublicKey().Type() {
+			return algorithmSignerWrapper{k}
+		}
+		k, ok := k.(AlgorithmSigner)
+		if !ok {
+			continue
+		}
+		for _, a := range algorithmsForKeyFormat(k.PublicKey().Type()) {
+			if algo == a {
+				return k
+			}
 		}
 	}
+	return nil
+}
 
-	r, err := kex.Server(t.conn, t.config.Rand, magics, hostKey)
+func (t *handshakeTransport) server(kex kexAlgorithm, magics *handshakeMagics) (*kexResult, error) {
+	hostKey := pickHostKey(t.hostKeys, t.algorithms.hostKey)
+	if hostKey == nil {
+		return nil, errors.New("ssh: internal error: negotiated unsupported signature type")
+	}
+
+	r, err := kex.Server(t.conn, t.config.Rand, magics, hostKey, t.algorithms.hostKey)
 	return r, err
 }
 
-func (t *handshakeTransport) client(kex kexAlgorithm, algs *algorithms, magics *handshakeMagics) (*kexResult, error) {
+func (t *handshakeTransport) client(kex kexAlgorithm, magics *handshakeMagics) (*kexResult, error) {
 	result, err := kex.Client(t.conn, t.config.Rand, magics)
 	if err != nil {
 		return nil, err
@@ -634,7 +689,7 @@ func (t *handshakeTransport) client(kex kexAlgorithm, algs *algorithms, magics *
 		return nil, err
 	}
 
-	if err := verifyHostKeySignature(hostKey, result); err != nil {
+	if err := verifyHostKeySignature(hostKey, t.algorithms.hostKey, result); err != nil {
 		return nil, err
 	}
 
diff --git a/vendor/golang.org/x/crypto/ssh/kex.go b/vendor/golang.org/x/crypto/ssh/kex.go
index 766e929397..927a90cd46 100644
--- a/vendor/golang.org/x/crypto/ssh/kex.go
+++ b/vendor/golang.org/x/crypto/ssh/kex.go
@@ -20,12 +20,14 @@ import (
 )
 
 const (
-	kexAlgoDH1SHA1          = "diffie-hellman-group1-sha1"
-	kexAlgoDH14SHA1         = "diffie-hellman-group14-sha1"
-	kexAlgoECDH256          = "ecdh-sha2-nistp256"
-	kexAlgoECDH384          = "ecdh-sha2-nistp384"
-	kexAlgoECDH521          = "ecdh-sha2-nistp521"
-	kexAlgoCurve25519SHA256 = "curve25519-sha256@libssh.org"
+	kexAlgoDH1SHA1                = "diffie-hellman-group1-sha1"
+	kexAlgoDH14SHA1               = "diffie-hellman-group14-sha1"
+	kexAlgoDH14SHA256             = "diffie-hellman-group14-sha256"
+	kexAlgoECDH256                = "ecdh-sha2-nistp256"
+	kexAlgoECDH384                = "ecdh-sha2-nistp384"
+	kexAlgoECDH521                = "ecdh-sha2-nistp521"
+	kexAlgoCurve25519SHA256LibSSH = "curve25519-sha256@libssh.org"
+	kexAlgoCurve25519SHA256       = "curve25519-sha256"
 
 	// For the following kex only the client half contains a production
 	// ready implementation. The server half only consists of a minimal
@@ -75,8 +77,9 @@ func (m *handshakeMagics) write(w io.Writer) {
 // kexAlgorithm abstracts different key exchange algorithms.
 type kexAlgorithm interface {
 	// Server runs server-side key agreement, signing the result
-	// with a hostkey.
-	Server(p packetConn, rand io.Reader, magics *handshakeMagics, s Signer) (*kexResult, error)
+	// with a hostkey. algo is the negotiated algorithm, and may
+	// be a certificate type.
+	Server(p packetConn, rand io.Reader, magics *handshakeMagics, s AlgorithmSigner, algo string) (*kexResult, error)
 
 	// Client runs the client-side key agreement. Caller is
 	// responsible for verifying the host key signature.
@@ -86,6 +89,7 @@ type kexAlgorithm interface {
 // dhGroup is a multiplicative group suitable for implementing Diffie-Hellman key agreement.
 type dhGroup struct {
 	g, p, pMinus1 *big.Int
+	hashFunc      crypto.Hash
 }
 
 func (group *dhGroup) diffieHellman(theirPublic, myPrivate *big.Int) (*big.Int, error) {
@@ -96,8 +100,6 @@ func (group *dhGroup) diffieHellman(theirPublic, myPrivate *big.Int) (*big.Int,
 }
 
 func (group *dhGroup) Client(c packetConn, randSource io.Reader, magics *handshakeMagics) (*kexResult, error) {
-	hashFunc := crypto.SHA1
-
 	var x *big.Int
 	for {
 		var err error
@@ -132,7 +134,7 @@ func (group *dhGroup) Client(c packetConn, randSource io.Reader, magics *handsha
 		return nil, err
 	}
 
-	h := hashFunc.New()
+	h := group.hashFunc.New()
 	magics.write(h)
 	writeString(h, kexDHReply.HostKey)
 	writeInt(h, X)
@@ -146,12 +148,11 @@ func (group *dhGroup) Client(c packetConn, randSource io.Reader, magics *handsha
 		K:         K,
 		HostKey:   kexDHReply.HostKey,
 		Signature: kexDHReply.Signature,
-		Hash:      crypto.SHA1,
+		Hash:      group.hashFunc,
 	}, nil
 }
 
-func (group *dhGroup) Server(c packetConn, randSource io.Reader, magics *handshakeMagics, priv Signer) (result *kexResult, err error) {
-	hashFunc := crypto.SHA1
+func (group *dhGroup) Server(c packetConn, randSource io.Reader, magics *handshakeMagics, priv AlgorithmSigner, algo string) (result *kexResult, err error) {
 	packet, err := c.readPacket()
 	if err != nil {
 		return
@@ -179,7 +180,7 @@ func (group *dhGroup) Server(c packetConn, randSource io.Reader, magics *handsha
 
 	hostKeyBytes := priv.PublicKey().Marshal()
 
-	h := hashFunc.New()
+	h := group.hashFunc.New()
 	magics.write(h)
 	writeString(h, hostKeyBytes)
 	writeInt(h, kexDHInit.X)
@@ -193,7 +194,7 @@ func (group *dhGroup) Server(c packetConn, randSource io.Reader, magics *handsha
 
 	// H is already a hash, but the hostkey signing will apply its
 	// own key-specific hash algorithm.
-	sig, err := signAndMarshal(priv, randSource, H)
+	sig, err := signAndMarshal(priv, randSource, H, algo)
 	if err != nil {
 		return nil, err
 	}
@@ -211,7 +212,7 @@ func (group *dhGroup) Server(c packetConn, randSource io.Reader, magics *handsha
 		K:         K,
 		HostKey:   hostKeyBytes,
 		Signature: sig,
-		Hash:      crypto.SHA1,
+		Hash:      group.hashFunc,
 	}, err
 }
 
@@ -314,7 +315,7 @@ func validateECPublicKey(curve elliptic.Curve, x, y *big.Int) bool {
 	return true
 }
 
-func (kex *ecdh) Server(c packetConn, rand io.Reader, magics *handshakeMagics, priv Signer) (result *kexResult, err error) {
+func (kex *ecdh) Server(c packetConn, rand io.Reader, magics *handshakeMagics, priv AlgorithmSigner, algo string) (result *kexResult, err error) {
 	packet, err := c.readPacket()
 	if err != nil {
 		return nil, err
@@ -359,7 +360,7 @@ func (kex *ecdh) Server(c packetConn, rand io.Reader, magics *handshakeMagics, p
 
 	// H is already a hash, but the hostkey signing will apply its
 	// own key-specific hash algorithm.
-	sig, err := signAndMarshal(priv, rand, H)
+	sig, err := signAndMarshal(priv, rand, H, algo)
 	if err != nil {
 		return nil, err
 	}
@@ -384,39 +385,62 @@ func (kex *ecdh) Server(c packetConn, rand io.Reader, magics *handshakeMagics, p
 	}, nil
 }
 
+// ecHash returns the hash to match the given elliptic curve, see RFC
+// 5656, section 6.2.1
+func ecHash(curve elliptic.Curve) crypto.Hash {
+	bitSize := curve.Params().BitSize
+	switch {
+	case bitSize <= 256:
+		return crypto.SHA256
+	case bitSize <= 384:
+		return crypto.SHA384
+	}
+	return crypto.SHA512
+}
+
 var kexAlgoMap = map[string]kexAlgorithm{}
 
 func init() {
-	// This is the group called diffie-hellman-group1-sha1 in RFC
-	// 4253 and Oakley Group 2 in RFC 2409.
+	// This is the group called diffie-hellman-group1-sha1 in
+	// RFC 4253 and Oakley Group 2 in RFC 2409.
 	p, _ := new(big.Int).SetString("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF", 16)
 	kexAlgoMap[kexAlgoDH1SHA1] = &dhGroup{
+		g:        new(big.Int).SetInt64(2),
+		p:        p,
+		pMinus1:  new(big.Int).Sub(p, bigOne),
+		hashFunc: crypto.SHA1,
+	}
+
+	// This are the groups called diffie-hellman-group14-sha1 and
+	// diffie-hellman-group14-sha256 in RFC 4253 and RFC 8268,
+	// and Oakley Group 14 in RFC 3526.
+	p, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF", 16)
+	group14 := &dhGroup{
 		g:       new(big.Int).SetInt64(2),
 		p:       p,
 		pMinus1: new(big.Int).Sub(p, bigOne),
 	}
 
-	// This is the group called diffie-hellman-group14-sha1 in RFC
-	// 4253 and Oakley Group 14 in RFC 3526.
-	p, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF", 16)
-
 	kexAlgoMap[kexAlgoDH14SHA1] = &dhGroup{
-		g:       new(big.Int).SetInt64(2),
-		p:       p,
-		pMinus1: new(big.Int).Sub(p, bigOne),
+		g: group14.g, p: group14.p, pMinus1: group14.pMinus1,
+		hashFunc: crypto.SHA1,
+	}
+	kexAlgoMap[kexAlgoDH14SHA256] = &dhGroup{
+		g: group14.g, p: group14.p, pMinus1: group14.pMinus1,
+		hashFunc: crypto.SHA256,
 	}
 
 	kexAlgoMap[kexAlgoECDH521] = &ecdh{elliptic.P521()}
 	kexAlgoMap[kexAlgoECDH384] = &ecdh{elliptic.P384()}
 	kexAlgoMap[kexAlgoECDH256] = &ecdh{elliptic.P256()}
 	kexAlgoMap[kexAlgoCurve25519SHA256] = &curve25519sha256{}
+	kexAlgoMap[kexAlgoCurve25519SHA256LibSSH] = &curve25519sha256{}
 	kexAlgoMap[kexAlgoDHGEXSHA1] = &dhGEXSHA{hashFunc: crypto.SHA1}
 	kexAlgoMap[kexAlgoDHGEXSHA256] = &dhGEXSHA{hashFunc: crypto.SHA256}
 }
 
-// curve25519sha256 implements the curve25519-sha256@libssh.org key
-// agreement protocol, as described in
-// https://git.libssh.org/projects/libssh.git/tree/doc/curve25519-sha256@libssh.org.txt
+// curve25519sha256 implements the curve25519-sha256 (formerly known as
+// curve25519-sha256@libssh.org) key exchange method, as described in RFC 8731.
 type curve25519sha256 struct{}
 
 type curve25519KeyPair struct {
@@ -486,7 +510,7 @@ func (kex *curve25519sha256) Client(c packetConn, rand io.Reader, magics *handsh
 	}, nil
 }
 
-func (kex *curve25519sha256) Server(c packetConn, rand io.Reader, magics *handshakeMagics, priv Signer) (result *kexResult, err error) {
+func (kex *curve25519sha256) Server(c packetConn, rand io.Reader, magics *handshakeMagics, priv AlgorithmSigner, algo string) (result *kexResult, err error) {
 	packet, err := c.readPacket()
 	if err != nil {
 		return
@@ -527,7 +551,7 @@ func (kex *curve25519sha256) Server(c packetConn, rand io.Reader, magics *handsh
 
 	H := h.Sum(nil)
 
-	sig, err := signAndMarshal(priv, rand, H)
+	sig, err := signAndMarshal(priv, rand, H, algo)
 	if err != nil {
 		return nil, err
 	}
@@ -553,7 +577,6 @@ func (kex *curve25519sha256) Server(c packetConn, rand io.Reader, magics *handsh
 // diffie-hellman-group-exchange-sha256 key agreement protocols,
 // as described in RFC 4419
 type dhGEXSHA struct {
-	g, p     *big.Int
 	hashFunc crypto.Hash
 }
 
@@ -563,14 +586,7 @@ const (
 	dhGroupExchangeMaximumBits   = 8192
 )
 
-func (gex *dhGEXSHA) diffieHellman(theirPublic, myPrivate *big.Int) (*big.Int, error) {
-	if theirPublic.Sign() <= 0 || theirPublic.Cmp(gex.p) >= 0 {
-		return nil, fmt.Errorf("ssh: DH parameter out of bounds")
-	}
-	return new(big.Int).Exp(theirPublic, myPrivate, gex.p), nil
-}
-
-func (gex dhGEXSHA) Client(c packetConn, randSource io.Reader, magics *handshakeMagics) (*kexResult, error) {
+func (gex *dhGEXSHA) Client(c packetConn, randSource io.Reader, magics *handshakeMagics) (*kexResult, error) {
 	// Send GexRequest
 	kexDHGexRequest := kexDHGexRequestMsg{
 		MinBits:      dhGroupExchangeMinimumBits,
@@ -587,35 +603,29 @@ func (gex dhGEXSHA) Client(c packetConn, randSource io.Reader, magics *handshake
 		return nil, err
 	}
 
-	var kexDHGexGroup kexDHGexGroupMsg
-	if err = Unmarshal(packet, &kexDHGexGroup); err != nil {
+	var msg kexDHGexGroupMsg
+	if err = Unmarshal(packet, &msg); err != nil {
 		return nil, err
 	}
 
 	// reject if p's bit length < dhGroupExchangeMinimumBits or > dhGroupExchangeMaximumBits
-	if kexDHGexGroup.P.BitLen() < dhGroupExchangeMinimumBits || kexDHGexGroup.P.BitLen() > dhGroupExchangeMaximumBits {
-		return nil, fmt.Errorf("ssh: server-generated gex p is out of range (%d bits)", kexDHGexGroup.P.BitLen())
+	if msg.P.BitLen() < dhGroupExchangeMinimumBits || msg.P.BitLen() > dhGroupExchangeMaximumBits {
+		return nil, fmt.Errorf("ssh: server-generated gex p is out of range (%d bits)", msg.P.BitLen())
 	}
 
-	gex.p = kexDHGexGroup.P
-	gex.g = kexDHGexGroup.G
-
-	// Check if g is safe by verifing that g > 1 and g < p - 1
-	one := big.NewInt(1)
-	var pMinusOne = &big.Int{}
-	pMinusOne.Sub(gex.p, one)
-	if gex.g.Cmp(one) != 1 && gex.g.Cmp(pMinusOne) != -1 {
+	// Check if g is safe by verifying that 1 < g < p-1
+	pMinusOne := new(big.Int).Sub(msg.P, bigOne)
+	if msg.G.Cmp(bigOne) <= 0 || msg.G.Cmp(pMinusOne) >= 0 {
 		return nil, fmt.Errorf("ssh: server provided gex g is not safe")
 	}
 
 	// Send GexInit
-	var pHalf = &big.Int{}
-	pHalf.Rsh(gex.p, 1)
+	pHalf := new(big.Int).Rsh(msg.P, 1)
 	x, err := rand.Int(randSource, pHalf)
 	if err != nil {
 		return nil, err
 	}
-	X := new(big.Int).Exp(gex.g, x, gex.p)
+	X := new(big.Int).Exp(msg.G, x, msg.P)
 	kexDHGexInit := kexDHGexInitMsg{
 		X: X,
 	}
@@ -634,13 +644,13 @@ func (gex dhGEXSHA) Client(c packetConn, randSource io.Reader, magics *handshake
 		return nil, err
 	}
 
-	kInt, err := gex.diffieHellman(kexDHGexReply.Y, x)
-	if err != nil {
-		return nil, err
+	if kexDHGexReply.Y.Cmp(bigOne) <= 0 || kexDHGexReply.Y.Cmp(pMinusOne) >= 0 {
+		return nil, errors.New("ssh: DH parameter out of bounds")
 	}
+	kInt := new(big.Int).Exp(kexDHGexReply.Y, x, msg.P)
 
-	// Check if k is safe by verifing that k > 1 and k < p - 1
-	if kInt.Cmp(one) != 1 && kInt.Cmp(pMinusOne) != -1 {
+	// Check if k is safe by verifying that k > 1 and k < p - 1
+	if kInt.Cmp(bigOne) <= 0 || kInt.Cmp(pMinusOne) >= 0 {
 		return nil, fmt.Errorf("ssh: derived k is not safe")
 	}
 
@@ -650,8 +660,8 @@ func (gex dhGEXSHA) Client(c packetConn, randSource io.Reader, magics *handshake
 	binary.Write(h, binary.BigEndian, uint32(dhGroupExchangeMinimumBits))
 	binary.Write(h, binary.BigEndian, uint32(dhGroupExchangePreferredBits))
 	binary.Write(h, binary.BigEndian, uint32(dhGroupExchangeMaximumBits))
-	writeInt(h, gex.p)
-	writeInt(h, gex.g)
+	writeInt(h, msg.P)
+	writeInt(h, msg.G)
 	writeInt(h, X)
 	writeInt(h, kexDHGexReply.Y)
 	K := make([]byte, intLength(kInt))
@@ -670,7 +680,7 @@ func (gex dhGEXSHA) Client(c packetConn, randSource io.Reader, magics *handshake
 // Server half implementation of the Diffie Hellman Key Exchange with SHA1 and SHA256.
 //
 // This is a minimal implementation to satisfy the automated tests.
-func (gex dhGEXSHA) Server(c packetConn, randSource io.Reader, magics *handshakeMagics, priv Signer) (result *kexResult, err error) {
+func (gex dhGEXSHA) Server(c packetConn, randSource io.Reader, magics *handshakeMagics, priv AlgorithmSigner, algo string) (result *kexResult, err error) {
 	// Receive GexRequest
 	packet, err := c.readPacket()
 	if err != nil {
@@ -681,35 +691,17 @@ func (gex dhGEXSHA) Server(c packetConn, randSource io.Reader, magics *handshake
 		return
 	}
 
-	// smoosh the user's preferred size into our own limits
-	if kexDHGexRequest.PreferedBits > dhGroupExchangeMaximumBits {
-		kexDHGexRequest.PreferedBits = dhGroupExchangeMaximumBits
-	}
-	if kexDHGexRequest.PreferedBits < dhGroupExchangeMinimumBits {
-		kexDHGexRequest.PreferedBits = dhGroupExchangeMinimumBits
-	}
-	// fix min/max if they're inconsistent.  technically, we could just pout
-	// and hang up, but there's no harm in giving them the benefit of the
-	// doubt and just picking a bitsize for them.
-	if kexDHGexRequest.MinBits > kexDHGexRequest.PreferedBits {
-		kexDHGexRequest.MinBits = kexDHGexRequest.PreferedBits
-	}
-	if kexDHGexRequest.MaxBits < kexDHGexRequest.PreferedBits {
-		kexDHGexRequest.MaxBits = kexDHGexRequest.PreferedBits
-	}
-
 	// Send GexGroup
 	// This is the group called diffie-hellman-group14-sha1 in RFC
 	// 4253 and Oakley Group 14 in RFC 3526.
 	p, _ := new(big.Int).SetString("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF", 16)
-	gex.p = p
-	gex.g = big.NewInt(2)
+	g := big.NewInt(2)
 
-	kexDHGexGroup := kexDHGexGroupMsg{
-		P: gex.p,
-		G: gex.g,
+	msg := &kexDHGexGroupMsg{
+		P: p,
+		G: g,
 	}
-	if err := c.writePacket(Marshal(&kexDHGexGroup)); err != nil {
+	if err := c.writePacket(Marshal(msg)); err != nil {
 		return nil, err
 	}
 
@@ -723,19 +715,19 @@ func (gex dhGEXSHA) Server(c packetConn, randSource io.Reader, magics *handshake
 		return
 	}
 
-	var pHalf = &big.Int{}
-	pHalf.Rsh(gex.p, 1)
+	pHalf := new(big.Int).Rsh(p, 1)
 
 	y, err := rand.Int(randSource, pHalf)
 	if err != nil {
 		return
 	}
+	Y := new(big.Int).Exp(g, y, p)
 
-	Y := new(big.Int).Exp(gex.g, y, gex.p)
-	kInt, err := gex.diffieHellman(kexDHGexInit.X, y)
-	if err != nil {
-		return nil, err
+	pMinusOne := new(big.Int).Sub(p, bigOne)
+	if kexDHGexInit.X.Cmp(bigOne) <= 0 || kexDHGexInit.X.Cmp(pMinusOne) >= 0 {
+		return nil, errors.New("ssh: DH parameter out of bounds")
 	}
+	kInt := new(big.Int).Exp(kexDHGexInit.X, y, p)
 
 	hostKeyBytes := priv.PublicKey().Marshal()
 
@@ -745,8 +737,8 @@ func (gex dhGEXSHA) Server(c packetConn, randSource io.Reader, magics *handshake
 	binary.Write(h, binary.BigEndian, uint32(dhGroupExchangeMinimumBits))
 	binary.Write(h, binary.BigEndian, uint32(dhGroupExchangePreferredBits))
 	binary.Write(h, binary.BigEndian, uint32(dhGroupExchangeMaximumBits))
-	writeInt(h, gex.p)
-	writeInt(h, gex.g)
+	writeInt(h, p)
+	writeInt(h, g)
 	writeInt(h, kexDHGexInit.X)
 	writeInt(h, Y)
 
@@ -758,7 +750,7 @@ func (gex dhGEXSHA) Server(c packetConn, randSource io.Reader, magics *handshake
 
 	// H is already a hash, but the hostkey signing will apply its
 	// own key-specific hash algorithm.
-	sig, err := signAndMarshal(priv, randSource, H)
+	sig, err := signAndMarshal(priv, randSource, H, algo)
 	if err != nil {
 		return nil, err
 	}
diff --git a/vendor/golang.org/x/crypto/ssh/keys.go b/vendor/golang.org/x/crypto/ssh/keys.go
index 31f26349a0..1c7de1a6dd 100644
--- a/vendor/golang.org/x/crypto/ssh/keys.go
+++ b/vendor/golang.org/x/crypto/ssh/keys.go
@@ -30,8 +30,9 @@ import (
 	"golang.org/x/crypto/ssh/internal/bcrypt_pbkdf"
 )
 
-// These constants represent the algorithm names for key types supported by this
-// package.
+// Public key algorithms names. These values can appear in PublicKey.Type,
+// ClientConfig.HostKeyAlgorithms, Signature.Format, or as AlgorithmSigner
+// arguments.
 const (
 	KeyAlgoRSA        = "ssh-rsa"
 	KeyAlgoDSA        = "ssh-dss"
@@ -41,16 +42,21 @@ const (
 	KeyAlgoECDSA521   = "ecdsa-sha2-nistp521"
 	KeyAlgoED25519    = "ssh-ed25519"
 	KeyAlgoSKED25519  = "sk-ssh-ed25519@openssh.com"
+
+	// KeyAlgoRSASHA256 and KeyAlgoRSASHA512 are only public key algorithms, not
+	// public key formats, so they can't appear as a PublicKey.Type. The
+	// corresponding PublicKey.Type is KeyAlgoRSA. See RFC 8332, Section 2.
+	KeyAlgoRSASHA256 = "rsa-sha2-256"
+	KeyAlgoRSASHA512 = "rsa-sha2-512"
 )
 
-// These constants represent non-default signature algorithms that are supported
-// as algorithm parameters to AlgorithmSigner.SignWithAlgorithm methods. See
-// [PROTOCOL.agent] section 4.5.1 and
-// https://tools.ietf.org/html/draft-ietf-curdle-rsa-sha2-10
 const (
-	SigAlgoRSA        = "ssh-rsa"
-	SigAlgoRSASHA2256 = "rsa-sha2-256"
-	SigAlgoRSASHA2512 = "rsa-sha2-512"
+	// Deprecated: use KeyAlgoRSA.
+	SigAlgoRSA = KeyAlgoRSA
+	// Deprecated: use KeyAlgoRSASHA256.
+	SigAlgoRSASHA2256 = KeyAlgoRSASHA256
+	// Deprecated: use KeyAlgoRSASHA512.
+	SigAlgoRSASHA2512 = KeyAlgoRSASHA512
 )
 
 // parsePubKey parses a public key of the given algorithm.
@@ -70,7 +76,7 @@ func parsePubKey(in []byte, algo string) (pubKey PublicKey, rest []byte, err err
 	case KeyAlgoSKED25519:
 		return parseSKEd25519(in)
 	case CertAlgoRSAv01, CertAlgoDSAv01, CertAlgoECDSA256v01, CertAlgoECDSA384v01, CertAlgoECDSA521v01, CertAlgoSKECDSA256v01, CertAlgoED25519v01, CertAlgoSKED25519v01:
-		cert, err := parseCert(in, certToPrivAlgo(algo))
+		cert, err := parseCert(in, certKeyAlgoNames[algo])
 		if err != nil {
 			return nil, nil, err
 		}
@@ -289,18 +295,21 @@ func MarshalAuthorizedKey(key PublicKey) []byte {
 	return b.Bytes()
 }
 
-// PublicKey is an abstraction of different types of public keys.
+// PublicKey represents a public key using an unspecified algorithm.
+//
+// Some PublicKeys provided by this package also implement CryptoPublicKey.
 type PublicKey interface {
-	// Type returns the key's type, e.g. "ssh-rsa".
+	// Type returns the key format name, e.g. "ssh-rsa".
 	Type() string
 
-	// Marshal returns the serialized key data in SSH wire format,
-	// with the name prefix. To unmarshal the returned data, use
-	// the ParsePublicKey function.
+	// Marshal returns the serialized key data in SSH wire format, with the name
+	// prefix. To unmarshal the returned data, use the ParsePublicKey function.
 	Marshal() []byte
 
-	// Verify that sig is a signature on the given data using this
-	// key. This function will hash the data appropriately first.
+	// Verify that sig is a signature on the given data using this key. This
+	// method will hash the data appropriately first. sig.Format is allowed to
+	// be any signature algorithm compatible with the key type, the caller
+	// should check if it has more stringent requirements.
 	Verify(data []byte, sig *Signature) error
 }
 
@@ -311,25 +320,32 @@ type CryptoPublicKey interface {
 }
 
 // A Signer can create signatures that verify against a public key.
+//
+// Some Signers provided by this package also implement AlgorithmSigner.
 type Signer interface {
-	// PublicKey returns an associated PublicKey instance.
+	// PublicKey returns the associated PublicKey.
 	PublicKey() PublicKey
 
-	// Sign returns raw signature for the given data. This method
-	// will apply the hash specified for the keytype to the data.
+	// Sign returns a signature for the given data. This method will hash the
+	// data appropriately first. The signature algorithm is expected to match
+	// the key format returned by the PublicKey.Type method (and not to be any
+	// alternative algorithm supported by the key format).
 	Sign(rand io.Reader, data []byte) (*Signature, error)
 }
 
-// A AlgorithmSigner is a Signer that also supports specifying a specific
-// algorithm to use for signing.
+// An AlgorithmSigner is a Signer that also supports specifying an algorithm to
+// use for signing.
+//
+// An AlgorithmSigner can't advertise the algorithms it supports, so it should
+// be prepared to be invoked with every algorithm supported by the public key
+// format.
 type AlgorithmSigner interface {
 	Signer
 
-	// SignWithAlgorithm is like Signer.Sign, but allows specification of a
-	// non-default signing algorithm. See the SigAlgo* constants in this
-	// package for signature algorithms supported by this package. Callers may
-	// pass an empty string for the algorithm in which case the AlgorithmSigner
-	// will use its default algorithm.
+	// SignWithAlgorithm is like Signer.Sign, but allows specifying a desired
+	// signing algorithm. Callers may pass an empty string for the algorithm in
+	// which case the AlgorithmSigner will use a default algorithm. This default
+	// doesn't currently control any behavior in this package.
 	SignWithAlgorithm(rand io.Reader, data []byte, algorithm string) (*Signature, error)
 }
 
@@ -381,17 +397,11 @@ func (r *rsaPublicKey) Marshal() []byte {
 }
 
 func (r *rsaPublicKey) Verify(data []byte, sig *Signature) error {
-	var hash crypto.Hash
-	switch sig.Format {
-	case SigAlgoRSA:
-		hash = crypto.SHA1
-	case SigAlgoRSASHA2256:
-		hash = crypto.SHA256
-	case SigAlgoRSASHA2512:
-		hash = crypto.SHA512
-	default:
+	supportedAlgos := algorithmsForKeyFormat(r.Type())
+	if !contains(supportedAlgos, sig.Format) {
 		return fmt.Errorf("ssh: signature type %s for key type %s", sig.Format, r.Type())
 	}
+	hash := hashFuncs[sig.Format]
 	h := hash.New()
 	h.Write(data)
 	digest := h.Sum(nil)
@@ -466,7 +476,7 @@ func (k *dsaPublicKey) Verify(data []byte, sig *Signature) error {
 	if sig.Format != k.Type() {
 		return fmt.Errorf("ssh: signature type %s for key type %s", sig.Format, k.Type())
 	}
-	h := crypto.SHA1.New()
+	h := hashFuncs[sig.Format].New()
 	h.Write(data)
 	digest := h.Sum(nil)
 
@@ -499,7 +509,7 @@ func (k *dsaPrivateKey) PublicKey() PublicKey {
 }
 
 func (k *dsaPrivateKey) Sign(rand io.Reader, data []byte) (*Signature, error) {
-	return k.SignWithAlgorithm(rand, data, "")
+	return k.SignWithAlgorithm(rand, data, k.PublicKey().Type())
 }
 
 func (k *dsaPrivateKey) SignWithAlgorithm(rand io.Reader, data []byte, algorithm string) (*Signature, error) {
@@ -507,7 +517,7 @@ func (k *dsaPrivateKey) SignWithAlgorithm(rand io.Reader, data []byte, algorithm
 		return nil, fmt.Errorf("ssh: unsupported signature algorithm %s", algorithm)
 	}
 
-	h := crypto.SHA1.New()
+	h := hashFuncs[k.PublicKey().Type()].New()
 	h.Write(data)
 	digest := h.Sum(nil)
 	r, s, err := dsa.Sign(rand, k.PrivateKey, digest)
@@ -603,19 +613,6 @@ func supportedEllipticCurve(curve elliptic.Curve) bool {
 	return curve == elliptic.P256() || curve == elliptic.P384() || curve == elliptic.P521()
 }
 
-// ecHash returns the hash to match the given elliptic curve, see RFC
-// 5656, section 6.2.1
-func ecHash(curve elliptic.Curve) crypto.Hash {
-	bitSize := curve.Params().BitSize
-	switch {
-	case bitSize <= 256:
-		return crypto.SHA256
-	case bitSize <= 384:
-		return crypto.SHA384
-	}
-	return crypto.SHA512
-}
-
 // parseECDSA parses an ECDSA key according to RFC 5656, section 3.1.
 func parseECDSA(in []byte) (out PublicKey, rest []byte, err error) {
 	var w struct {
@@ -671,7 +668,7 @@ func (k *ecdsaPublicKey) Verify(data []byte, sig *Signature) error {
 		return fmt.Errorf("ssh: signature type %s for key type %s", sig.Format, k.Type())
 	}
 
-	h := ecHash(k.Curve).New()
+	h := hashFuncs[sig.Format].New()
 	h.Write(data)
 	digest := h.Sum(nil)
 
@@ -775,7 +772,7 @@ func (k *skECDSAPublicKey) Verify(data []byte, sig *Signature) error {
 		return fmt.Errorf("ssh: signature type %s for key type %s", sig.Format, k.Type())
 	}
 
-	h := ecHash(k.Curve).New()
+	h := hashFuncs[sig.Format].New()
 	h.Write([]byte(k.application))
 	appDigest := h.Sum(nil)
 
@@ -874,7 +871,7 @@ func (k *skEd25519PublicKey) Verify(data []byte, sig *Signature) error {
 		return fmt.Errorf("invalid size %d for Ed25519 public key", l)
 	}
 
-	h := sha256.New()
+	h := hashFuncs[sig.Format].New()
 	h.Write([]byte(k.application))
 	appDigest := h.Sum(nil)
 
@@ -961,44 +958,20 @@ func (s *wrappedSigner) PublicKey() PublicKey {
 }
 
 func (s *wrappedSigner) Sign(rand io.Reader, data []byte) (*Signature, error) {
-	return s.SignWithAlgorithm(rand, data, "")
+	return s.SignWithAlgorithm(rand, data, s.pubKey.Type())
 }
 
 func (s *wrappedSigner) SignWithAlgorithm(rand io.Reader, data []byte, algorithm string) (*Signature, error) {
-	var hashFunc crypto.Hash
-
-	if _, ok := s.pubKey.(*rsaPublicKey); ok {
-		// RSA keys support a few hash functions determined by the requested signature algorithm
-		switch algorithm {
-		case "", SigAlgoRSA:
-			algorithm = SigAlgoRSA
-			hashFunc = crypto.SHA1
-		case SigAlgoRSASHA2256:
-			hashFunc = crypto.SHA256
-		case SigAlgoRSASHA2512:
-			hashFunc = crypto.SHA512
-		default:
-			return nil, fmt.Errorf("ssh: unsupported signature algorithm %s", algorithm)
-		}
-	} else {
-		// The only supported algorithm for all other key types is the same as the type of the key
-		if algorithm == "" {
-			algorithm = s.pubKey.Type()
-		} else if algorithm != s.pubKey.Type() {
-			return nil, fmt.Errorf("ssh: unsupported signature algorithm %s", algorithm)
-		}
-
-		switch key := s.pubKey.(type) {
-		case *dsaPublicKey:
-			hashFunc = crypto.SHA1
-		case *ecdsaPublicKey:
-			hashFunc = ecHash(key.Curve)
-		case ed25519PublicKey:
-		default:
-			return nil, fmt.Errorf("ssh: unsupported key type %T", key)
-		}
+	if algorithm == "" {
+		algorithm = s.pubKey.Type()
 	}
 
+	supportedAlgos := algorithmsForKeyFormat(s.pubKey.Type())
+	if !contains(supportedAlgos, algorithm) {
+		return nil, fmt.Errorf("ssh: unsupported signature algorithm %q for key format %q", algorithm, s.pubKey.Type())
+	}
+
+	hashFunc := hashFuncs[algorithm]
 	var digest []byte
 	if hashFunc != 0 {
 		h := hashFunc.New()
diff --git a/vendor/golang.org/x/crypto/ssh/knownhosts/knownhosts.go b/vendor/golang.org/x/crypto/ssh/knownhosts/knownhosts.go
new file mode 100644
index 0000000000..260cfe58c6
--- /dev/null
+++ b/vendor/golang.org/x/crypto/ssh/knownhosts/knownhosts.go
@@ -0,0 +1,540 @@
+// Copyright 2017 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 knownhosts implements a parser for the OpenSSH known_hosts
+// host key database, and provides utility functions for writing
+// OpenSSH compliant known_hosts files.
+package knownhosts
+
+import (
+	"bufio"
+	"bytes"
+	"crypto/hmac"
+	"crypto/rand"
+	"crypto/sha1"
+	"encoding/base64"
+	"errors"
+	"fmt"
+	"io"
+	"net"
+	"os"
+	"strings"
+
+	"golang.org/x/crypto/ssh"
+)
+
+// See the sshd manpage
+// (http://man.openbsd.org/sshd#SSH_KNOWN_HOSTS_FILE_FORMAT) for
+// background.
+
+type addr struct{ host, port string }
+
+func (a *addr) String() string {
+	h := a.host
+	if strings.Contains(h, ":") {
+		h = "[" + h + "]"
+	}
+	return h + ":" + a.port
+}
+
+type matcher interface {
+	match(addr) bool
+}
+
+type hostPattern struct {
+	negate bool
+	addr   addr
+}
+
+func (p *hostPattern) String() string {
+	n := ""
+	if p.negate {
+		n = "!"
+	}
+
+	return n + p.addr.String()
+}
+
+type hostPatterns []hostPattern
+
+func (ps hostPatterns) match(a addr) bool {
+	matched := false
+	for _, p := range ps {
+		if !p.match(a) {
+			continue
+		}
+		if p.negate {
+			return false
+		}
+		matched = true
+	}
+	return matched
+}
+
+// See
+// https://android.googlesource.com/platform/external/openssh/+/ab28f5495c85297e7a597c1ba62e996416da7c7e/addrmatch.c
+// The matching of * has no regard for separators, unlike filesystem globs
+func wildcardMatch(pat []byte, str []byte) bool {
+	for {
+		if len(pat) == 0 {
+			return len(str) == 0
+		}
+		if len(str) == 0 {
+			return false
+		}
+
+		if pat[0] == '*' {
+			if len(pat) == 1 {
+				return true
+			}
+
+			for j := range str {
+				if wildcardMatch(pat[1:], str[j:]) {
+					return true
+				}
+			}
+			return false
+		}
+
+		if pat[0] == '?' || pat[0] == str[0] {
+			pat = pat[1:]
+			str = str[1:]
+		} else {
+			return false
+		}
+	}
+}
+
+func (p *hostPattern) match(a addr) bool {
+	return wildcardMatch([]byte(p.addr.host), []byte(a.host)) && p.addr.port == a.port
+}
+
+type keyDBLine struct {
+	cert     bool
+	matcher  matcher
+	knownKey KnownKey
+}
+
+func serialize(k ssh.PublicKey) string {
+	return k.Type() + " " + base64.StdEncoding.EncodeToString(k.Marshal())
+}
+
+func (l *keyDBLine) match(a addr) bool {
+	return l.matcher.match(a)
+}
+
+type hostKeyDB struct {
+	// Serialized version of revoked keys
+	revoked map[string]*KnownKey
+	lines   []keyDBLine
+}
+
+func newHostKeyDB() *hostKeyDB {
+	db := &hostKeyDB{
+		revoked: make(map[string]*KnownKey),
+	}
+
+	return db
+}
+
+func keyEq(a, b ssh.PublicKey) bool {
+	return bytes.Equal(a.Marshal(), b.Marshal())
+}
+
+// IsAuthorityForHost can be used as a callback in ssh.CertChecker
+func (db *hostKeyDB) IsHostAuthority(remote ssh.PublicKey, address string) bool {
+	h, p, err := net.SplitHostPort(address)
+	if err != nil {
+		return false
+	}
+	a := addr{host: h, port: p}
+
+	for _, l := range db.lines {
+		if l.cert && keyEq(l.knownKey.Key, remote) && l.match(a) {
+			return true
+		}
+	}
+	return false
+}
+
+// IsRevoked can be used as a callback in ssh.CertChecker
+func (db *hostKeyDB) IsRevoked(key *ssh.Certificate) bool {
+	_, ok := db.revoked[string(key.Marshal())]
+	return ok
+}
+
+const markerCert = "@cert-authority"
+const markerRevoked = "@revoked"
+
+func nextWord(line []byte) (string, []byte) {
+	i := bytes.IndexAny(line, "\t ")
+	if i == -1 {
+		return string(line), nil
+	}
+
+	return string(line[:i]), bytes.TrimSpace(line[i:])
+}
+
+func parseLine(line []byte) (marker, host string, key ssh.PublicKey, err error) {
+	if w, next := nextWord(line); w == markerCert || w == markerRevoked {
+		marker = w
+		line = next
+	}
+
+	host, line = nextWord(line)
+	if len(line) == 0 {
+		return "", "", nil, errors.New("knownhosts: missing host pattern")
+	}
+
+	// ignore the keytype as it's in the key blob anyway.
+	_, line = nextWord(line)
+	if len(line) == 0 {
+		return "", "", nil, errors.New("knownhosts: missing key type pattern")
+	}
+
+	keyBlob, _ := nextWord(line)
+
+	keyBytes, err := base64.StdEncoding.DecodeString(keyBlob)
+	if err != nil {
+		return "", "", nil, err
+	}
+	key, err = ssh.ParsePublicKey(keyBytes)
+	if err != nil {
+		return "", "", nil, err
+	}
+
+	return marker, host, key, nil
+}
+
+func (db *hostKeyDB) parseLine(line []byte, filename string, linenum int) error {
+	marker, pattern, key, err := parseLine(line)
+	if err != nil {
+		return err
+	}
+
+	if marker == markerRevoked {
+		db.revoked[string(key.Marshal())] = &KnownKey{
+			Key:      key,
+			Filename: filename,
+			Line:     linenum,
+		}
+
+		return nil
+	}
+
+	entry := keyDBLine{
+		cert: marker == markerCert,
+		knownKey: KnownKey{
+			Filename: filename,
+			Line:     linenum,
+			Key:      key,
+		},
+	}
+
+	if pattern[0] == '|' {
+		entry.matcher, err = newHashedHost(pattern)
+	} else {
+		entry.matcher, err = newHostnameMatcher(pattern)
+	}
+
+	if err != nil {
+		return err
+	}
+
+	db.lines = append(db.lines, entry)
+	return nil
+}
+
+func newHostnameMatcher(pattern string) (matcher, error) {
+	var hps hostPatterns
+	for _, p := range strings.Split(pattern, ",") {
+		if len(p) == 0 {
+			continue
+		}
+
+		var a addr
+		var negate bool
+		if p[0] == '!' {
+			negate = true
+			p = p[1:]
+		}
+
+		if len(p) == 0 {
+			return nil, errors.New("knownhosts: negation without following hostname")
+		}
+
+		var err error
+		if p[0] == '[' {
+			a.host, a.port, err = net.SplitHostPort(p)
+			if err != nil {
+				return nil, err
+			}
+		} else {
+			a.host, a.port, err = net.SplitHostPort(p)
+			if err != nil {
+				a.host = p
+				a.port = "22"
+			}
+		}
+		hps = append(hps, hostPattern{
+			negate: negate,
+			addr:   a,
+		})
+	}
+	return hps, nil
+}
+
+// KnownKey represents a key declared in a known_hosts file.
+type KnownKey struct {
+	Key      ssh.PublicKey
+	Filename string
+	Line     int
+}
+
+func (k *KnownKey) String() string {
+	return fmt.Sprintf("%s:%d: %s", k.Filename, k.Line, serialize(k.Key))
+}
+
+// KeyError is returned if we did not find the key in the host key
+// database, or there was a mismatch.  Typically, in batch
+// applications, this should be interpreted as failure. Interactive
+// applications can offer an interactive prompt to the user.
+type KeyError struct {
+	// Want holds the accepted host keys. For each key algorithm,
+	// there can be one hostkey.  If Want is empty, the host is
+	// unknown. If Want is non-empty, there was a mismatch, which
+	// can signify a MITM attack.
+	Want []KnownKey
+}
+
+func (u *KeyError) Error() string {
+	if len(u.Want) == 0 {
+		return "knownhosts: key is unknown"
+	}
+	return "knownhosts: key mismatch"
+}
+
+// RevokedError is returned if we found a key that was revoked.
+type RevokedError struct {
+	Revoked KnownKey
+}
+
+func (r *RevokedError) Error() string {
+	return "knownhosts: key is revoked"
+}
+
+// check checks a key against the host database. This should not be
+// used for verifying certificates.
+func (db *hostKeyDB) check(address string, remote net.Addr, remoteKey ssh.PublicKey) error {
+	if revoked := db.revoked[string(remoteKey.Marshal())]; revoked != nil {
+		return &RevokedError{Revoked: *revoked}
+	}
+
+	host, port, err := net.SplitHostPort(remote.String())
+	if err != nil {
+		return fmt.Errorf("knownhosts: SplitHostPort(%s): %v", remote, err)
+	}
+
+	hostToCheck := addr{host, port}
+	if address != "" {
+		// Give preference to the hostname if available.
+		host, port, err := net.SplitHostPort(address)
+		if err != nil {
+			return fmt.Errorf("knownhosts: SplitHostPort(%s): %v", address, err)
+		}
+
+		hostToCheck = addr{host, port}
+	}
+
+	return db.checkAddr(hostToCheck, remoteKey)
+}
+
+// checkAddr checks if we can find the given public key for the
+// given address.  If we only find an entry for the IP address,
+// or only the hostname, then this still succeeds.
+func (db *hostKeyDB) checkAddr(a addr, remoteKey ssh.PublicKey) error {
+	// TODO(hanwen): are these the right semantics? What if there
+	// is just a key for the IP address, but not for the
+	// hostname?
+
+	// Algorithm => key.
+	knownKeys := map[string]KnownKey{}
+	for _, l := range db.lines {
+		if l.match(a) {
+			typ := l.knownKey.Key.Type()
+			if _, ok := knownKeys[typ]; !ok {
+				knownKeys[typ] = l.knownKey
+			}
+		}
+	}
+
+	keyErr := &KeyError{}
+	for _, v := range knownKeys {
+		keyErr.Want = append(keyErr.Want, v)
+	}
+
+	// Unknown remote host.
+	if len(knownKeys) == 0 {
+		return keyErr
+	}
+
+	// If the remote host starts using a different, unknown key type, we
+	// also interpret that as a mismatch.
+	if known, ok := knownKeys[remoteKey.Type()]; !ok || !keyEq(known.Key, remoteKey) {
+		return keyErr
+	}
+
+	return nil
+}
+
+// The Read function parses file contents.
+func (db *hostKeyDB) Read(r io.Reader, filename string) error {
+	scanner := bufio.NewScanner(r)
+
+	lineNum := 0
+	for scanner.Scan() {
+		lineNum++
+		line := scanner.Bytes()
+		line = bytes.TrimSpace(line)
+		if len(line) == 0 || line[0] == '#' {
+			continue
+		}
+
+		if err := db.parseLine(line, filename, lineNum); err != nil {
+			return fmt.Errorf("knownhosts: %s:%d: %v", filename, lineNum, err)
+		}
+	}
+	return scanner.Err()
+}
+
+// New creates a host key callback from the given OpenSSH host key
+// files. The returned callback is for use in
+// ssh.ClientConfig.HostKeyCallback. By preference, the key check
+// operates on the hostname if available, i.e. if a server changes its
+// IP address, the host key check will still succeed, even though a
+// record of the new IP address is not available.
+func New(files ...string) (ssh.HostKeyCallback, error) {
+	db := newHostKeyDB()
+	for _, fn := range files {
+		f, err := os.Open(fn)
+		if err != nil {
+			return nil, err
+		}
+		defer f.Close()
+		if err := db.Read(f, fn); err != nil {
+			return nil, err
+		}
+	}
+
+	var certChecker ssh.CertChecker
+	certChecker.IsHostAuthority = db.IsHostAuthority
+	certChecker.IsRevoked = db.IsRevoked
+	certChecker.HostKeyFallback = db.check
+
+	return certChecker.CheckHostKey, nil
+}
+
+// Normalize normalizes an address into the form used in known_hosts
+func Normalize(address string) string {
+	host, port, err := net.SplitHostPort(address)
+	if err != nil {
+		host = address
+		port = "22"
+	}
+	entry := host
+	if port != "22" {
+		entry = "[" + entry + "]:" + port
+	} else if strings.Contains(host, ":") && !strings.HasPrefix(host, "[") {
+		entry = "[" + entry + "]"
+	}
+	return entry
+}
+
+// Line returns a line to add append to the known_hosts files.
+func Line(addresses []string, key ssh.PublicKey) string {
+	var trimmed []string
+	for _, a := range addresses {
+		trimmed = append(trimmed, Normalize(a))
+	}
+
+	return strings.Join(trimmed, ",") + " " + serialize(key)
+}
+
+// HashHostname hashes the given hostname. The hostname is not
+// normalized before hashing.
+func HashHostname(hostname string) string {
+	// TODO(hanwen): check if we can safely normalize this always.
+	salt := make([]byte, sha1.Size)
+
+	_, err := rand.Read(salt)
+	if err != nil {
+		panic(fmt.Sprintf("crypto/rand failure %v", err))
+	}
+
+	hash := hashHost(hostname, salt)
+	return encodeHash(sha1HashType, salt, hash)
+}
+
+func decodeHash(encoded string) (hashType string, salt, hash []byte, err error) {
+	if len(encoded) == 0 || encoded[0] != '|' {
+		err = errors.New("knownhosts: hashed host must start with '|'")
+		return
+	}
+	components := strings.Split(encoded, "|")
+	if len(components) != 4 {
+		err = fmt.Errorf("knownhosts: got %d components, want 3", len(components))
+		return
+	}
+
+	hashType = components[1]
+	if salt, err = base64.StdEncoding.DecodeString(components[2]); err != nil {
+		return
+	}
+	if hash, err = base64.StdEncoding.DecodeString(components[3]); err != nil {
+		return
+	}
+	return
+}
+
+func encodeHash(typ string, salt []byte, hash []byte) string {
+	return strings.Join([]string{"",
+		typ,
+		base64.StdEncoding.EncodeToString(salt),
+		base64.StdEncoding.EncodeToString(hash),
+	}, "|")
+}
+
+// See https://android.googlesource.com/platform/external/openssh/+/ab28f5495c85297e7a597c1ba62e996416da7c7e/hostfile.c#120
+func hashHost(hostname string, salt []byte) []byte {
+	mac := hmac.New(sha1.New, salt)
+	mac.Write([]byte(hostname))
+	return mac.Sum(nil)
+}
+
+type hashedHost struct {
+	salt []byte
+	hash []byte
+}
+
+const sha1HashType = "1"
+
+func newHashedHost(encoded string) (*hashedHost, error) {
+	typ, salt, hash, err := decodeHash(encoded)
+	if err != nil {
+		return nil, err
+	}
+
+	// The type field seems for future algorithm agility, but it's
+	// actually hardcoded in openssh currently, see
+	// https://android.googlesource.com/platform/external/openssh/+/ab28f5495c85297e7a597c1ba62e996416da7c7e/hostfile.c#120
+	if typ != sha1HashType {
+		return nil, fmt.Errorf("knownhosts: got hash type %s, must be '1'", typ)
+	}
+
+	return &hashedHost{salt: salt, hash: hash}, nil
+}
+
+func (h *hashedHost) match(a addr) bool {
+	return bytes.Equal(hashHost(Normalize(a.String()), h.salt), h.hash)
+}
diff --git a/vendor/golang.org/x/crypto/ssh/messages.go b/vendor/golang.org/x/crypto/ssh/messages.go
index ac41a4168b..19bc67c464 100644
--- a/vendor/golang.org/x/crypto/ssh/messages.go
+++ b/vendor/golang.org/x/crypto/ssh/messages.go
@@ -141,6 +141,14 @@ type serviceAcceptMsg struct {
 	Service string `sshtype:"6"`
 }
 
+// See RFC 8308, section 2.3
+const msgExtInfo = 7
+
+type extInfoMsg struct {
+	NumExtensions uint32 `sshtype:"7"`
+	Payload       []byte `ssh:"rest"`
+}
+
 // See RFC 4252, section 5.
 const msgUserAuthRequest = 50
 
@@ -180,11 +188,11 @@ const msgUserAuthInfoRequest = 60
 const msgUserAuthInfoResponse = 61
 
 type userAuthInfoRequestMsg struct {
-	User               string `sshtype:"60"`
-	Instruction        string
-	DeprecatedLanguage string
-	NumPrompts         uint32
-	Prompts            []byte `ssh:"rest"`
+	Name        string `sshtype:"60"`
+	Instruction string
+	Language    string
+	NumPrompts  uint32
+	Prompts     []byte `ssh:"rest"`
 }
 
 // See RFC 4254, section 5.1.
@@ -782,6 +790,8 @@ func decode(packet []byte) (interface{}, error) {
 		msg = new(serviceRequestMsg)
 	case msgServiceAccept:
 		msg = new(serviceAcceptMsg)
+	case msgExtInfo:
+		msg = new(extInfoMsg)
 	case msgKexInit:
 		msg = new(kexInitMsg)
 	case msgKexDHInit:
@@ -843,6 +853,7 @@ var packetTypeNames = map[byte]string{
 	msgDisconnect:          "disconnectMsg",
 	msgServiceRequest:      "serviceRequestMsg",
 	msgServiceAccept:       "serviceAcceptMsg",
+	msgExtInfo:             "extInfoMsg",
 	msgKexInit:             "kexInitMsg",
 	msgKexDHInit:           "kexDHInitMsg",
 	msgKexDHReply:          "kexDHReplyMsg",
diff --git a/vendor/golang.org/x/crypto/ssh/server.go b/vendor/golang.org/x/crypto/ssh/server.go
index 7d42a8c88d..70045bdfd8 100644
--- a/vendor/golang.org/x/crypto/ssh/server.go
+++ b/vendor/golang.org/x/crypto/ssh/server.go
@@ -120,7 +120,7 @@ type ServerConfig struct {
 }
 
 // AddHostKey adds a private key as a host key. If an existing host
-// key exists with the same algorithm, it is overwritten. Each server
+// key exists with the same public key format, it is replaced. Each server
 // config must have at least one host key.
 func (s *ServerConfig) AddHostKey(key Signer) {
 	for i, k := range s.hostKeys {
@@ -212,9 +212,10 @@ func NewServerConn(c net.Conn, config *ServerConfig) (*ServerConn, <-chan NewCha
 }
 
 // signAndMarshal signs the data with the appropriate algorithm,
-// and serializes the result in SSH wire format.
-func signAndMarshal(k Signer, rand io.Reader, data []byte) ([]byte, error) {
-	sig, err := k.Sign(rand, data)
+// and serializes the result in SSH wire format. algo is the negotiate
+// algorithm and may be a certificate type.
+func signAndMarshal(k AlgorithmSigner, rand io.Reader, data []byte, algo string) ([]byte, error) {
+	sig, err := k.SignWithAlgorithm(rand, data, underlyingAlgo(algo))
 	if err != nil {
 		return nil, err
 	}
@@ -284,7 +285,7 @@ func (s *connection) serverHandshake(config *ServerConfig) (*Permissions, error)
 
 func isAcceptableAlgo(algo string) bool {
 	switch algo {
-	case KeyAlgoRSA, KeyAlgoDSA, KeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoECDSA521, KeyAlgoSKECDSA256, KeyAlgoED25519, KeyAlgoSKED25519,
+	case KeyAlgoRSA, KeyAlgoRSASHA256, KeyAlgoRSASHA512, KeyAlgoDSA, KeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoECDSA521, KeyAlgoSKECDSA256, KeyAlgoED25519, KeyAlgoSKED25519,
 		CertAlgoRSAv01, CertAlgoDSAv01, CertAlgoECDSA256v01, CertAlgoECDSA384v01, CertAlgoECDSA521v01, CertAlgoSKECDSA256v01, CertAlgoED25519v01, CertAlgoSKED25519v01:
 		return true
 	}
@@ -553,6 +554,7 @@ userAuthLoop:
 				if !ok || len(payload) > 0 {
 					return nil, parseError(msgUserAuthRequest)
 				}
+
 				// Ensure the public key algo and signature algo
 				// are supported.  Compare the private key
 				// algorithm name that corresponds to algo with
@@ -562,7 +564,12 @@ userAuthLoop:
 					authErr = fmt.Errorf("ssh: algorithm %q not accepted", sig.Format)
 					break
 				}
-				signedData := buildDataSignedForAuth(sessionID, userAuthReq, algoBytes, pubKeyData)
+				if underlyingAlgo(algo) != sig.Format {
+					authErr = fmt.Errorf("ssh: signature %q not compatible with selected algorithm %q", sig.Format, algo)
+					break
+				}
+
+				signedData := buildDataSignedForAuth(sessionID, userAuthReq, algo, pubKeyData)
 
 				if err := pubKey.Verify(signedData, sig); err != nil {
 					return nil, err
@@ -572,6 +579,10 @@ userAuthLoop:
 				perms = candidate.perms
 			}
 		case "gssapi-with-mic":
+			if config.GSSAPIWithMICConfig == nil {
+				authErr = errors.New("ssh: gssapi-with-mic auth not configured")
+				break
+			}
 			gssapiConfig := config.GSSAPIWithMICConfig
 			userAuthRequestGSSAPI, err := parseGSSAPIPayload(userAuthReq.Payload)
 			if err != nil {
@@ -629,6 +640,30 @@ userAuthLoop:
 		}
 
 		authFailures++
+		if config.MaxAuthTries > 0 && authFailures >= config.MaxAuthTries {
+			// If we have hit the max attempts, don't bother sending the
+			// final SSH_MSG_USERAUTH_FAILURE message, since there are
+			// no more authentication methods which can be attempted,
+			// and this message may cause the client to re-attempt
+			// authentication while we send the disconnect message.
+			// Continue, and trigger the disconnect at the start of
+			// the loop.
+			//
+			// The SSH specification is somewhat confusing about this,
+			// RFC 4252 Section 5.1 requires each authentication failure
+			// be responded to with a respective SSH_MSG_USERAUTH_FAILURE
+			// message, but Section 4 says the server should disconnect
+			// after some number of attempts, but it isn't explicit which
+			// message should take precedence (i.e. should there be a failure
+			// message than a disconnect message, or if we are going to
+			// disconnect, should we only send that message.)
+			//
+			// Either way, OpenSSH disconnects immediately after the last
+			// failed authnetication attempt, and given they are typically
+			// considered the golden implementation it seems reasonable
+			// to match that behavior.
+			continue
+		}
 
 		var failureMsg userAuthFailureMsg
 		if config.PasswordCallback != nil {
@@ -666,7 +701,7 @@ type sshClientKeyboardInteractive struct {
 	*connection
 }
 
-func (c *sshClientKeyboardInteractive) Challenge(user, instruction string, questions []string, echos []bool) (answers []string, err error) {
+func (c *sshClientKeyboardInteractive) Challenge(name, instruction string, questions []string, echos []bool) (answers []string, err error) {
 	if len(questions) != len(echos) {
 		return nil, errors.New("ssh: echos and questions must have equal length")
 	}
@@ -678,6 +713,7 @@ func (c *sshClientKeyboardInteractive) Challenge(user, instruction string, quest
 	}
 
 	if err := c.transport.writePacket(Marshal(&userAuthInfoRequestMsg{
+		Name:        name,
 		Instruction: instruction,
 		NumPrompts:  uint32(len(questions)),
 		Prompts:     prompts,
diff --git a/vendor/golang.org/x/crypto/ssh/session.go b/vendor/golang.org/x/crypto/ssh/session.go
index d3321f6b78..eca31a22d5 100644
--- a/vendor/golang.org/x/crypto/ssh/session.go
+++ b/vendor/golang.org/x/crypto/ssh/session.go
@@ -85,6 +85,7 @@ const (
 	IXANY         = 39
 	IXOFF         = 40
 	IMAXBEL       = 41
+	IUTF8         = 42 // RFC 8160
 	ISIG          = 50
 	ICANON        = 51
 	XCASE         = 52
diff --git a/vendor/golang.org/x/crypto/ssh/terminal/terminal.go b/vendor/golang.org/x/crypto/ssh/terminal/terminal.go
new file mode 100644
index 0000000000..a4d1919a9e
--- /dev/null
+++ b/vendor/golang.org/x/crypto/ssh/terminal/terminal.go
@@ -0,0 +1,76 @@
+// Copyright 2011 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 terminal provides support functions for dealing with terminals, as
+// commonly found on UNIX systems.
+//
+// Deprecated: this package moved to golang.org/x/term.
+package terminal
+
+import (
+	"io"
+
+	"golang.org/x/term"
+)
+
+// EscapeCodes contains escape sequences that can be written to the terminal in
+// order to achieve different styles of text.
+type EscapeCodes = term.EscapeCodes
+
+// Terminal contains the state for running a VT100 terminal that is capable of
+// reading lines of input.
+type Terminal = term.Terminal
+
+// NewTerminal runs a VT100 terminal on the given ReadWriter. If the ReadWriter is
+// a local terminal, that terminal must first have been put into raw mode.
+// prompt is a string that is written at the start of each input line (i.e.
+// "> ").
+func NewTerminal(c io.ReadWriter, prompt string) *Terminal {
+	return term.NewTerminal(c, prompt)
+}
+
+// ErrPasteIndicator may be returned from ReadLine as the error, in addition
+// to valid line data. It indicates that bracketed paste mode is enabled and
+// that the returned line consists only of pasted data. Programs may wish to
+// interpret pasted data more literally than typed data.
+var ErrPasteIndicator = term.ErrPasteIndicator
+
+// State contains the state of a terminal.
+type State = term.State
+
+// IsTerminal returns whether the given file descriptor is a terminal.
+func IsTerminal(fd int) bool {
+	return term.IsTerminal(fd)
+}
+
+// ReadPassword reads a line of input from a terminal without local echo.  This
+// is commonly used for inputting passwords and other sensitive data. The slice
+// returned does not include the \n.
+func ReadPassword(fd int) ([]byte, error) {
+	return term.ReadPassword(fd)
+}
+
+// MakeRaw puts the terminal connected to the given file descriptor into raw
+// mode and returns the previous state of the terminal so that it can be
+// restored.
+func MakeRaw(fd int) (*State, error) {
+	return term.MakeRaw(fd)
+}
+
+// Restore restores the terminal connected to the given file descriptor to a
+// previous state.
+func Restore(fd int, oldState *State) error {
+	return term.Restore(fd, oldState)
+}
+
+// GetState returns the current state of a terminal which may be useful to
+// restore the terminal after a signal.
+func GetState(fd int) (*State, error) {
+	return term.GetState(fd)
+}
+
+// GetSize returns the dimensions of the given terminal.
+func GetSize(fd int) (width, height int, err error) {
+	return term.GetSize(fd)
+}
diff --git a/vendor/golang.org/x/crypto/ssh/transport.go b/vendor/golang.org/x/crypto/ssh/transport.go
index 49ddc2e7de..acf5a21bbb 100644
--- a/vendor/golang.org/x/crypto/ssh/transport.go
+++ b/vendor/golang.org/x/crypto/ssh/transport.go
@@ -238,15 +238,19 @@ var (
 // (to setup server->client keys) or clientKeys (for client->server keys).
 func newPacketCipher(d direction, algs directionAlgorithms, kex *kexResult) (packetCipher, error) {
 	cipherMode := cipherModes[algs.Cipher]
-	macMode := macModes[algs.MAC]
 
 	iv := make([]byte, cipherMode.ivSize)
 	key := make([]byte, cipherMode.keySize)
-	macKey := make([]byte, macMode.keySize)
 
 	generateKeyMaterial(iv, d.ivTag, kex)
 	generateKeyMaterial(key, d.keyTag, kex)
-	generateKeyMaterial(macKey, d.macKeyTag, kex)
+
+	var macKey []byte
+	if !aeadCiphers[algs.Cipher] {
+		macMode := macModes[algs.MAC]
+		macKey = make([]byte, macMode.keySize)
+		generateKeyMaterial(macKey, d.macKeyTag, kex)
+	}
 
 	return cipherModes[algs.Cipher].create(key, iv, macKey, algs)
 }
diff --git a/vendor/golang.org/x/crypto/tea/cipher.go b/vendor/golang.org/x/crypto/tea/cipher.go
new file mode 100644
index 0000000000..c1ff90e048
--- /dev/null
+++ b/vendor/golang.org/x/crypto/tea/cipher.go
@@ -0,0 +1,116 @@
+// Copyright 2015 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 tea implements the TEA algorithm, as defined in Needham and
+// Wheeler's 1994 technical report, “TEA, a Tiny Encryption Algorithm”. See
+// http://www.cix.co.uk/~klockstone/tea.pdf for details.
+//
+// TEA is a legacy cipher and its short block size makes it vulnerable to
+// birthday bound attacks (see https://sweet32.info). It should only be used
+// where compatibility with legacy systems, not security, is the goal.
+//
+// Deprecated: any new system should use AES (from crypto/aes, if necessary in
+// an AEAD mode like crypto/cipher.NewGCM) or XChaCha20-Poly1305 (from
+// golang.org/x/crypto/chacha20poly1305).
+package tea
+
+import (
+	"crypto/cipher"
+	"encoding/binary"
+	"errors"
+)
+
+const (
+	// BlockSize is the size of a TEA block, in bytes.
+	BlockSize = 8
+
+	// KeySize is the size of a TEA key, in bytes.
+	KeySize = 16
+
+	// delta is the TEA key schedule constant.
+	delta = 0x9e3779b9
+
+	// numRounds is the standard number of rounds in TEA.
+	numRounds = 64
+)
+
+// tea is an instance of the TEA cipher with a particular key.
+type tea struct {
+	key    [16]byte
+	rounds int
+}
+
+// NewCipher returns an instance of the TEA cipher with the standard number of
+// rounds. The key argument must be 16 bytes long.
+func NewCipher(key []byte) (cipher.Block, error) {
+	return NewCipherWithRounds(key, numRounds)
+}
+
+// NewCipherWithRounds returns an instance of the TEA cipher with a given
+// number of rounds, which must be even. The key argument must be 16 bytes
+// long.
+func NewCipherWithRounds(key []byte, rounds int) (cipher.Block, error) {
+	if len(key) != 16 {
+		return nil, errors.New("tea: incorrect key size")
+	}
+
+	if rounds&1 != 0 {
+		return nil, errors.New("tea: odd number of rounds specified")
+	}
+
+	c := &tea{
+		rounds: rounds,
+	}
+	copy(c.key[:], key)
+
+	return c, nil
+}
+
+// BlockSize returns the TEA block size, which is eight bytes. It is necessary
+// to satisfy the Block interface in the package "crypto/cipher".
+func (*tea) BlockSize() int {
+	return BlockSize
+}
+
+// Encrypt encrypts the 8 byte buffer src using the key in t and stores the
+// result in dst. Note that for amounts of data larger than a block, it is not
+// safe to just call Encrypt on successive blocks; instead, use an encryption
+// mode like CBC (see crypto/cipher/cbc.go).
+func (t *tea) Encrypt(dst, src []byte) {
+	e := binary.BigEndian
+	v0, v1 := e.Uint32(src), e.Uint32(src[4:])
+	k0, k1, k2, k3 := e.Uint32(t.key[0:]), e.Uint32(t.key[4:]), e.Uint32(t.key[8:]), e.Uint32(t.key[12:])
+
+	sum := uint32(0)
+	delta := uint32(delta)
+
+	for i := 0; i < t.rounds/2; i++ {
+		sum += delta
+		v0 += ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1)
+		v1 += ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3)
+	}
+
+	e.PutUint32(dst, v0)
+	e.PutUint32(dst[4:], v1)
+}
+
+// Decrypt decrypts the 8 byte buffer src using the key in t and stores the
+// result in dst.
+func (t *tea) Decrypt(dst, src []byte) {
+	e := binary.BigEndian
+	v0, v1 := e.Uint32(src), e.Uint32(src[4:])
+	k0, k1, k2, k3 := e.Uint32(t.key[0:]), e.Uint32(t.key[4:]), e.Uint32(t.key[8:]), e.Uint32(t.key[12:])
+
+	delta := uint32(delta)
+	sum := delta * uint32(t.rounds/2) // in general, sum = delta * n
+
+	for i := 0; i < t.rounds/2; i++ {
+		v1 -= ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3)
+		v0 -= ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1)
+		sum -= delta
+	}
+
+	e.PutUint32(dst, v0)
+	e.PutUint32(dst[4:], v1)
+}
diff --git a/vendor/golang.org/x/crypto/twofish/twofish.go b/vendor/golang.org/x/crypto/twofish/twofish.go
new file mode 100644
index 0000000000..1197d75132
--- /dev/null
+++ b/vendor/golang.org/x/crypto/twofish/twofish.go
@@ -0,0 +1,348 @@
+// Copyright 2011 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 twofish implements Bruce Schneier's Twofish encryption algorithm.
+//
+// Deprecated: Twofish is a legacy cipher and should not be used for new
+// applications. Also, this package does not and will not provide an optimized
+// implementation. Instead, use AES (from crypto/aes, if necessary in an AEAD
+// mode like crypto/cipher.NewGCM) or XChaCha20-Poly1305 (from
+// golang.org/x/crypto/chacha20poly1305).
+package twofish // import "golang.org/x/crypto/twofish"
+
+// Twofish is defined in https://www.schneier.com/paper-twofish-paper.pdf [TWOFISH]
+
+// This code is a port of the LibTom C implementation.
+// See http://libtom.org/?page=features&newsitems=5&whatfile=crypt.
+// LibTomCrypt is free for all purposes under the public domain.
+// It was heavily inspired by the go blowfish package.
+
+import "strconv"
+
+// BlockSize is the constant block size of Twofish.
+const BlockSize = 16
+
+const mdsPolynomial = 0x169 // x^8 + x^6 + x^5 + x^3 + 1, see [TWOFISH] 4.2
+const rsPolynomial = 0x14d  // x^8 + x^6 + x^3 + x^2 + 1, see [TWOFISH] 4.3
+
+// A Cipher is an instance of Twofish encryption using a particular key.
+type Cipher struct {
+	s [4][256]uint32
+	k [40]uint32
+}
+
+type KeySizeError int
+
+func (k KeySizeError) Error() string {
+	return "crypto/twofish: invalid key size " + strconv.Itoa(int(k))
+}
+
+// NewCipher creates and returns a Cipher.
+// The key argument should be the Twofish key, 16, 24 or 32 bytes.
+func NewCipher(key []byte) (*Cipher, error) {
+	keylen := len(key)
+
+	if keylen != 16 && keylen != 24 && keylen != 32 {
+		return nil, KeySizeError(keylen)
+	}
+
+	// k is the number of 64 bit words in key
+	k := keylen / 8
+
+	// Create the S[..] words
+	var S [4 * 4]byte
+	for i := 0; i < k; i++ {
+		// Computes [y0 y1 y2 y3] = rs . [x0 x1 x2 x3 x4 x5 x6 x7]
+		for j, rsRow := range rs {
+			for k, rsVal := range rsRow {
+				S[4*i+j] ^= gfMult(key[8*i+k], rsVal, rsPolynomial)
+			}
+		}
+	}
+
+	// Calculate subkeys
+	c := new(Cipher)
+	var tmp [4]byte
+	for i := byte(0); i < 20; i++ {
+		// A = h(p * 2x, Me)
+		for j := range tmp {
+			tmp[j] = 2 * i
+		}
+		A := h(tmp[:], key, 0)
+
+		// B = rolc(h(p * (2x + 1), Mo), 8)
+		for j := range tmp {
+			tmp[j] = 2*i + 1
+		}
+		B := h(tmp[:], key, 1)
+		B = rol(B, 8)
+
+		c.k[2*i] = A + B
+
+		// K[2i+1] = (A + 2B) <<< 9
+		c.k[2*i+1] = rol(2*B+A, 9)
+	}
+
+	// Calculate sboxes
+	switch k {
+	case 2:
+		for i := range c.s[0] {
+			c.s[0][i] = mdsColumnMult(sbox[1][sbox[0][sbox[0][byte(i)]^S[0]]^S[4]], 0)
+			c.s[1][i] = mdsColumnMult(sbox[0][sbox[0][sbox[1][byte(i)]^S[1]]^S[5]], 1)
+			c.s[2][i] = mdsColumnMult(sbox[1][sbox[1][sbox[0][byte(i)]^S[2]]^S[6]], 2)
+			c.s[3][i] = mdsColumnMult(sbox[0][sbox[1][sbox[1][byte(i)]^S[3]]^S[7]], 3)
+		}
+	case 3:
+		for i := range c.s[0] {
+			c.s[0][i] = mdsColumnMult(sbox[1][sbox[0][sbox[0][sbox[1][byte(i)]^S[0]]^S[4]]^S[8]], 0)
+			c.s[1][i] = mdsColumnMult(sbox[0][sbox[0][sbox[1][sbox[1][byte(i)]^S[1]]^S[5]]^S[9]], 1)
+			c.s[2][i] = mdsColumnMult(sbox[1][sbox[1][sbox[0][sbox[0][byte(i)]^S[2]]^S[6]]^S[10]], 2)
+			c.s[3][i] = mdsColumnMult(sbox[0][sbox[1][sbox[1][sbox[0][byte(i)]^S[3]]^S[7]]^S[11]], 3)
+		}
+	default:
+		for i := range c.s[0] {
+			c.s[0][i] = mdsColumnMult(sbox[1][sbox[0][sbox[0][sbox[1][sbox[1][byte(i)]^S[0]]^S[4]]^S[8]]^S[12]], 0)
+			c.s[1][i] = mdsColumnMult(sbox[0][sbox[0][sbox[1][sbox[1][sbox[0][byte(i)]^S[1]]^S[5]]^S[9]]^S[13]], 1)
+			c.s[2][i] = mdsColumnMult(sbox[1][sbox[1][sbox[0][sbox[0][sbox[0][byte(i)]^S[2]]^S[6]]^S[10]]^S[14]], 2)
+			c.s[3][i] = mdsColumnMult(sbox[0][sbox[1][sbox[1][sbox[0][sbox[1][byte(i)]^S[3]]^S[7]]^S[11]]^S[15]], 3)
+		}
+	}
+
+	return c, nil
+}
+
+// BlockSize returns the Twofish block size, 16 bytes.
+func (c *Cipher) BlockSize() int { return BlockSize }
+
+// store32l stores src in dst in little-endian form.
+func store32l(dst []byte, src uint32) {
+	dst[0] = byte(src)
+	dst[1] = byte(src >> 8)
+	dst[2] = byte(src >> 16)
+	dst[3] = byte(src >> 24)
+	return
+}
+
+// load32l reads a little-endian uint32 from src.
+func load32l(src []byte) uint32 {
+	return uint32(src[0]) | uint32(src[1])<<8 | uint32(src[2])<<16 | uint32(src[3])<<24
+}
+
+// rol returns x after a left circular rotation of y bits.
+func rol(x, y uint32) uint32 {
+	return (x << (y & 31)) | (x >> (32 - (y & 31)))
+}
+
+// ror returns x after a right circular rotation of y bits.
+func ror(x, y uint32) uint32 {
+	return (x >> (y & 31)) | (x << (32 - (y & 31)))
+}
+
+// The RS matrix. See [TWOFISH] 4.3
+var rs = [4][8]byte{
+	{0x01, 0xA4, 0x55, 0x87, 0x5A, 0x58, 0xDB, 0x9E},
+	{0xA4, 0x56, 0x82, 0xF3, 0x1E, 0xC6, 0x68, 0xE5},
+	{0x02, 0xA1, 0xFC, 0xC1, 0x47, 0xAE, 0x3D, 0x19},
+	{0xA4, 0x55, 0x87, 0x5A, 0x58, 0xDB, 0x9E, 0x03},
+}
+
+// sbox tables
+var sbox = [2][256]byte{
+	{
+		0xa9, 0x67, 0xb3, 0xe8, 0x04, 0xfd, 0xa3, 0x76, 0x9a, 0x92, 0x80, 0x78, 0xe4, 0xdd, 0xd1, 0x38,
+		0x0d, 0xc6, 0x35, 0x98, 0x18, 0xf7, 0xec, 0x6c, 0x43, 0x75, 0x37, 0x26, 0xfa, 0x13, 0x94, 0x48,
+		0xf2, 0xd0, 0x8b, 0x30, 0x84, 0x54, 0xdf, 0x23, 0x19, 0x5b, 0x3d, 0x59, 0xf3, 0xae, 0xa2, 0x82,
+		0x63, 0x01, 0x83, 0x2e, 0xd9, 0x51, 0x9b, 0x7c, 0xa6, 0xeb, 0xa5, 0xbe, 0x16, 0x0c, 0xe3, 0x61,
+		0xc0, 0x8c, 0x3a, 0xf5, 0x73, 0x2c, 0x25, 0x0b, 0xbb, 0x4e, 0x89, 0x6b, 0x53, 0x6a, 0xb4, 0xf1,
+		0xe1, 0xe6, 0xbd, 0x45, 0xe2, 0xf4, 0xb6, 0x66, 0xcc, 0x95, 0x03, 0x56, 0xd4, 0x1c, 0x1e, 0xd7,
+		0xfb, 0xc3, 0x8e, 0xb5, 0xe9, 0xcf, 0xbf, 0xba, 0xea, 0x77, 0x39, 0xaf, 0x33, 0xc9, 0x62, 0x71,
+		0x81, 0x79, 0x09, 0xad, 0x24, 0xcd, 0xf9, 0xd8, 0xe5, 0xc5, 0xb9, 0x4d, 0x44, 0x08, 0x86, 0xe7,
+		0xa1, 0x1d, 0xaa, 0xed, 0x06, 0x70, 0xb2, 0xd2, 0x41, 0x7b, 0xa0, 0x11, 0x31, 0xc2, 0x27, 0x90,
+		0x20, 0xf6, 0x60, 0xff, 0x96, 0x5c, 0xb1, 0xab, 0x9e, 0x9c, 0x52, 0x1b, 0x5f, 0x93, 0x0a, 0xef,
+		0x91, 0x85, 0x49, 0xee, 0x2d, 0x4f, 0x8f, 0x3b, 0x47, 0x87, 0x6d, 0x46, 0xd6, 0x3e, 0x69, 0x64,
+		0x2a, 0xce, 0xcb, 0x2f, 0xfc, 0x97, 0x05, 0x7a, 0xac, 0x7f, 0xd5, 0x1a, 0x4b, 0x0e, 0xa7, 0x5a,
+		0x28, 0x14, 0x3f, 0x29, 0x88, 0x3c, 0x4c, 0x02, 0xb8, 0xda, 0xb0, 0x17, 0x55, 0x1f, 0x8a, 0x7d,
+		0x57, 0xc7, 0x8d, 0x74, 0xb7, 0xc4, 0x9f, 0x72, 0x7e, 0x15, 0x22, 0x12, 0x58, 0x07, 0x99, 0x34,
+		0x6e, 0x50, 0xde, 0x68, 0x65, 0xbc, 0xdb, 0xf8, 0xc8, 0xa8, 0x2b, 0x40, 0xdc, 0xfe, 0x32, 0xa4,
+		0xca, 0x10, 0x21, 0xf0, 0xd3, 0x5d, 0x0f, 0x00, 0x6f, 0x9d, 0x36, 0x42, 0x4a, 0x5e, 0xc1, 0xe0,
+	},
+	{
+		0x75, 0xf3, 0xc6, 0xf4, 0xdb, 0x7b, 0xfb, 0xc8, 0x4a, 0xd3, 0xe6, 0x6b, 0x45, 0x7d, 0xe8, 0x4b,
+		0xd6, 0x32, 0xd8, 0xfd, 0x37, 0x71, 0xf1, 0xe1, 0x30, 0x0f, 0xf8, 0x1b, 0x87, 0xfa, 0x06, 0x3f,
+		0x5e, 0xba, 0xae, 0x5b, 0x8a, 0x00, 0xbc, 0x9d, 0x6d, 0xc1, 0xb1, 0x0e, 0x80, 0x5d, 0xd2, 0xd5,
+		0xa0, 0x84, 0x07, 0x14, 0xb5, 0x90, 0x2c, 0xa3, 0xb2, 0x73, 0x4c, 0x54, 0x92, 0x74, 0x36, 0x51,
+		0x38, 0xb0, 0xbd, 0x5a, 0xfc, 0x60, 0x62, 0x96, 0x6c, 0x42, 0xf7, 0x10, 0x7c, 0x28, 0x27, 0x8c,
+		0x13, 0x95, 0x9c, 0xc7, 0x24, 0x46, 0x3b, 0x70, 0xca, 0xe3, 0x85, 0xcb, 0x11, 0xd0, 0x93, 0xb8,
+		0xa6, 0x83, 0x20, 0xff, 0x9f, 0x77, 0xc3, 0xcc, 0x03, 0x6f, 0x08, 0xbf, 0x40, 0xe7, 0x2b, 0xe2,
+		0x79, 0x0c, 0xaa, 0x82, 0x41, 0x3a, 0xea, 0xb9, 0xe4, 0x9a, 0xa4, 0x97, 0x7e, 0xda, 0x7a, 0x17,
+		0x66, 0x94, 0xa1, 0x1d, 0x3d, 0xf0, 0xde, 0xb3, 0x0b, 0x72, 0xa7, 0x1c, 0xef, 0xd1, 0x53, 0x3e,
+		0x8f, 0x33, 0x26, 0x5f, 0xec, 0x76, 0x2a, 0x49, 0x81, 0x88, 0xee, 0x21, 0xc4, 0x1a, 0xeb, 0xd9,
+		0xc5, 0x39, 0x99, 0xcd, 0xad, 0x31, 0x8b, 0x01, 0x18, 0x23, 0xdd, 0x1f, 0x4e, 0x2d, 0xf9, 0x48,
+		0x4f, 0xf2, 0x65, 0x8e, 0x78, 0x5c, 0x58, 0x19, 0x8d, 0xe5, 0x98, 0x57, 0x67, 0x7f, 0x05, 0x64,
+		0xaf, 0x63, 0xb6, 0xfe, 0xf5, 0xb7, 0x3c, 0xa5, 0xce, 0xe9, 0x68, 0x44, 0xe0, 0x4d, 0x43, 0x69,
+		0x29, 0x2e, 0xac, 0x15, 0x59, 0xa8, 0x0a, 0x9e, 0x6e, 0x47, 0xdf, 0x34, 0x35, 0x6a, 0xcf, 0xdc,
+		0x22, 0xc9, 0xc0, 0x9b, 0x89, 0xd4, 0xed, 0xab, 0x12, 0xa2, 0x0d, 0x52, 0xbb, 0x02, 0x2f, 0xa9,
+		0xd7, 0x61, 0x1e, 0xb4, 0x50, 0x04, 0xf6, 0xc2, 0x16, 0x25, 0x86, 0x56, 0x55, 0x09, 0xbe, 0x91,
+	},
+}
+
+// gfMult returns a·b in GF(2^8)/p
+func gfMult(a, b byte, p uint32) byte {
+	B := [2]uint32{0, uint32(b)}
+	P := [2]uint32{0, p}
+	var result uint32
+
+	// branchless GF multiplier
+	for i := 0; i < 7; i++ {
+		result ^= B[a&1]
+		a >>= 1
+		B[1] = P[B[1]>>7] ^ (B[1] << 1)
+	}
+	result ^= B[a&1]
+	return byte(result)
+}
+
+// mdsColumnMult calculates y{col} where [y0 y1 y2 y3] = MDS · [x0]
+func mdsColumnMult(in byte, col int) uint32 {
+	mul01 := in
+	mul5B := gfMult(in, 0x5B, mdsPolynomial)
+	mulEF := gfMult(in, 0xEF, mdsPolynomial)
+
+	switch col {
+	case 0:
+		return uint32(mul01) | uint32(mul5B)<<8 | uint32(mulEF)<<16 | uint32(mulEF)<<24
+	case 1:
+		return uint32(mulEF) | uint32(mulEF)<<8 | uint32(mul5B)<<16 | uint32(mul01)<<24
+	case 2:
+		return uint32(mul5B) | uint32(mulEF)<<8 | uint32(mul01)<<16 | uint32(mulEF)<<24
+	case 3:
+		return uint32(mul5B) | uint32(mul01)<<8 | uint32(mulEF)<<16 | uint32(mul5B)<<24
+	}
+
+	panic("unreachable")
+}
+
+// h implements the S-box generation function. See [TWOFISH] 4.3.5
+func h(in, key []byte, offset int) uint32 {
+	var y [4]byte
+	for x := range y {
+		y[x] = in[x]
+	}
+	switch len(key) / 8 {
+	case 4:
+		y[0] = sbox[1][y[0]] ^ key[4*(6+offset)+0]
+		y[1] = sbox[0][y[1]] ^ key[4*(6+offset)+1]
+		y[2] = sbox[0][y[2]] ^ key[4*(6+offset)+2]
+		y[3] = sbox[1][y[3]] ^ key[4*(6+offset)+3]
+		fallthrough
+	case 3:
+		y[0] = sbox[1][y[0]] ^ key[4*(4+offset)+0]
+		y[1] = sbox[1][y[1]] ^ key[4*(4+offset)+1]
+		y[2] = sbox[0][y[2]] ^ key[4*(4+offset)+2]
+		y[3] = sbox[0][y[3]] ^ key[4*(4+offset)+3]
+		fallthrough
+	case 2:
+		y[0] = sbox[1][sbox[0][sbox[0][y[0]]^key[4*(2+offset)+0]]^key[4*(0+offset)+0]]
+		y[1] = sbox[0][sbox[0][sbox[1][y[1]]^key[4*(2+offset)+1]]^key[4*(0+offset)+1]]
+		y[2] = sbox[1][sbox[1][sbox[0][y[2]]^key[4*(2+offset)+2]]^key[4*(0+offset)+2]]
+		y[3] = sbox[0][sbox[1][sbox[1][y[3]]^key[4*(2+offset)+3]]^key[4*(0+offset)+3]]
+	}
+	// [y0 y1 y2 y3] = MDS . [x0 x1 x2 x3]
+	var mdsMult uint32
+	for i := range y {
+		mdsMult ^= mdsColumnMult(y[i], i)
+	}
+	return mdsMult
+}
+
+// Encrypt encrypts a 16-byte block from src to dst, which may overlap.
+// Note that for amounts of data larger than a block,
+// it is not safe to just call Encrypt on successive blocks;
+// instead, use an encryption mode like CBC (see crypto/cipher/cbc.go).
+func (c *Cipher) Encrypt(dst, src []byte) {
+	S1 := c.s[0]
+	S2 := c.s[1]
+	S3 := c.s[2]
+	S4 := c.s[3]
+
+	// Load input
+	ia := load32l(src[0:4])
+	ib := load32l(src[4:8])
+	ic := load32l(src[8:12])
+	id := load32l(src[12:16])
+
+	// Pre-whitening
+	ia ^= c.k[0]
+	ib ^= c.k[1]
+	ic ^= c.k[2]
+	id ^= c.k[3]
+
+	for i := 0; i < 8; i++ {
+		k := c.k[8+i*4 : 12+i*4]
+		t2 := S2[byte(ib)] ^ S3[byte(ib>>8)] ^ S4[byte(ib>>16)] ^ S1[byte(ib>>24)]
+		t1 := S1[byte(ia)] ^ S2[byte(ia>>8)] ^ S3[byte(ia>>16)] ^ S4[byte(ia>>24)] + t2
+		ic = ror(ic^(t1+k[0]), 1)
+		id = rol(id, 1) ^ (t2 + t1 + k[1])
+
+		t2 = S2[byte(id)] ^ S3[byte(id>>8)] ^ S4[byte(id>>16)] ^ S1[byte(id>>24)]
+		t1 = S1[byte(ic)] ^ S2[byte(ic>>8)] ^ S3[byte(ic>>16)] ^ S4[byte(ic>>24)] + t2
+		ia = ror(ia^(t1+k[2]), 1)
+		ib = rol(ib, 1) ^ (t2 + t1 + k[3])
+	}
+
+	// Output with "undo last swap"
+	ta := ic ^ c.k[4]
+	tb := id ^ c.k[5]
+	tc := ia ^ c.k[6]
+	td := ib ^ c.k[7]
+
+	store32l(dst[0:4], ta)
+	store32l(dst[4:8], tb)
+	store32l(dst[8:12], tc)
+	store32l(dst[12:16], td)
+}
+
+// Decrypt decrypts a 16-byte block from src to dst, which may overlap.
+func (c *Cipher) Decrypt(dst, src []byte) {
+	S1 := c.s[0]
+	S2 := c.s[1]
+	S3 := c.s[2]
+	S4 := c.s[3]
+
+	// Load input
+	ta := load32l(src[0:4])
+	tb := load32l(src[4:8])
+	tc := load32l(src[8:12])
+	td := load32l(src[12:16])
+
+	// Undo undo final swap
+	ia := tc ^ c.k[6]
+	ib := td ^ c.k[7]
+	ic := ta ^ c.k[4]
+	id := tb ^ c.k[5]
+
+	for i := 8; i > 0; i-- {
+		k := c.k[4+i*4 : 8+i*4]
+		t2 := S2[byte(id)] ^ S3[byte(id>>8)] ^ S4[byte(id>>16)] ^ S1[byte(id>>24)]
+		t1 := S1[byte(ic)] ^ S2[byte(ic>>8)] ^ S3[byte(ic>>16)] ^ S4[byte(ic>>24)] + t2
+		ia = rol(ia, 1) ^ (t1 + k[2])
+		ib = ror(ib^(t2+t1+k[3]), 1)
+
+		t2 = S2[byte(ib)] ^ S3[byte(ib>>8)] ^ S4[byte(ib>>16)] ^ S1[byte(ib>>24)]
+		t1 = S1[byte(ia)] ^ S2[byte(ia>>8)] ^ S3[byte(ia>>16)] ^ S4[byte(ia>>24)] + t2
+		ic = rol(ic, 1) ^ (t1 + k[0])
+		id = ror(id^(t2+t1+k[1]), 1)
+	}
+
+	// Undo pre-whitening
+	ia ^= c.k[0]
+	ib ^= c.k[1]
+	ic ^= c.k[2]
+	id ^= c.k[3]
+
+	store32l(dst[0:4], ia)
+	store32l(dst[4:8], ib)
+	store32l(dst[8:12], ic)
+	store32l(dst[12:16], id)
+}
diff --git a/vendor/golang.org/x/crypto/xtea/block.go b/vendor/golang.org/x/crypto/xtea/block.go
new file mode 100644
index 0000000000..fcb4e4d000
--- /dev/null
+++ b/vendor/golang.org/x/crypto/xtea/block.go
@@ -0,0 +1,66 @@
+// Copyright 2009 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.
+
+/*
+	Implementation adapted from Needham and Wheeler's paper:
+	http://www.cix.co.uk/~klockstone/xtea.pdf
+
+	A precalculated look up table is used during encryption/decryption for values that are based purely on the key.
+*/
+
+package xtea
+
+// XTEA is based on 64 rounds.
+const numRounds = 64
+
+// blockToUint32 reads an 8 byte slice into two uint32s.
+// The block is treated as big endian.
+func blockToUint32(src []byte) (uint32, uint32) {
+	r0 := uint32(src[0])<<24 | uint32(src[1])<<16 | uint32(src[2])<<8 | uint32(src[3])
+	r1 := uint32(src[4])<<24 | uint32(src[5])<<16 | uint32(src[6])<<8 | uint32(src[7])
+	return r0, r1
+}
+
+// uint32ToBlock writes two uint32s into an 8 byte data block.
+// Values are written as big endian.
+func uint32ToBlock(v0, v1 uint32, dst []byte) {
+	dst[0] = byte(v0 >> 24)
+	dst[1] = byte(v0 >> 16)
+	dst[2] = byte(v0 >> 8)
+	dst[3] = byte(v0)
+	dst[4] = byte(v1 >> 24)
+	dst[5] = byte(v1 >> 16)
+	dst[6] = byte(v1 >> 8)
+	dst[7] = byte(v1 >> 0)
+}
+
+// encryptBlock encrypts a single 8 byte block using XTEA.
+func encryptBlock(c *Cipher, dst, src []byte) {
+	v0, v1 := blockToUint32(src)
+
+	// Two rounds of XTEA applied per loop
+	for i := 0; i < numRounds; {
+		v0 += ((v1<<4 ^ v1>>5) + v1) ^ c.table[i]
+		i++
+		v1 += ((v0<<4 ^ v0>>5) + v0) ^ c.table[i]
+		i++
+	}
+
+	uint32ToBlock(v0, v1, dst)
+}
+
+// decryptBlock decrypts a single 8 byte block using XTEA.
+func decryptBlock(c *Cipher, dst, src []byte) {
+	v0, v1 := blockToUint32(src)
+
+	// Two rounds of XTEA applied per loop
+	for i := numRounds; i > 0; {
+		i--
+		v1 -= ((v0<<4 ^ v0>>5) + v0) ^ c.table[i]
+		i--
+		v0 -= ((v1<<4 ^ v1>>5) + v1) ^ c.table[i]
+	}
+
+	uint32ToBlock(v0, v1, dst)
+}
diff --git a/vendor/golang.org/x/crypto/xtea/cipher.go b/vendor/golang.org/x/crypto/xtea/cipher.go
new file mode 100644
index 0000000000..a4c2fd02b3
--- /dev/null
+++ b/vendor/golang.org/x/crypto/xtea/cipher.go
@@ -0,0 +1,90 @@
+// Copyright 2009 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 xtea implements XTEA encryption, as defined in Needham and Wheeler's
+// 1997 technical report, "Tea extensions."
+//
+// XTEA is a legacy cipher and its short block size makes it vulnerable to
+// birthday bound attacks (see https://sweet32.info). It should only be used
+// where compatibility with legacy systems, not security, is the goal.
+//
+// Deprecated: any new system should use AES (from crypto/aes, if necessary in
+// an AEAD mode like crypto/cipher.NewGCM) or XChaCha20-Poly1305 (from
+// golang.org/x/crypto/chacha20poly1305).
+package xtea // import "golang.org/x/crypto/xtea"
+
+// For details, see http://www.cix.co.uk/~klockstone/xtea.pdf
+
+import "strconv"
+
+// The XTEA block size in bytes.
+const BlockSize = 8
+
+// A Cipher is an instance of an XTEA cipher using a particular key.
+type Cipher struct {
+	// table contains a series of precalculated values that are used each round.
+	table [64]uint32
+}
+
+type KeySizeError int
+
+func (k KeySizeError) Error() string {
+	return "crypto/xtea: invalid key size " + strconv.Itoa(int(k))
+}
+
+// NewCipher creates and returns a new Cipher.
+// The key argument should be the XTEA key.
+// XTEA only supports 128 bit (16 byte) keys.
+func NewCipher(key []byte) (*Cipher, error) {
+	k := len(key)
+	switch k {
+	default:
+		return nil, KeySizeError(k)
+	case 16:
+		break
+	}
+
+	c := new(Cipher)
+	initCipher(c, key)
+
+	return c, nil
+}
+
+// BlockSize returns the XTEA block size, 8 bytes.
+// It is necessary to satisfy the Block interface in the
+// package "crypto/cipher".
+func (c *Cipher) BlockSize() int { return BlockSize }
+
+// Encrypt encrypts the 8 byte buffer src using the key and stores the result in dst.
+// Note that for amounts of data larger than a block,
+// it is not safe to just call Encrypt on successive blocks;
+// instead, use an encryption mode like CBC (see crypto/cipher/cbc.go).
+func (c *Cipher) Encrypt(dst, src []byte) { encryptBlock(c, dst, src) }
+
+// Decrypt decrypts the 8 byte buffer src using the key and stores the result in dst.
+func (c *Cipher) Decrypt(dst, src []byte) { decryptBlock(c, dst, src) }
+
+// initCipher initializes the cipher context by creating a look up table
+// of precalculated values that are based on the key.
+func initCipher(c *Cipher, key []byte) {
+	// Load the key into four uint32s
+	var k [4]uint32
+	for i := 0; i < len(k); i++ {
+		j := i << 2 // Multiply by 4
+		k[i] = uint32(key[j+0])<<24 | uint32(key[j+1])<<16 | uint32(key[j+2])<<8 | uint32(key[j+3])
+	}
+
+	// Precalculate the table
+	const delta = 0x9E3779B9
+	var sum uint32
+
+	// Two rounds of XTEA applied per loop
+	for i := 0; i < numRounds; {
+		c.table[i] = sum + k[sum&3]
+		i++
+		sum += delta
+		c.table[i] = sum + k[(sum>>11)&3]
+		i++
+	}
+}
diff --git a/vendor/golang.org/x/crypto/xts/xts.go b/vendor/golang.org/x/crypto/xts/xts.go
new file mode 100644
index 0000000000..b51308e95e
--- /dev/null
+++ b/vendor/golang.org/x/crypto/xts/xts.go
@@ -0,0 +1,164 @@
+// 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 xts implements the XTS cipher mode as specified in IEEE P1619/D16.
+//
+// XTS mode is typically used for disk encryption, which presents a number of
+// novel problems that make more common modes inapplicable. The disk is
+// conceptually an array of sectors and we must be able to encrypt and decrypt
+// a sector in isolation. However, an attacker must not be able to transpose
+// two sectors of plaintext by transposing their ciphertext.
+//
+// XTS wraps a block cipher with Rogaway's XEX mode in order to build a
+// tweakable block cipher. This allows each sector to have a unique tweak and
+// effectively create a unique key for each sector.
+//
+// XTS does not provide any authentication. An attacker can manipulate the
+// ciphertext and randomise a block (16 bytes) of the plaintext. This package
+// does not implement ciphertext-stealing so sectors must be a multiple of 16
+// bytes.
+//
+// Note that XTS is usually not appropriate for any use besides disk encryption.
+// Most users should use an AEAD mode like GCM (from crypto/cipher.NewGCM) instead.
+package xts // import "golang.org/x/crypto/xts"
+
+import (
+	"crypto/cipher"
+	"encoding/binary"
+	"errors"
+	"sync"
+
+	"golang.org/x/crypto/internal/subtle"
+)
+
+// Cipher contains an expanded key structure. It is safe for concurrent use if
+// the underlying block cipher is safe for concurrent use.
+type Cipher struct {
+	k1, k2 cipher.Block
+}
+
+// blockSize is the block size that the underlying cipher must have. XTS is
+// only defined for 16-byte ciphers.
+const blockSize = 16
+
+var tweakPool = sync.Pool{
+	New: func() interface{} {
+		return new([blockSize]byte)
+	},
+}
+
+// NewCipher creates a Cipher given a function for creating the underlying
+// block cipher (which must have a block size of 16 bytes). The key must be
+// twice the length of the underlying cipher's key.
+func NewCipher(cipherFunc func([]byte) (cipher.Block, error), key []byte) (c *Cipher, err error) {
+	c = new(Cipher)
+	if c.k1, err = cipherFunc(key[:len(key)/2]); err != nil {
+		return
+	}
+	c.k2, err = cipherFunc(key[len(key)/2:])
+
+	if c.k1.BlockSize() != blockSize {
+		err = errors.New("xts: cipher does not have a block size of 16")
+	}
+
+	return
+}
+
+// Encrypt encrypts a sector of plaintext and puts the result into ciphertext.
+// Plaintext and ciphertext must overlap entirely or not at all.
+// Sectors must be a multiple of 16 bytes and less than 2²⁴ bytes.
+func (c *Cipher) Encrypt(ciphertext, plaintext []byte, sectorNum uint64) {
+	if len(ciphertext) < len(plaintext) {
+		panic("xts: ciphertext is smaller than plaintext")
+	}
+	if len(plaintext)%blockSize != 0 {
+		panic("xts: plaintext is not a multiple of the block size")
+	}
+	if subtle.InexactOverlap(ciphertext[:len(plaintext)], plaintext) {
+		panic("xts: invalid buffer overlap")
+	}
+
+	tweak := tweakPool.Get().(*[blockSize]byte)
+	for i := range tweak {
+		tweak[i] = 0
+	}
+	binary.LittleEndian.PutUint64(tweak[:8], sectorNum)
+
+	c.k2.Encrypt(tweak[:], tweak[:])
+
+	for len(plaintext) > 0 {
+		for j := range tweak {
+			ciphertext[j] = plaintext[j] ^ tweak[j]
+		}
+		c.k1.Encrypt(ciphertext, ciphertext)
+		for j := range tweak {
+			ciphertext[j] ^= tweak[j]
+		}
+		plaintext = plaintext[blockSize:]
+		ciphertext = ciphertext[blockSize:]
+
+		mul2(tweak)
+	}
+
+	tweakPool.Put(tweak)
+}
+
+// Decrypt decrypts a sector of ciphertext and puts the result into plaintext.
+// Plaintext and ciphertext must overlap entirely or not at all.
+// Sectors must be a multiple of 16 bytes and less than 2²⁴ bytes.
+func (c *Cipher) Decrypt(plaintext, ciphertext []byte, sectorNum uint64) {
+	if len(plaintext) < len(ciphertext) {
+		panic("xts: plaintext is smaller than ciphertext")
+	}
+	if len(ciphertext)%blockSize != 0 {
+		panic("xts: ciphertext is not a multiple of the block size")
+	}
+	if subtle.InexactOverlap(plaintext[:len(ciphertext)], ciphertext) {
+		panic("xts: invalid buffer overlap")
+	}
+
+	tweak := tweakPool.Get().(*[blockSize]byte)
+	for i := range tweak {
+		tweak[i] = 0
+	}
+	binary.LittleEndian.PutUint64(tweak[:8], sectorNum)
+
+	c.k2.Encrypt(tweak[:], tweak[:])
+
+	for len(ciphertext) > 0 {
+		for j := range tweak {
+			plaintext[j] = ciphertext[j] ^ tweak[j]
+		}
+		c.k1.Decrypt(plaintext, plaintext)
+		for j := range tweak {
+			plaintext[j] ^= tweak[j]
+		}
+		plaintext = plaintext[blockSize:]
+		ciphertext = ciphertext[blockSize:]
+
+		mul2(tweak)
+	}
+
+	tweakPool.Put(tweak)
+}
+
+// mul2 multiplies tweak by 2 in GF(2¹²⁸) with an irreducible polynomial of
+// x¹²⁸ + x⁷ + x² + x + 1.
+func mul2(tweak *[blockSize]byte) {
+	var carryIn byte
+	for j := range tweak {
+		carryOut := tweak[j] >> 7
+		tweak[j] = (tweak[j] << 1) + carryIn
+		carryIn = carryOut
+	}
+	if carryIn != 0 {
+		// If we have a carry bit then we need to subtract a multiple
+		// of the irreducible polynomial (x¹²⁸ + x⁷ + x² + x + 1).
+		// By dropping the carry bit, we're subtracting the x^128 term
+		// so all that remains is to subtract x⁷ + x² + x + 1.
+		// Subtraction (and addition) in this representation is just
+		// XOR.
+		tweak[0] ^= 1<<7 | 1<<2 | 1<<1 | 1
+	}
+}
-- 
2.41.0

