From 5434077d73e99688e2f484d0a4b9c6a7aaa32656 Mon Sep 17 00:00:00 2001 From: Matthieu Grieger Date: Sun, 10 Jul 2016 20:15:15 -0700 Subject: [PATCH] Remove crypto/pkcs12 --- glide.lock | 4 - glide.yaml | 3 - vendor/golang.org/x/crypto/.gitattributes | 10 - vendor/golang.org/x/crypto/.gitignore | 2 - vendor/golang.org/x/crypto/AUTHORS | 3 - vendor/golang.org/x/crypto/CONTRIBUTING.md | 31 - vendor/golang.org/x/crypto/CONTRIBUTORS | 3 - vendor/golang.org/x/crypto/LICENSE | 27 - vendor/golang.org/x/crypto/PATENTS | 22 - vendor/golang.org/x/crypto/README | 3 - .../x/crypto/acme/internal/acme/acme.go | 473 ----- .../x/crypto/acme/internal/acme/acme_test.go | 759 ------- .../x/crypto/acme/internal/acme/jws.go | 67 - .../x/crypto/acme/internal/acme/jws_test.go | 139 -- .../x/crypto/acme/internal/acme/types.go | 181 -- vendor/golang.org/x/crypto/bcrypt/base64.go | 35 - vendor/golang.org/x/crypto/bcrypt/bcrypt.go | 294 --- .../golang.org/x/crypto/bcrypt/bcrypt_test.go | 226 --- vendor/golang.org/x/crypto/blowfish/block.go | 159 -- .../x/crypto/blowfish/blowfish_test.go | 274 --- vendor/golang.org/x/crypto/blowfish/cipher.go | 91 - vendor/golang.org/x/crypto/blowfish/const.go | 199 -- vendor/golang.org/x/crypto/bn256/bn256.go | 404 ---- .../golang.org/x/crypto/bn256/bn256_test.go | 304 --- vendor/golang.org/x/crypto/bn256/constants.go | 44 - vendor/golang.org/x/crypto/bn256/curve.go | 278 --- .../golang.org/x/crypto/bn256/example_test.go | 43 - 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 | 249 --- vendor/golang.org/x/crypto/cast5/cast5.go | 526 ----- .../golang.org/x/crypto/cast5/cast5_test.go | 106 - vendor/golang.org/x/crypto/codereview.cfg | 1 - .../x/crypto/curve25519/const_amd64.s | 20 - .../x/crypto/curve25519/cswap_amd64.s | 88 - .../x/crypto/curve25519/curve25519.go | 841 -------- .../x/crypto/curve25519/curve25519_test.go | 29 - vendor/golang.org/x/crypto/curve25519/doc.go | 23 - .../x/crypto/curve25519/freeze_amd64.s | 94 - .../x/crypto/curve25519/ladderstep_amd64.s | 1398 ------------- .../x/crypto/curve25519/mont25519_amd64.go | 240 --- .../x/crypto/curve25519/mul_amd64.s | 191 -- .../x/crypto/curve25519/square_amd64.s | 153 -- vendor/golang.org/x/crypto/ed25519/ed25519.go | 181 -- .../x/crypto/ed25519/ed25519_test.go | 183 -- .../ed25519/internal/edwards25519/const.go | 1422 ------------- .../internal/edwards25519/edwards25519.go | 1771 ----------------- .../x/crypto/ed25519/testdata/sign.input.gz | Bin 50330 -> 0 bytes .../golang.org/x/crypto/hkdf/example_test.go | 61 - vendor/golang.org/x/crypto/hkdf/hkdf.go | 75 - vendor/golang.org/x/crypto/hkdf/hkdf_test.go | 370 ---- vendor/golang.org/x/crypto/md4/md4.go | 118 -- vendor/golang.org/x/crypto/md4/md4_test.go | 71 - vendor/golang.org/x/crypto/md4/md4block.go | 89 - vendor/golang.org/x/crypto/nacl/box/box.go | 85 - .../golang.org/x/crypto/nacl/box/box_test.go | 78 - .../x/crypto/nacl/secretbox/secretbox.go | 149 -- .../x/crypto/nacl/secretbox/secretbox_test.go | 91 - vendor/golang.org/x/crypto/ocsp/ocsp.go | 673 ------- vendor/golang.org/x/crypto/ocsp/ocsp_test.go | 584 ------ .../x/crypto/openpgp/armor/armor.go | 219 -- .../x/crypto/openpgp/armor/armor_test.go | 95 - .../x/crypto/openpgp/armor/encode.go | 160 -- .../x/crypto/openpgp/canonical_text.go | 59 - .../x/crypto/openpgp/canonical_text_test.go | 52 - .../x/crypto/openpgp/clearsign/clearsign.go | 376 ---- .../openpgp/clearsign/clearsign_test.go | 210 -- .../x/crypto/openpgp/elgamal/elgamal.go | 122 -- .../x/crypto/openpgp/elgamal/elgamal_test.go | 49 - .../x/crypto/openpgp/errors/errors.go | 72 - vendor/golang.org/x/crypto/openpgp/keys.go | 633 ------ .../golang.org/x/crypto/openpgp/keys_test.go | 370 ---- .../x/crypto/openpgp/packet/compressed.go | 123 -- .../crypto/openpgp/packet/compressed_test.go | 41 - .../x/crypto/openpgp/packet/config.go | 91 - .../x/crypto/openpgp/packet/encrypted_key.go | 199 -- .../openpgp/packet/encrypted_key_test.go | 146 -- .../x/crypto/openpgp/packet/literal.go | 89 - .../x/crypto/openpgp/packet/ocfb.go | 143 -- .../x/crypto/openpgp/packet/ocfb_test.go | 46 - .../openpgp/packet/one_pass_signature.go | 73 - .../x/crypto/openpgp/packet/opaque.go | 162 -- .../x/crypto/openpgp/packet/opaque_test.go | 67 - .../x/crypto/openpgp/packet/packet.go | 539 ----- .../x/crypto/openpgp/packet/packet_test.go | 255 --- .../x/crypto/openpgp/packet/private_key.go | 362 ---- .../crypto/openpgp/packet/private_key_test.go | 126 -- .../x/crypto/openpgp/packet/public_key.go | 750 ------- .../crypto/openpgp/packet/public_key_test.go | 202 -- .../x/crypto/openpgp/packet/public_key_v3.go | 280 --- .../openpgp/packet/public_key_v3_test.go | 82 - .../x/crypto/openpgp/packet/reader.go | 76 - .../x/crypto/openpgp/packet/signature.go | 706 ------- .../x/crypto/openpgp/packet/signature_test.go | 42 - .../x/crypto/openpgp/packet/signature_v3.go | 146 -- .../openpgp/packet/signature_v3_test.go | 92 - .../openpgp/packet/symmetric_key_encrypted.go | 155 -- .../packet/symmetric_key_encrypted_test.go | 103 - .../openpgp/packet/symmetrically_encrypted.go | 290 --- .../packet/symmetrically_encrypted_test.go | 123 -- .../x/crypto/openpgp/packet/userattribute.go | 91 - .../openpgp/packet/userattribute_test.go | 109 - .../x/crypto/openpgp/packet/userid.go | 160 -- .../x/crypto/openpgp/packet/userid_test.go | 87 - vendor/golang.org/x/crypto/openpgp/read.go | 442 ---- .../golang.org/x/crypto/openpgp/read_test.go | 613 ------ vendor/golang.org/x/crypto/openpgp/s2k/s2k.go | 273 --- .../x/crypto/openpgp/s2k/s2k_test.go | 137 -- vendor/golang.org/x/crypto/openpgp/write.go | 378 ---- .../golang.org/x/crypto/openpgp/write_test.go | 273 --- .../x/crypto/otr/libotr_test_helper.c | 197 -- vendor/golang.org/x/crypto/otr/otr.go | 1408 ------------- vendor/golang.org/x/crypto/otr/otr_test.go | 470 ----- vendor/golang.org/x/crypto/otr/smp.go | 572 ------ vendor/golang.org/x/crypto/pbkdf2/pbkdf2.go | 77 - .../golang.org/x/crypto/pbkdf2/pbkdf2_test.go | 157 -- .../golang.org/x/crypto/pkcs12/bmp-string.go | 50 - .../x/crypto/pkcs12/bmp-string_test.go | 63 - vendor/golang.org/x/crypto/pkcs12/crypto.go | 131 -- .../golang.org/x/crypto/pkcs12/crypto_test.go | 125 -- vendor/golang.org/x/crypto/pkcs12/errors.go | 23 - .../crypto/pkcs12/internal/rc2/bench_test.go | 27 - .../x/crypto/pkcs12/internal/rc2/rc2.go | 274 --- .../x/crypto/pkcs12/internal/rc2/rc2_test.go | 93 - vendor/golang.org/x/crypto/pkcs12/mac.go | 45 - vendor/golang.org/x/crypto/pkcs12/mac_test.go | 42 - vendor/golang.org/x/crypto/pkcs12/pbkdf.go | 170 -- .../golang.org/x/crypto/pkcs12/pbkdf_test.go | 34 - vendor/golang.org/x/crypto/pkcs12/pkcs12.go | 342 ---- .../golang.org/x/crypto/pkcs12/pkcs12_test.go | 138 -- vendor/golang.org/x/crypto/pkcs12/safebags.go | 57 - .../x/crypto/poly1305/const_amd64.s | 45 - .../golang.org/x/crypto/poly1305/poly1305.go | 32 - .../x/crypto/poly1305/poly1305_amd64.s | 497 ----- .../x/crypto/poly1305/poly1305_arm.s | 379 ---- .../x/crypto/poly1305/poly1305_test.go | 86 - .../golang.org/x/crypto/poly1305/sum_amd64.go | 24 - .../golang.org/x/crypto/poly1305/sum_arm.go | 24 - .../golang.org/x/crypto/poly1305/sum_ref.go | 1531 -------------- .../x/crypto/ripemd160/ripemd160.go | 120 -- .../x/crypto/ripemd160/ripemd160_test.go | 64 - .../x/crypto/ripemd160/ripemd160block.go | 161 -- .../x/crypto/salsa20/salsa/hsalsa20.go | 144 -- .../x/crypto/salsa20/salsa/salsa2020_amd64.s | 902 --------- .../x/crypto/salsa20/salsa/salsa208.go | 199 -- .../x/crypto/salsa20/salsa/salsa20_amd64.go | 23 - .../x/crypto/salsa20/salsa/salsa20_ref.go | 234 --- .../x/crypto/salsa20/salsa/salsa_test.go | 35 - vendor/golang.org/x/crypto/salsa20/salsa20.go | 54 - .../x/crypto/salsa20/salsa20_test.go | 139 -- vendor/golang.org/x/crypto/scrypt/scrypt.go | 243 --- .../golang.org/x/crypto/scrypt/scrypt_test.go | 160 -- vendor/golang.org/x/crypto/sha3/doc.go | 66 - vendor/golang.org/x/crypto/sha3/hashes.go | 65 - vendor/golang.org/x/crypto/sha3/keccakf.go | 410 ---- vendor/golang.org/x/crypto/sha3/register.go | 18 - vendor/golang.org/x/crypto/sha3/sha3.go | 193 -- vendor/golang.org/x/crypto/sha3/sha3_test.go | 306 --- vendor/golang.org/x/crypto/sha3/shake.go | 60 - .../sha3/testdata/keccakKats.json.deflate | Bin 521342 -> 0 bytes vendor/golang.org/x/crypto/sha3/xor.go | 16 - .../golang.org/x/crypto/sha3/xor_generic.go | 28 - .../golang.org/x/crypto/sha3/xor_unaligned.go | 58 - .../golang.org/x/crypto/ssh/agent/client.go | 659 ------ .../x/crypto/ssh/agent/client_test.go | 327 --- .../x/crypto/ssh/agent/example_test.go | 40 - .../golang.org/x/crypto/ssh/agent/forward.go | 103 - .../golang.org/x/crypto/ssh/agent/keyring.go | 184 -- .../x/crypto/ssh/agent/keyring_test.go | 78 - .../golang.org/x/crypto/ssh/agent/server.go | 451 ----- .../x/crypto/ssh/agent/server_test.go | 204 -- .../x/crypto/ssh/agent/testdata_test.go | 64 - .../golang.org/x/crypto/ssh/benchmark_test.go | 122 -- vendor/golang.org/x/crypto/ssh/buffer.go | 98 - vendor/golang.org/x/crypto/ssh/buffer_test.go | 87 - vendor/golang.org/x/crypto/ssh/certs.go | 503 ----- vendor/golang.org/x/crypto/ssh/certs_test.go | 216 -- vendor/golang.org/x/crypto/ssh/channel.go | 631 ------ vendor/golang.org/x/crypto/ssh/cipher.go | 579 ------ vendor/golang.org/x/crypto/ssh/cipher_test.go | 127 -- vendor/golang.org/x/crypto/ssh/client.go | 213 -- vendor/golang.org/x/crypto/ssh/client_auth.go | 473 ----- .../x/crypto/ssh/client_auth_test.go | 439 ---- vendor/golang.org/x/crypto/ssh/client_test.go | 39 - vendor/golang.org/x/crypto/ssh/common.go | 356 ---- vendor/golang.org/x/crypto/ssh/connection.go | 144 -- vendor/golang.org/x/crypto/ssh/doc.go | 18 - .../golang.org/x/crypto/ssh/example_test.go | 243 --- vendor/golang.org/x/crypto/ssh/handshake.go | 451 ----- .../golang.org/x/crypto/ssh/handshake_test.go | 486 ----- vendor/golang.org/x/crypto/ssh/kex.go | 526 ----- vendor/golang.org/x/crypto/ssh/kex_test.go | 50 - vendor/golang.org/x/crypto/ssh/keys.go | 846 -------- vendor/golang.org/x/crypto/ssh/keys_test.go | 440 ---- vendor/golang.org/x/crypto/ssh/mac.go | 57 - .../golang.org/x/crypto/ssh/mempipe_test.go | 110 - vendor/golang.org/x/crypto/ssh/messages.go | 758 ------- .../golang.org/x/crypto/ssh/messages_test.go | 288 --- vendor/golang.org/x/crypto/ssh/mux.go | 330 --- vendor/golang.org/x/crypto/ssh/mux_test.go | 502 ----- vendor/golang.org/x/crypto/ssh/server.go | 489 ----- vendor/golang.org/x/crypto/ssh/session.go | 612 ------ .../golang.org/x/crypto/ssh/session_test.go | 774 ------- vendor/golang.org/x/crypto/ssh/tcpip.go | 407 ---- vendor/golang.org/x/crypto/ssh/tcpip_test.go | 20 - .../x/crypto/ssh/terminal/terminal.go | 892 --------- .../x/crypto/ssh/terminal/terminal_test.go | 291 --- .../golang.org/x/crypto/ssh/terminal/util.go | 128 -- .../x/crypto/ssh/terminal/util_bsd.go | 12 - .../x/crypto/ssh/terminal/util_linux.go | 11 - .../x/crypto/ssh/terminal/util_plan9.go | 58 - .../x/crypto/ssh/terminal/util_windows.go | 174 -- .../x/crypto/ssh/test/agent_unix_test.go | 59 - .../golang.org/x/crypto/ssh/test/cert_test.go | 47 - vendor/golang.org/x/crypto/ssh/test/doc.go | 7 - .../x/crypto/ssh/test/forward_unix_test.go | 160 -- .../x/crypto/ssh/test/session_test.go | 365 ---- .../x/crypto/ssh/test/tcpip_test.go | 46 - .../x/crypto/ssh/test/test_unix_test.go | 268 --- .../x/crypto/ssh/test/testdata_test.go | 64 - .../golang.org/x/crypto/ssh/testdata/doc.go | 8 - .../golang.org/x/crypto/ssh/testdata/keys.go | 57 - .../golang.org/x/crypto/ssh/testdata_test.go | 63 - vendor/golang.org/x/crypto/ssh/transport.go | 333 ---- .../golang.org/x/crypto/ssh/transport_test.go | 109 - vendor/golang.org/x/crypto/tea/cipher.go | 109 - vendor/golang.org/x/crypto/tea/tea_test.go | 93 - vendor/golang.org/x/crypto/twofish/twofish.go | 342 ---- .../x/crypto/twofish/twofish_test.go | 129 -- vendor/golang.org/x/crypto/xtea/block.go | 66 - vendor/golang.org/x/crypto/xtea/cipher.go | 82 - vendor/golang.org/x/crypto/xtea/xtea_test.go | 229 --- vendor/golang.org/x/crypto/xts/xts.go | 138 -- vendor/golang.org/x/crypto/xts/xts_test.go | 85 - 236 files changed, 54417 deletions(-) delete mode 100644 vendor/golang.org/x/crypto/.gitattributes delete mode 100644 vendor/golang.org/x/crypto/.gitignore delete mode 100644 vendor/golang.org/x/crypto/AUTHORS delete mode 100644 vendor/golang.org/x/crypto/CONTRIBUTING.md delete mode 100644 vendor/golang.org/x/crypto/CONTRIBUTORS delete mode 100644 vendor/golang.org/x/crypto/LICENSE delete mode 100644 vendor/golang.org/x/crypto/PATENTS delete mode 100644 vendor/golang.org/x/crypto/README delete mode 100644 vendor/golang.org/x/crypto/acme/internal/acme/acme.go delete mode 100644 vendor/golang.org/x/crypto/acme/internal/acme/acme_test.go delete mode 100644 vendor/golang.org/x/crypto/acme/internal/acme/jws.go delete mode 100644 vendor/golang.org/x/crypto/acme/internal/acme/jws_test.go delete mode 100644 vendor/golang.org/x/crypto/acme/internal/acme/types.go delete mode 100644 vendor/golang.org/x/crypto/bcrypt/base64.go delete mode 100644 vendor/golang.org/x/crypto/bcrypt/bcrypt.go delete mode 100644 vendor/golang.org/x/crypto/bcrypt/bcrypt_test.go delete mode 100644 vendor/golang.org/x/crypto/blowfish/block.go delete mode 100644 vendor/golang.org/x/crypto/blowfish/blowfish_test.go delete mode 100644 vendor/golang.org/x/crypto/blowfish/cipher.go delete mode 100644 vendor/golang.org/x/crypto/blowfish/const.go delete mode 100644 vendor/golang.org/x/crypto/bn256/bn256.go delete mode 100644 vendor/golang.org/x/crypto/bn256/bn256_test.go delete mode 100644 vendor/golang.org/x/crypto/bn256/constants.go delete mode 100644 vendor/golang.org/x/crypto/bn256/curve.go delete mode 100644 vendor/golang.org/x/crypto/bn256/example_test.go delete mode 100644 vendor/golang.org/x/crypto/bn256/gfp12.go delete mode 100644 vendor/golang.org/x/crypto/bn256/gfp2.go delete mode 100644 vendor/golang.org/x/crypto/bn256/gfp6.go delete mode 100644 vendor/golang.org/x/crypto/bn256/optate.go delete mode 100644 vendor/golang.org/x/crypto/bn256/twist.go delete mode 100644 vendor/golang.org/x/crypto/cast5/cast5.go delete mode 100644 vendor/golang.org/x/crypto/cast5/cast5_test.go delete mode 100644 vendor/golang.org/x/crypto/codereview.cfg delete mode 100644 vendor/golang.org/x/crypto/curve25519/const_amd64.s delete mode 100644 vendor/golang.org/x/crypto/curve25519/cswap_amd64.s delete mode 100644 vendor/golang.org/x/crypto/curve25519/curve25519.go delete mode 100644 vendor/golang.org/x/crypto/curve25519/curve25519_test.go delete mode 100644 vendor/golang.org/x/crypto/curve25519/doc.go delete mode 100644 vendor/golang.org/x/crypto/curve25519/freeze_amd64.s delete mode 100644 vendor/golang.org/x/crypto/curve25519/ladderstep_amd64.s delete mode 100644 vendor/golang.org/x/crypto/curve25519/mont25519_amd64.go delete mode 100644 vendor/golang.org/x/crypto/curve25519/mul_amd64.s delete mode 100644 vendor/golang.org/x/crypto/curve25519/square_amd64.s delete mode 100644 vendor/golang.org/x/crypto/ed25519/ed25519.go delete mode 100644 vendor/golang.org/x/crypto/ed25519/ed25519_test.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 delete mode 100644 vendor/golang.org/x/crypto/ed25519/testdata/sign.input.gz delete mode 100644 vendor/golang.org/x/crypto/hkdf/example_test.go delete mode 100644 vendor/golang.org/x/crypto/hkdf/hkdf.go delete mode 100644 vendor/golang.org/x/crypto/hkdf/hkdf_test.go delete mode 100644 vendor/golang.org/x/crypto/md4/md4.go delete mode 100644 vendor/golang.org/x/crypto/md4/md4_test.go delete mode 100644 vendor/golang.org/x/crypto/md4/md4block.go delete mode 100644 vendor/golang.org/x/crypto/nacl/box/box.go delete mode 100644 vendor/golang.org/x/crypto/nacl/box/box_test.go delete mode 100644 vendor/golang.org/x/crypto/nacl/secretbox/secretbox.go delete mode 100644 vendor/golang.org/x/crypto/nacl/secretbox/secretbox_test.go delete mode 100644 vendor/golang.org/x/crypto/ocsp/ocsp.go delete mode 100644 vendor/golang.org/x/crypto/ocsp/ocsp_test.go delete mode 100644 vendor/golang.org/x/crypto/openpgp/armor/armor.go delete mode 100644 vendor/golang.org/x/crypto/openpgp/armor/armor_test.go delete mode 100644 vendor/golang.org/x/crypto/openpgp/armor/encode.go delete mode 100644 vendor/golang.org/x/crypto/openpgp/canonical_text.go delete mode 100644 vendor/golang.org/x/crypto/openpgp/canonical_text_test.go delete mode 100644 vendor/golang.org/x/crypto/openpgp/clearsign/clearsign.go delete mode 100644 vendor/golang.org/x/crypto/openpgp/clearsign/clearsign_test.go delete mode 100644 vendor/golang.org/x/crypto/openpgp/elgamal/elgamal.go delete mode 100644 vendor/golang.org/x/crypto/openpgp/elgamal/elgamal_test.go delete mode 100644 vendor/golang.org/x/crypto/openpgp/errors/errors.go delete mode 100644 vendor/golang.org/x/crypto/openpgp/keys.go delete mode 100644 vendor/golang.org/x/crypto/openpgp/keys_test.go delete mode 100644 vendor/golang.org/x/crypto/openpgp/packet/compressed.go delete mode 100644 vendor/golang.org/x/crypto/openpgp/packet/compressed_test.go delete mode 100644 vendor/golang.org/x/crypto/openpgp/packet/config.go delete mode 100644 vendor/golang.org/x/crypto/openpgp/packet/encrypted_key.go delete mode 100644 vendor/golang.org/x/crypto/openpgp/packet/encrypted_key_test.go delete mode 100644 vendor/golang.org/x/crypto/openpgp/packet/literal.go delete mode 100644 vendor/golang.org/x/crypto/openpgp/packet/ocfb.go delete mode 100644 vendor/golang.org/x/crypto/openpgp/packet/ocfb_test.go delete mode 100644 vendor/golang.org/x/crypto/openpgp/packet/one_pass_signature.go delete mode 100644 vendor/golang.org/x/crypto/openpgp/packet/opaque.go delete mode 100644 vendor/golang.org/x/crypto/openpgp/packet/opaque_test.go delete mode 100644 vendor/golang.org/x/crypto/openpgp/packet/packet.go delete mode 100644 vendor/golang.org/x/crypto/openpgp/packet/packet_test.go delete mode 100644 vendor/golang.org/x/crypto/openpgp/packet/private_key.go delete mode 100644 vendor/golang.org/x/crypto/openpgp/packet/private_key_test.go delete mode 100644 vendor/golang.org/x/crypto/openpgp/packet/public_key.go delete mode 100644 vendor/golang.org/x/crypto/openpgp/packet/public_key_test.go delete mode 100644 vendor/golang.org/x/crypto/openpgp/packet/public_key_v3.go delete mode 100644 vendor/golang.org/x/crypto/openpgp/packet/public_key_v3_test.go delete mode 100644 vendor/golang.org/x/crypto/openpgp/packet/reader.go delete mode 100644 vendor/golang.org/x/crypto/openpgp/packet/signature.go delete mode 100644 vendor/golang.org/x/crypto/openpgp/packet/signature_test.go delete mode 100644 vendor/golang.org/x/crypto/openpgp/packet/signature_v3.go delete mode 100644 vendor/golang.org/x/crypto/openpgp/packet/signature_v3_test.go delete mode 100644 vendor/golang.org/x/crypto/openpgp/packet/symmetric_key_encrypted.go delete mode 100644 vendor/golang.org/x/crypto/openpgp/packet/symmetric_key_encrypted_test.go delete mode 100644 vendor/golang.org/x/crypto/openpgp/packet/symmetrically_encrypted.go delete mode 100644 vendor/golang.org/x/crypto/openpgp/packet/symmetrically_encrypted_test.go delete mode 100644 vendor/golang.org/x/crypto/openpgp/packet/userattribute.go delete mode 100644 vendor/golang.org/x/crypto/openpgp/packet/userattribute_test.go delete mode 100644 vendor/golang.org/x/crypto/openpgp/packet/userid.go delete mode 100644 vendor/golang.org/x/crypto/openpgp/packet/userid_test.go delete mode 100644 vendor/golang.org/x/crypto/openpgp/read.go delete mode 100644 vendor/golang.org/x/crypto/openpgp/read_test.go delete mode 100644 vendor/golang.org/x/crypto/openpgp/s2k/s2k.go delete mode 100644 vendor/golang.org/x/crypto/openpgp/s2k/s2k_test.go delete mode 100644 vendor/golang.org/x/crypto/openpgp/write.go delete mode 100644 vendor/golang.org/x/crypto/openpgp/write_test.go delete mode 100644 vendor/golang.org/x/crypto/otr/libotr_test_helper.c delete mode 100644 vendor/golang.org/x/crypto/otr/otr.go delete mode 100644 vendor/golang.org/x/crypto/otr/otr_test.go delete mode 100644 vendor/golang.org/x/crypto/otr/smp.go delete mode 100644 vendor/golang.org/x/crypto/pbkdf2/pbkdf2.go delete mode 100644 vendor/golang.org/x/crypto/pbkdf2/pbkdf2_test.go delete mode 100644 vendor/golang.org/x/crypto/pkcs12/bmp-string.go delete mode 100644 vendor/golang.org/x/crypto/pkcs12/bmp-string_test.go delete mode 100644 vendor/golang.org/x/crypto/pkcs12/crypto.go delete mode 100644 vendor/golang.org/x/crypto/pkcs12/crypto_test.go delete mode 100644 vendor/golang.org/x/crypto/pkcs12/errors.go delete mode 100644 vendor/golang.org/x/crypto/pkcs12/internal/rc2/bench_test.go delete mode 100644 vendor/golang.org/x/crypto/pkcs12/internal/rc2/rc2.go delete mode 100644 vendor/golang.org/x/crypto/pkcs12/internal/rc2/rc2_test.go delete mode 100644 vendor/golang.org/x/crypto/pkcs12/mac.go delete mode 100644 vendor/golang.org/x/crypto/pkcs12/mac_test.go delete mode 100644 vendor/golang.org/x/crypto/pkcs12/pbkdf.go delete mode 100644 vendor/golang.org/x/crypto/pkcs12/pbkdf_test.go delete mode 100644 vendor/golang.org/x/crypto/pkcs12/pkcs12.go delete mode 100644 vendor/golang.org/x/crypto/pkcs12/pkcs12_test.go delete mode 100644 vendor/golang.org/x/crypto/pkcs12/safebags.go delete mode 100644 vendor/golang.org/x/crypto/poly1305/const_amd64.s delete mode 100644 vendor/golang.org/x/crypto/poly1305/poly1305.go delete mode 100644 vendor/golang.org/x/crypto/poly1305/poly1305_amd64.s delete mode 100644 vendor/golang.org/x/crypto/poly1305/poly1305_arm.s delete mode 100644 vendor/golang.org/x/crypto/poly1305/poly1305_test.go delete mode 100644 vendor/golang.org/x/crypto/poly1305/sum_amd64.go delete mode 100644 vendor/golang.org/x/crypto/poly1305/sum_arm.go delete mode 100644 vendor/golang.org/x/crypto/poly1305/sum_ref.go delete mode 100644 vendor/golang.org/x/crypto/ripemd160/ripemd160.go delete mode 100644 vendor/golang.org/x/crypto/ripemd160/ripemd160_test.go delete mode 100644 vendor/golang.org/x/crypto/ripemd160/ripemd160block.go delete mode 100644 vendor/golang.org/x/crypto/salsa20/salsa/hsalsa20.go delete mode 100644 vendor/golang.org/x/crypto/salsa20/salsa/salsa2020_amd64.s delete mode 100644 vendor/golang.org/x/crypto/salsa20/salsa/salsa208.go delete mode 100644 vendor/golang.org/x/crypto/salsa20/salsa/salsa20_amd64.go delete mode 100644 vendor/golang.org/x/crypto/salsa20/salsa/salsa20_ref.go delete mode 100644 vendor/golang.org/x/crypto/salsa20/salsa/salsa_test.go delete mode 100644 vendor/golang.org/x/crypto/salsa20/salsa20.go delete mode 100644 vendor/golang.org/x/crypto/salsa20/salsa20_test.go delete mode 100644 vendor/golang.org/x/crypto/scrypt/scrypt.go delete mode 100644 vendor/golang.org/x/crypto/scrypt/scrypt_test.go delete mode 100644 vendor/golang.org/x/crypto/sha3/doc.go delete mode 100644 vendor/golang.org/x/crypto/sha3/hashes.go delete mode 100644 vendor/golang.org/x/crypto/sha3/keccakf.go delete mode 100644 vendor/golang.org/x/crypto/sha3/register.go delete mode 100644 vendor/golang.org/x/crypto/sha3/sha3.go delete mode 100644 vendor/golang.org/x/crypto/sha3/sha3_test.go delete mode 100644 vendor/golang.org/x/crypto/sha3/shake.go delete mode 100644 vendor/golang.org/x/crypto/sha3/testdata/keccakKats.json.deflate delete mode 100644 vendor/golang.org/x/crypto/sha3/xor.go delete mode 100644 vendor/golang.org/x/crypto/sha3/xor_generic.go delete mode 100644 vendor/golang.org/x/crypto/sha3/xor_unaligned.go delete mode 100644 vendor/golang.org/x/crypto/ssh/agent/client.go delete mode 100644 vendor/golang.org/x/crypto/ssh/agent/client_test.go delete mode 100644 vendor/golang.org/x/crypto/ssh/agent/example_test.go delete mode 100644 vendor/golang.org/x/crypto/ssh/agent/forward.go delete mode 100644 vendor/golang.org/x/crypto/ssh/agent/keyring.go delete mode 100644 vendor/golang.org/x/crypto/ssh/agent/keyring_test.go delete mode 100644 vendor/golang.org/x/crypto/ssh/agent/server.go delete mode 100644 vendor/golang.org/x/crypto/ssh/agent/server_test.go delete mode 100644 vendor/golang.org/x/crypto/ssh/agent/testdata_test.go delete mode 100644 vendor/golang.org/x/crypto/ssh/benchmark_test.go delete mode 100644 vendor/golang.org/x/crypto/ssh/buffer.go delete mode 100644 vendor/golang.org/x/crypto/ssh/buffer_test.go delete mode 100644 vendor/golang.org/x/crypto/ssh/certs.go delete mode 100644 vendor/golang.org/x/crypto/ssh/certs_test.go delete mode 100644 vendor/golang.org/x/crypto/ssh/channel.go delete mode 100644 vendor/golang.org/x/crypto/ssh/cipher.go delete mode 100644 vendor/golang.org/x/crypto/ssh/cipher_test.go delete mode 100644 vendor/golang.org/x/crypto/ssh/client.go delete mode 100644 vendor/golang.org/x/crypto/ssh/client_auth.go delete mode 100644 vendor/golang.org/x/crypto/ssh/client_auth_test.go delete mode 100644 vendor/golang.org/x/crypto/ssh/client_test.go delete mode 100644 vendor/golang.org/x/crypto/ssh/common.go delete mode 100644 vendor/golang.org/x/crypto/ssh/connection.go delete mode 100644 vendor/golang.org/x/crypto/ssh/doc.go delete mode 100644 vendor/golang.org/x/crypto/ssh/example_test.go delete mode 100644 vendor/golang.org/x/crypto/ssh/handshake.go delete mode 100644 vendor/golang.org/x/crypto/ssh/handshake_test.go delete mode 100644 vendor/golang.org/x/crypto/ssh/kex.go delete mode 100644 vendor/golang.org/x/crypto/ssh/kex_test.go delete mode 100644 vendor/golang.org/x/crypto/ssh/keys.go delete mode 100644 vendor/golang.org/x/crypto/ssh/keys_test.go delete mode 100644 vendor/golang.org/x/crypto/ssh/mac.go delete mode 100644 vendor/golang.org/x/crypto/ssh/mempipe_test.go delete mode 100644 vendor/golang.org/x/crypto/ssh/messages.go delete mode 100644 vendor/golang.org/x/crypto/ssh/messages_test.go delete mode 100644 vendor/golang.org/x/crypto/ssh/mux.go delete mode 100644 vendor/golang.org/x/crypto/ssh/mux_test.go delete mode 100644 vendor/golang.org/x/crypto/ssh/server.go delete mode 100644 vendor/golang.org/x/crypto/ssh/session.go delete mode 100644 vendor/golang.org/x/crypto/ssh/session_test.go delete mode 100644 vendor/golang.org/x/crypto/ssh/tcpip.go delete mode 100644 vendor/golang.org/x/crypto/ssh/tcpip_test.go delete mode 100644 vendor/golang.org/x/crypto/ssh/terminal/terminal.go delete mode 100644 vendor/golang.org/x/crypto/ssh/terminal/terminal_test.go delete mode 100644 vendor/golang.org/x/crypto/ssh/terminal/util.go delete mode 100644 vendor/golang.org/x/crypto/ssh/terminal/util_bsd.go delete mode 100644 vendor/golang.org/x/crypto/ssh/terminal/util_linux.go delete mode 100644 vendor/golang.org/x/crypto/ssh/terminal/util_plan9.go delete mode 100644 vendor/golang.org/x/crypto/ssh/terminal/util_windows.go delete mode 100644 vendor/golang.org/x/crypto/ssh/test/agent_unix_test.go delete mode 100644 vendor/golang.org/x/crypto/ssh/test/cert_test.go delete mode 100644 vendor/golang.org/x/crypto/ssh/test/doc.go delete mode 100644 vendor/golang.org/x/crypto/ssh/test/forward_unix_test.go delete mode 100644 vendor/golang.org/x/crypto/ssh/test/session_test.go delete mode 100644 vendor/golang.org/x/crypto/ssh/test/tcpip_test.go delete mode 100644 vendor/golang.org/x/crypto/ssh/test/test_unix_test.go delete mode 100644 vendor/golang.org/x/crypto/ssh/test/testdata_test.go delete mode 100644 vendor/golang.org/x/crypto/ssh/testdata/doc.go delete mode 100644 vendor/golang.org/x/crypto/ssh/testdata/keys.go delete mode 100644 vendor/golang.org/x/crypto/ssh/testdata_test.go delete mode 100644 vendor/golang.org/x/crypto/ssh/transport.go delete mode 100644 vendor/golang.org/x/crypto/ssh/transport_test.go delete mode 100644 vendor/golang.org/x/crypto/tea/cipher.go delete mode 100644 vendor/golang.org/x/crypto/tea/tea_test.go delete mode 100644 vendor/golang.org/x/crypto/twofish/twofish.go delete mode 100644 vendor/golang.org/x/crypto/twofish/twofish_test.go delete mode 100644 vendor/golang.org/x/crypto/xtea/block.go delete mode 100644 vendor/golang.org/x/crypto/xtea/cipher.go delete mode 100644 vendor/golang.org/x/crypto/xtea/xtea_test.go delete mode 100644 vendor/golang.org/x/crypto/xts/xts.go delete mode 100644 vendor/golang.org/x/crypto/xts/xts_test.go diff --git a/glide.lock b/glide.lock index e666628..81b4ae9 100644 --- a/glide.lock +++ b/glide.lock @@ -53,10 +53,6 @@ imports: version: f390dcf405f7b83c997eac1b06768bb9f44dec18 - name: github.com/urfave/cli version: 01857ac33766ce0c93856370626f9799281c14f4 -- name: golang.org/x/crypto - version: 0c565bf13221fb55497d7ae2bb95694db1fd1bff - subpackages: - - pkcs12 - name: golang.org/x/sys version: a408501be4d17ee978c04a618e7a1b22af058c0e subpackages: diff --git a/glide.yaml b/glide.yaml index e1a6bc8..074387b 100644 --- a/glide.yaml +++ b/glide.yaml @@ -24,6 +24,3 @@ import: version: v1.1.3 - package: github.com/BurntSushi/toml version: v0.2.0 -- package: golang.org/x/crypto - subpackages: - - pkcs12 diff --git a/vendor/golang.org/x/crypto/.gitattributes b/vendor/golang.org/x/crypto/.gitattributes deleted file mode 100644 index d2f212e..0000000 --- a/vendor/golang.org/x/crypto/.gitattributes +++ /dev/null @@ -1,10 +0,0 @@ -# Treat all files in this repo as binary, with no git magic updating -# line endings. Windows users contributing to Go will need to use a -# modern version of git and editors capable of LF line endings. -# -# We'll prevent accidental CRLF line endings from entering the repo -# via the git-review gofmt checks. -# -# See golang.org/issue/9281 - -* -text diff --git a/vendor/golang.org/x/crypto/.gitignore b/vendor/golang.org/x/crypto/.gitignore deleted file mode 100644 index 8339fd6..0000000 --- a/vendor/golang.org/x/crypto/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# Add no patterns to .hgignore except for files generated by the build. -last-change diff --git a/vendor/golang.org/x/crypto/AUTHORS b/vendor/golang.org/x/crypto/AUTHORS deleted file mode 100644 index 15167cd..0000000 --- a/vendor/golang.org/x/crypto/AUTHORS +++ /dev/null @@ -1,3 +0,0 @@ -# This source code refers to The Go Authors for copyright purposes. -# The master list of authors is in the main Go distribution, -# visible at http://tip.golang.org/AUTHORS. diff --git a/vendor/golang.org/x/crypto/CONTRIBUTING.md b/vendor/golang.org/x/crypto/CONTRIBUTING.md deleted file mode 100644 index 88dff59..0000000 --- a/vendor/golang.org/x/crypto/CONTRIBUTING.md +++ /dev/null @@ -1,31 +0,0 @@ -# Contributing to Go - -Go is an open source project. - -It is the work of hundreds of contributors. We appreciate your help! - - -## Filing issues - -When [filing an issue](https://golang.org/issue/new), make sure to answer these five questions: - -1. What version of Go are you using (`go version`)? -2. What operating system and processor architecture are you using? -3. What did you do? -4. What did you expect to see? -5. What did you see instead? - -General questions should go to the [golang-nuts mailing list](https://groups.google.com/group/golang-nuts) instead of the issue tracker. -The gophers there will answer or ask you to file an issue if you've tripped over a bug. - -## Contributing code - -Please read the [Contribution Guidelines](https://golang.org/doc/contribute.html) -before sending patches. - -**We do not accept GitHub pull requests** -(we use [Gerrit](https://code.google.com/p/gerrit/) instead for code review). - -Unless otherwise noted, the Go source files are distributed under -the BSD-style license found in the LICENSE file. - diff --git a/vendor/golang.org/x/crypto/CONTRIBUTORS b/vendor/golang.org/x/crypto/CONTRIBUTORS deleted file mode 100644 index 1c4577e..0000000 --- a/vendor/golang.org/x/crypto/CONTRIBUTORS +++ /dev/null @@ -1,3 +0,0 @@ -# This source code was written by the Go contributors. -# The master list of contributors is in the main Go distribution, -# visible at http://tip.golang.org/CONTRIBUTORS. diff --git a/vendor/golang.org/x/crypto/LICENSE b/vendor/golang.org/x/crypto/LICENSE deleted file mode 100644 index 6a66aea..0000000 --- a/vendor/golang.org/x/crypto/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2009 The Go Authors. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/golang.org/x/crypto/PATENTS b/vendor/golang.org/x/crypto/PATENTS deleted file mode 100644 index 7330990..0000000 --- a/vendor/golang.org/x/crypto/PATENTS +++ /dev/null @@ -1,22 +0,0 @@ -Additional IP Rights Grant (Patents) - -"This implementation" means the copyrightable works distributed by -Google as part of the Go project. - -Google hereby grants to You a perpetual, worldwide, non-exclusive, -no-charge, royalty-free, irrevocable (except as stated in this section) -patent license to make, have made, use, offer to sell, sell, import, -transfer and otherwise run, modify and propagate the contents of this -implementation of Go, where such license applies only to those patent -claims, both currently owned or controlled by Google and acquired in -the future, licensable by Google that are necessarily infringed by this -implementation of Go. This grant does not include claims that would be -infringed only as a consequence of further modification of this -implementation. If you or your agent or exclusive licensee institute or -order or agree to the institution of patent litigation against any -entity (including a cross-claim or counterclaim in a lawsuit) alleging -that this implementation of Go or any code incorporated within this -implementation of Go constitutes direct or contributory patent -infringement, or inducement of patent infringement, then any patent -rights granted to you under this License for this implementation of Go -shall terminate as of the date such litigation is filed. diff --git a/vendor/golang.org/x/crypto/README b/vendor/golang.org/x/crypto/README deleted file mode 100644 index f1e0cbf..0000000 --- a/vendor/golang.org/x/crypto/README +++ /dev/null @@ -1,3 +0,0 @@ -This repository holds supplementary Go cryptography libraries. - -To submit changes to this repository, see http://golang.org/doc/contribute.html. diff --git a/vendor/golang.org/x/crypto/acme/internal/acme/acme.go b/vendor/golang.org/x/crypto/acme/internal/acme/acme.go deleted file mode 100644 index 2732999..0000000 --- a/vendor/golang.org/x/crypto/acme/internal/acme/acme.go +++ /dev/null @@ -1,473 +0,0 @@ -// 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 ACME client implementation. -// See https://ietf-wg-acme.github.io/acme/ for details. -// -// This package is a work in progress and makes no API stability promises. -package acme - -import ( - "bytes" - "crypto/rsa" - "encoding/base64" - "encoding/json" - "errors" - "fmt" - "io/ioutil" - "net/http" - "strconv" - "strings" - "time" - - "golang.org/x/net/context" -) - -// Client is an ACME client. -type Client struct { - // HTTPClient optionally specifies an HTTP client to use - // instead of http.DefaultClient. - HTTPClient *http.Client - - // Key is the account key used to register with a CA - // and sign requests. - Key *rsa.PrivateKey -} - -// Discover performs ACME server discovery using the provided discovery endpoint URL. -func (c *Client) Discover(url string) (*Directory, error) { - res, err := c.httpClient().Get(url) - if err != nil { - return nil, err - } - defer res.Body.Close() - if res.StatusCode != http.StatusOK { - return nil, responseError(res) - } - var v struct { - Reg string `json:"new-reg"` - Authz string `json:"new-authz"` - Cert string `json:"new-cert"` - Revoke string `json:"revoke-cert"` - Meta struct { - Terms string `json:"terms-of-service"` - Website string `json:"website"` - CAA []string `json:"caa-identities"` - } - } - if json.NewDecoder(res.Body).Decode(&v); err != nil { - return nil, err - } - return &Directory{ - RegURL: v.Reg, - AuthzURL: v.Authz, - CertURL: v.Cert, - RevokeURL: v.Revoke, - Terms: v.Meta.Terms, - Website: v.Meta.Website, - CAA: v.Meta.CAA, - }, nil -} - -// CreateCert requests a new certificate. -// In the case where CA server does not provide the issued certificate in the response, -// CreateCert will poll certURL using c.FetchCert, which will result in additional round-trips. -// In such scenario the caller can cancel the polling with ctx. -// -// If the bundle is true, the returned value will also contain CA (the issuer) certificate. -// The url argument is an Directory.CertURL value, typically obtained from c.Discover. -// The csr is a DER encoded certificate signing request. -func (c *Client) CreateCert(ctx context.Context, url string, csr []byte, exp time.Duration, bundle bool) (der [][]byte, certURL string, err error) { - req := struct { - Resource string `json:"resource"` - CSR string `json:"csr"` - NotBefore string `json:"notBefore,omitempty"` - NotAfter string `json:"notAfter,omitempty"` - }{ - Resource: "new-cert", - CSR: base64.RawURLEncoding.EncodeToString(csr), - } - now := timeNow() - req.NotBefore = now.Format(time.RFC3339) - if exp > 0 { - req.NotAfter = now.Add(exp).Format(time.RFC3339) - } - - res, err := c.postJWS(url, req) - if err != nil { - return nil, "", err - } - defer res.Body.Close() - if res.StatusCode != http.StatusCreated { - return nil, "", responseError(res) - } - - curl := res.Header.Get("location") // cert permanent URL - if res.ContentLength == 0 { - // no cert in the body; poll until we get it - cert, err := c.FetchCert(ctx, curl, bundle) - return cert, curl, err - } - // slurp issued cert and ca, if requested - cert, err := responseCert(c.httpClient(), res, bundle) - return cert, curl, err -} - -// 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. -// -// The returned value will also contain CA (the issuer) certificate if bundle == true. -// -// http.DefaultClient is used if client argument is nil. -func (c *Client) FetchCert(ctx context.Context, url string, bundle bool) ([][]byte, error) { - for { - res, err := c.httpClient().Get(url) - if err != nil { - return nil, err - } - defer res.Body.Close() - if res.StatusCode == http.StatusOK { - return responseCert(c.httpClient(), res, bundle) - } - if res.StatusCode > 299 { - return nil, responseError(res) - } - d, err := retryAfter(res.Header.Get("retry-after")) - if err != nil { - d = 3 * time.Second - } - select { - case <-time.After(d): - // retry - case <-ctx.Done(): - return nil, ctx.Err() - } - } -} - -// Register creates a new account registration by following the "new-reg" flow. -// It returns registered account. The a argument is not modified. -// -// The url argument is typically an Directory.RegURL obtained from c.Discover. -func (c *Client) Register(url string, a *Account) (*Account, error) { - return c.doReg(url, "new-reg", a) -} - -// GetReg retrieves an existing registration. -// The url argument is an Account.URI, typically obtained from c.Register. -func (c *Client) GetReg(url string) (*Account, error) { - a := &Account{URI: url} - return c.doReg(url, "reg", a) -} - -// UpdateReg updates an existing registration. -// It returns an updated account copy. The provided account is not modified. -// -// The url argument is an Account.URI, usually obtained with c.Register. -func (c *Client) UpdateReg(url string, a *Account) (*Account, error) { - return c.doReg(url, "reg", a) -} - -// Authorize performs the initial step in an authorization 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. -// -// The url argument is an authz URL, usually obtained with c.Register. -func (c *Client) Authorize(url, domain string) (*Authorization, error) { - 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: "dns", Value: domain}, - } - res, err := c.postJWS(url, req) - if err != nil { - return nil, err - } - defer res.Body.Close() - if res.StatusCode != http.StatusCreated { - return nil, responseError(res) - } - - var v wireAuthz - if err := json.NewDecoder(res.Body).Decode(&v); err != nil { - return nil, fmt.Errorf("Decode: %v", err) - } - if v.Status != StatusPending { - return nil, fmt.Errorf("Unexpected status: %s", v.Status) - } - return v.authorization(res.Header.Get("Location")), nil -} - -// GetAuthz retrieves the current status of an authorization flow. -// -// A client typically polls an authz status using this method. -func (c *Client) GetAuthz(url string) (*Authorization, error) { - res, err := c.httpClient().Get(url) - if err != nil { - return nil, err - } - defer res.Body.Close() - if res.StatusCode != http.StatusOK && res.StatusCode != http.StatusAccepted { - return nil, responseError(res) - } - var v wireAuthz - if err := json.NewDecoder(res.Body).Decode(&v); err != nil { - return nil, fmt.Errorf("Decode: %v", err) - } - return v.authorization(url), nil -} - -// GetChallenge retrieves the current status of an challenge. -// -// A client typically polls a challenge status using this method. -func (c *Client) GetChallenge(url string) (*Challenge, error) { - res, err := c.httpClient().Get(url) - if err != nil { - return nil, err - } - defer res.Body.Close() - if res.StatusCode != http.StatusOK && res.StatusCode != http.StatusAccepted { - return nil, responseError(res) - } - v := wireChallenge{URI: url} - if err := json.NewDecoder(res.Body).Decode(&v); err != nil { - return nil, fmt.Errorf("Decode: %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(chal *Challenge) (*Challenge, error) { - req := struct { - Resource string `json:"resource"` - Type string `json:"type"` - Auth string `json:"keyAuthorization"` - }{ - Resource: "challenge", - Type: chal.Type, - Auth: keyAuth(&c.Key.PublicKey, chal.Token), - } - res, err := c.postJWS(chal.URI, req) - if err != nil { - return nil, err - } - defer res.Body.Close() - // Note: the protocol specifies 200 as the expected response code, but - // letsencrypt seems to be returning 202. - if res.StatusCode != http.StatusOK && res.StatusCode != http.StatusAccepted { - return nil, responseError(res) - } - - var v wireChallenge - if err := json.NewDecoder(res.Body).Decode(&v); err != nil { - return nil, fmt.Errorf("Decode: %v", err) - } - return v.challenge(), nil -} - -// HTTP01Handler creates a new handler which responds to a http-01 challenge. -// The token argument is a Challenge.Token value. -func (c *Client) HTTP01Handler(token string) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - if !strings.HasSuffix(r.URL.Path, token) { - w.WriteHeader(http.StatusNotFound) - return - } - w.Header().Set("content-type", "text/plain") - w.Write([]byte(keyAuth(&c.Key.PublicKey, token))) - }) -} - -func (c *Client) httpClient() *http.Client { - if c.HTTPClient != nil { - return c.HTTPClient - } - return http.DefaultClient -} - -// postJWS signs body and posts it to the provided url. -// The body argument must be JSON-serializable. -func (c *Client) postJWS(url string, body interface{}) (*http.Response, error) { - nonce, err := fetchNonce(c.httpClient(), url) - if err != nil { - return nil, err - } - b, err := jwsEncodeJSON(body, c.Key, nonce) - if err != nil { - return nil, err - } - req, err := http.NewRequest("POST", url, bytes.NewReader(b)) - if err != nil { - return nil, err - } - return c.httpClient().Do(req) -} - -// doReg sends all types of registration requests. -// The type of request is identified by typ argument, which is a "resource" -// in the ACME spec terms. -// -// A non-nil acct argument indicates whether the intention is to mutate data -// of the Account. Only Contact and Agreement of its fields are used -// in such cases. -// -// The fields of acct will be populate with the server response -// and may be overwritten. -func (c *Client) doReg(url string, typ string, acct *Account) (*Account, error) { - req := struct { - Resource string `json:"resource"` - Contact []string `json:"contact,omitempty"` - Agreement string `json:"agreement,omitempty"` - }{ - Resource: typ, - } - if acct != nil { - req.Contact = acct.Contact - req.Agreement = acct.AgreedTerms - } - res, err := c.postJWS(url, req) - if err != nil { - return nil, err - } - defer res.Body.Close() - if res.StatusCode < 200 || res.StatusCode > 299 { - return nil, responseError(res) - } - - var v struct { - Contact []string - Agreement string - Authorizations string - Certificates string - } - if err := json.NewDecoder(res.Body).Decode(&v); err != nil { - return nil, fmt.Errorf("Decode: %v", err) - } - return &Account{ - URI: res.Header.Get("Location"), - Contact: v.Contact, - AgreedTerms: v.Agreement, - CurrentTerms: linkHeader(res.Header, "terms-of-service"), - Authz: linkHeader(res.Header, "next"), - Authorizations: v.Authorizations, - Certificates: v.Certificates, - }, nil -} - -func responseCert(client *http.Client, res *http.Response, bundle bool) ([][]byte, error) { - b, err := ioutil.ReadAll(res.Body) - if err != nil { - return nil, fmt.Errorf("ReadAll: %v", err) - } - cert := [][]byte{b} - if !bundle { - return cert, nil - } - - // append ca cert - up := linkHeader(res.Header, "up") - if up == "" { - return nil, errors.New("rel=up link not found") - } - res, err = client.Get(up) - if err != nil { - return nil, err - } - defer res.Body.Close() - if res.StatusCode != http.StatusOK { - return nil, responseError(res) - } - b, err = ioutil.ReadAll(res.Body) - if err != nil { - return nil, err - } - return append(cert, b), nil -} - -// 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 := struct { - Status int - Type string - Detail string - }{ - 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 &Error{ - StatusCode: e.Status, - ProblemType: e.Type, - Detail: e.Detail, - Header: resp.Header, - } -} - -func fetchNonce(client *http.Client, url string) (string, error) { - resp, err := client.Head(url) - if err != nil { - return "", nil - } - defer resp.Body.Close() - enc := resp.Header.Get("replay-nonce") - if enc == "" { - return "", errors.New("nonce not found") - } - return enc, nil -} - -func linkHeader(h http.Header, rel string) 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 { - return strings.Trim(parts[0], "<>") - } - } - } - return "" -} - -func retryAfter(v string) (time.Duration, error) { - if i, err := strconv.Atoi(v); err == nil { - return time.Duration(i) * time.Second, nil - } - t, err := http.ParseTime(v) - if err != nil { - return 0, err - } - return t.Sub(timeNow()), nil -} - -// keyAuth generates a key authorization string for a given token. -func keyAuth(pub *rsa.PublicKey, token string) string { - return fmt.Sprintf("%s.%s", token, JWKThumbprint(pub)) -} - -// timeNow is useful for testing for fixed current time. -var timeNow = time.Now diff --git a/vendor/golang.org/x/crypto/acme/internal/acme/acme_test.go b/vendor/golang.org/x/crypto/acme/internal/acme/acme_test.go deleted file mode 100644 index f9d17c3..0000000 --- a/vendor/golang.org/x/crypto/acme/internal/acme/acme_test.go +++ /dev/null @@ -1,759 +0,0 @@ -// 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/rand" - "crypto/x509" - "crypto/x509/pkix" - "encoding/base64" - "encoding/json" - "fmt" - "io/ioutil" - "math/big" - "net/http" - "net/http/httptest" - "reflect" - "strings" - "testing" - "time" - - "golang.org/x/net/context" -) - -// Decodes a JWS-encoded request and unmarshals the decoded JSON into a provided -// interface. -func decodeJWSRequest(t *testing.T, v interface{}, r *http.Request) { - // Decode request - var req struct{ Payload string } - if err := json.NewDecoder(r.Body).Decode(&req); err != nil { - t.Fatal(err) - } - payload, err := base64.RawURLEncoding.DecodeString(req.Payload) - if err != nil { - t.Fatal(err) - } - err = json.Unmarshal(payload, v) - if err != nil { - t.Fatal(err) - } -} - -func TestDiscover(t *testing.T) { - const ( - reg = "https://example.com/acme/new-reg" - authz = "https://example.com/acme/new-authz" - cert = "https://example.com/acme/new-cert" - revoke = "https://example.com/acme/revoke-cert" - ) - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.Header().Set("content-type", "application/json") - fmt.Fprintf(w, `{ - "new-reg": %q, - "new-authz": %q, - "new-cert": %q, - "revoke-cert": %q - }`, reg, authz, cert, revoke) - })) - defer ts.Close() - ep, err := (&Client{}).Discover(ts.URL) - if err != nil { - t.Fatal(err) - } - if ep.RegURL != reg { - t.Errorf("RegURL = %q; want %q", ep.RegURL, reg) - } - if ep.AuthzURL != authz { - t.Errorf("authzURL = %q; want %q", ep.AuthzURL, authz) - } - if ep.CertURL != cert { - t.Errorf("certURL = %q; want %q", ep.CertURL, cert) - } - if ep.RevokeURL != revoke { - t.Errorf("revokeURL = %q; want %q", ep.RevokeURL, revoke) - } -} - -func TestRegister(t *testing.T) { - contacts := []string{"mailto:admin@example.com"} - - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - if r.Method == "HEAD" { - w.Header().Set("replay-nonce", "test-nonce") - return - } - if r.Method != "POST" { - t.Errorf("r.Method = %q; want POST", r.Method) - } - - var j struct { - Resource string - Contact []string - Agreement string - } - decodeJWSRequest(t, &j, r) - - // Test request - if j.Resource != "new-reg" { - t.Errorf("j.Resource = %q; want new-reg", j.Resource) - } - if !reflect.DeepEqual(j.Contact, contacts) { - t.Errorf("j.Contact = %v; want %v", j.Contact, contacts) - } - - w.Header().Set("Location", "https://ca.tld/acme/reg/1") - w.Header().Set("Link", `;rel="next"`) - w.Header().Add("Link", `;rel="recover"`) - w.Header().Add("Link", `;rel="terms-of-service"`) - w.WriteHeader(http.StatusCreated) - b, _ := json.Marshal(contacts) - fmt.Fprintf(w, `{ - "key":%q, - "contact":%s - }`, testKeyThumbprint, b) - })) - defer ts.Close() - - c := Client{Key: testKey} - a := &Account{Contact: contacts} - var err error - if a, err = c.Register(ts.URL, a); err != nil { - t.Fatal(err) - } - if a.URI != "https://ca.tld/acme/reg/1" { - t.Errorf("a.URI = %q; want https://ca.tld/acme/reg/1", a.URI) - } - if a.Authz != "https://ca.tld/acme/new-authz" { - t.Errorf("a.Authz = %q; want https://ca.tld/acme/new-authz", a.Authz) - } - if a.CurrentTerms != "https://ca.tld/acme/terms" { - t.Errorf("a.CurrentTerms = %q; want https://ca.tld/acme/terms", a.CurrentTerms) - } - if !reflect.DeepEqual(a.Contact, contacts) { - t.Errorf("a.Contact = %v; want %v", a.Contact, contacts) - } -} - -func TestUpdateReg(t *testing.T) { - const terms = "https://ca.tld/acme/terms" - contacts := []string{"mailto:admin@example.com"} - - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - if r.Method == "HEAD" { - w.Header().Set("replay-nonce", "test-nonce") - return - } - if r.Method != "POST" { - t.Errorf("r.Method = %q; want POST", r.Method) - } - - var j struct { - Resource string - Contact []string - Agreement string - } - decodeJWSRequest(t, &j, r) - - // Test request - if j.Resource != "reg" { - t.Errorf("j.Resource = %q; want reg", j.Resource) - } - if j.Agreement != terms { - t.Errorf("j.Agreement = %q; want %q", j.Agreement, terms) - } - if !reflect.DeepEqual(j.Contact, contacts) { - t.Errorf("j.Contact = %v; want %v", j.Contact, contacts) - } - - w.Header().Set("Link", `;rel="next"`) - w.Header().Add("Link", `;rel="recover"`) - w.Header().Add("Link", fmt.Sprintf(`<%s>;rel="terms-of-service"`, terms)) - w.WriteHeader(http.StatusOK) - b, _ := json.Marshal(contacts) - fmt.Fprintf(w, `{ - "key":%q, - "contact":%s, - "agreement":%q - }`, testKeyThumbprint, b, terms) - })) - defer ts.Close() - - c := Client{Key: testKey} - a := &Account{Contact: contacts, AgreedTerms: terms} - var err error - if a, err = c.UpdateReg(ts.URL, a); err != nil { - t.Fatal(err) - } - if a.Authz != "https://ca.tld/acme/new-authz" { - t.Errorf("a.Authz = %q; want https://ca.tld/acme/new-authz", a.Authz) - } - if a.AgreedTerms != terms { - t.Errorf("a.AgreedTerms = %q; want %q", a.AgreedTerms, terms) - } - if a.CurrentTerms != terms { - t.Errorf("a.CurrentTerms = %q; want %q", a.CurrentTerms, terms) - } -} - -func TestGetReg(t *testing.T) { - const terms = "https://ca.tld/acme/terms" - const newTerms = "https://ca.tld/acme/new-terms" - contacts := []string{"mailto:admin@example.com"} - - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - if r.Method == "HEAD" { - w.Header().Set("replay-nonce", "test-nonce") - return - } - if r.Method != "POST" { - t.Errorf("r.Method = %q; want POST", r.Method) - } - - var j struct { - Resource string - Contact []string - Agreement string - } - decodeJWSRequest(t, &j, r) - - // Test request - if j.Resource != "reg" { - t.Errorf("j.Resource = %q; want reg", j.Resource) - } - if len(j.Contact) != 0 { - t.Errorf("j.Contact = %v", j.Contact) - } - if j.Agreement != "" { - t.Errorf("j.Agreement = %q", j.Agreement) - } - - w.Header().Set("Link", `;rel="next"`) - w.Header().Add("Link", `;rel="recover"`) - w.Header().Add("Link", fmt.Sprintf(`<%s>;rel="terms-of-service"`, newTerms)) - w.WriteHeader(http.StatusOK) - b, _ := json.Marshal(contacts) - fmt.Fprintf(w, `{ - "key":%q, - "contact":%s, - "agreement":%q - }`, testKeyThumbprint, b, terms) - })) - defer ts.Close() - - c := Client{Key: testKey} - a, err := c.GetReg(ts.URL) - if err != nil { - t.Fatal(err) - } - if a.Authz != "https://ca.tld/acme/new-authz" { - t.Errorf("a.AuthzURL = %q; want https://ca.tld/acme/new-authz", a.Authz) - } - if a.AgreedTerms != terms { - t.Errorf("a.AgreedTerms = %q; want %q", a.AgreedTerms, terms) - } - if a.CurrentTerms != newTerms { - t.Errorf("a.CurrentTerms = %q; want %q", a.CurrentTerms, newTerms) - } -} - -func TestAuthorize(t *testing.T) { - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - if r.Method == "HEAD" { - w.Header().Set("replay-nonce", "test-nonce") - return - } - if r.Method != "POST" { - t.Errorf("r.Method = %q; want POST", r.Method) - } - - var j struct { - Resource string - Identifier struct { - Type string - Value string - } - } - decodeJWSRequest(t, &j, r) - - // Test request - if j.Resource != "new-authz" { - t.Errorf("j.Resource = %q; want new-authz", j.Resource) - } - if j.Identifier.Type != "dns" { - t.Errorf("j.Identifier.Type = %q; want dns", j.Identifier.Type) - } - if j.Identifier.Value != "example.com" { - t.Errorf("j.Identifier.Value = %q; want example.com", j.Identifier.Value) - } - - w.Header().Set("Location", "https://ca.tld/acme/auth/1") - w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, `{ - "identifier": {"type":"dns","value":"example.com"}, - "status":"pending", - "challenges":[ - { - "type":"http-01", - "status":"pending", - "uri":"https://ca.tld/acme/challenge/publickey/id1", - "token":"token1" - }, - { - "type":"tls-sni-01", - "status":"pending", - "uri":"https://ca.tld/acme/challenge/publickey/id2", - "token":"token2" - } - ], - "combinations":[[0],[1]]}`) - })) - defer ts.Close() - - cl := Client{Key: testKey} - auth, err := cl.Authorize(ts.URL, "example.com") - if err != nil { - t.Fatal(err) - } - - if auth.URI != "https://ca.tld/acme/auth/1" { - t.Errorf("URI = %q; want https://ca.tld/acme/auth/1", auth.URI) - } - if auth.Status != "pending" { - t.Errorf("Status = %q; want pending", auth.Status) - } - if auth.Identifier.Type != "dns" { - t.Errorf("Identifier.Type = %q; want dns", auth.Identifier.Type) - } - if auth.Identifier.Value != "example.com" { - t.Errorf("Identifier.Value = %q; want example.com", auth.Identifier.Value) - } - - if n := len(auth.Challenges); n != 2 { - t.Fatalf("len(auth.Challenges) = %d; want 2", n) - } - - c := auth.Challenges[0] - if c.Type != "http-01" { - t.Errorf("c.Type = %q; want http-01", c.Type) - } - if c.URI != "https://ca.tld/acme/challenge/publickey/id1" { - t.Errorf("c.URI = %q; want https://ca.tld/acme/challenge/publickey/id1", c.URI) - } - if c.Token != "token1" { - t.Errorf("c.Token = %q; want token1", c.Type) - } - - c = auth.Challenges[1] - if c.Type != "tls-sni-01" { - t.Errorf("c.Type = %q; want tls-sni-01", c.Type) - } - if c.URI != "https://ca.tld/acme/challenge/publickey/id2" { - t.Errorf("c.URI = %q; want https://ca.tld/acme/challenge/publickey/id2", c.URI) - } - if c.Token != "token2" { - t.Errorf("c.Token = %q; want token2", c.Type) - } - - combs := [][]int{{0}, {1}} - if !reflect.DeepEqual(auth.Combinations, combs) { - t.Errorf("auth.Combinations: %+v\nwant: %+v\n", auth.Combinations, combs) - } -} - -func TestPollAuthz(t *testing.T) { - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - if r.Method != "GET" { - t.Errorf("r.Method = %q; want GET", r.Method) - } - - w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, `{ - "identifier": {"type":"dns","value":"example.com"}, - "status":"pending", - "challenges":[ - { - "type":"http-01", - "status":"pending", - "uri":"https://ca.tld/acme/challenge/publickey/id1", - "token":"token1" - }, - { - "type":"tls-sni-01", - "status":"pending", - "uri":"https://ca.tld/acme/challenge/publickey/id2", - "token":"token2" - } - ], - "combinations":[[0],[1]]}`) - })) - defer ts.Close() - - cl := Client{Key: testKey} - auth, err := cl.GetAuthz(ts.URL) - if err != nil { - t.Fatal(err) - } - - if auth.Status != "pending" { - t.Errorf("Status = %q; want pending", auth.Status) - } - if auth.Identifier.Type != "dns" { - t.Errorf("Identifier.Type = %q; want dns", auth.Identifier.Type) - } - if auth.Identifier.Value != "example.com" { - t.Errorf("Identifier.Value = %q; want example.com", auth.Identifier.Value) - } - - if n := len(auth.Challenges); n != 2 { - t.Fatalf("len(set.Challenges) = %d; want 2", n) - } - - c := auth.Challenges[0] - if c.Type != "http-01" { - t.Errorf("c.Type = %q; want http-01", c.Type) - } - if c.URI != "https://ca.tld/acme/challenge/publickey/id1" { - t.Errorf("c.URI = %q; want https://ca.tld/acme/challenge/publickey/id1", c.URI) - } - if c.Token != "token1" { - t.Errorf("c.Token = %q; want token1", c.Type) - } - - c = auth.Challenges[1] - if c.Type != "tls-sni-01" { - t.Errorf("c.Type = %q; want tls-sni-01", c.Type) - } - if c.URI != "https://ca.tld/acme/challenge/publickey/id2" { - t.Errorf("c.URI = %q; want https://ca.tld/acme/challenge/publickey/id2", c.URI) - } - if c.Token != "token2" { - t.Errorf("c.Token = %q; want token2", c.Type) - } - - combs := [][]int{{0}, {1}} - if !reflect.DeepEqual(auth.Combinations, combs) { - t.Errorf("auth.Combinations: %+v\nwant: %+v\n", auth.Combinations, combs) - } -} - -func TestPollChallenge(t *testing.T) { - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - if r.Method != "GET" { - t.Errorf("r.Method = %q; want GET", r.Method) - } - - w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, `{ - "type":"http-01", - "status":"pending", - "uri":"https://ca.tld/acme/challenge/publickey/id1", - "token":"token1"}`) - })) - defer ts.Close() - - cl := Client{Key: testKey} - chall, err := cl.GetChallenge(ts.URL) - if err != nil { - t.Fatal(err) - } - - if chall.Status != "pending" { - t.Errorf("Status = %q; want pending", chall.Status) - } - if chall.Type != "http-01" { - t.Errorf("c.Type = %q; want http-01", chall.Type) - } - if chall.URI != "https://ca.tld/acme/challenge/publickey/id1" { - t.Errorf("c.URI = %q; want https://ca.tld/acme/challenge/publickey/id1", chall.URI) - } - if chall.Token != "token1" { - t.Errorf("c.Token = %q; want token1", chall.Type) - } -} - -func TestAcceptChallenge(t *testing.T) { - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - if r.Method == "HEAD" { - w.Header().Set("replay-nonce", "test-nonce") - return - } - if r.Method != "POST" { - t.Errorf("r.Method = %q; want POST", r.Method) - } - - var j struct { - Resource string - Type string - Auth string `json:"keyAuthorization"` - } - decodeJWSRequest(t, &j, r) - - // Test request - if j.Resource != "challenge" { - t.Errorf(`resource = %q; want "challenge"`, j.Resource) - } - if j.Type != "http-01" { - t.Errorf(`type = %q; want "http-01"`, j.Type) - } - keyAuth := "token1." + testKeyThumbprint - if j.Auth != keyAuth { - t.Errorf(`keyAuthorization = %q; want %q`, j.Auth, keyAuth) - } - - // Respond to request - w.WriteHeader(http.StatusAccepted) - fmt.Fprintf(w, `{ - "type":"http-01", - "status":"pending", - "uri":"https://ca.tld/acme/challenge/publickey/id1", - "token":"token1", - "keyAuthorization":%q - }`, keyAuth) - })) - defer ts.Close() - - cl := Client{Key: testKey} - c, err := cl.Accept(&Challenge{ - URI: ts.URL, - Token: "token1", - Type: "http-01", - }) - if err != nil { - t.Fatal(err) - } - - if c.Type != "http-01" { - t.Errorf("c.Type = %q; want http-01", c.Type) - } - if c.URI != "https://ca.tld/acme/challenge/publickey/id1" { - t.Errorf("c.URI = %q; want https://ca.tld/acme/challenge/publickey/id1", c.URI) - } - if c.Token != "token1" { - t.Errorf("c.Token = %q; want token1", c.Type) - } -} - -func TestNewCert(t *testing.T) { - notBefore := time.Now() - notAfter := notBefore.AddDate(0, 2, 0) - timeNow = func() time.Time { return notBefore } - - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - if r.Method == "HEAD" { - w.Header().Set("replay-nonce", "test-nonce") - return - } - if r.Method != "POST" { - t.Errorf("r.Method = %q; want POST", r.Method) - } - - var j struct { - Resource string `json:"resource"` - CSR string `json:"csr"` - NotBefore string `json:"notBefore,omitempty"` - NotAfter string `json:"notAfter,omitempty"` - } - decodeJWSRequest(t, &j, r) - - // Test request - if j.Resource != "new-cert" { - t.Errorf(`resource = %q; want "new-cert"`, j.Resource) - } - if j.NotBefore != notBefore.Format(time.RFC3339) { - t.Errorf(`notBefore = %q; wanted %q`, j.NotBefore, notBefore.Format(time.RFC3339)) - } - if j.NotAfter != notAfter.Format(time.RFC3339) { - t.Errorf(`notAfter = %q; wanted %q`, j.NotAfter, notAfter.Format(time.RFC3339)) - } - - // Respond to request - template := x509.Certificate{ - SerialNumber: big.NewInt(int64(1)), - Subject: pkix.Name{ - Organization: []string{"goacme"}, - }, - NotBefore: notBefore, - NotAfter: notAfter, - - KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, - ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, - BasicConstraintsValid: true, - } - - sampleCert, err := x509.CreateCertificate(rand.Reader, &template, &template, &testKey.PublicKey, testKey) - if err != nil { - t.Fatalf("Error creating certificate: %v", err) - } - - w.Header().Set("Location", "https://ca.tld/acme/cert/1") - w.WriteHeader(http.StatusCreated) - w.Write(sampleCert) - })) - defer ts.Close() - - csr := x509.CertificateRequest{ - Version: 0, - Subject: pkix.Name{ - CommonName: "example.com", - Organization: []string{"goacme"}, - }, - } - csrb, err := x509.CreateCertificateRequest(rand.Reader, &csr, testKey) - if err != nil { - t.Fatal(err) - } - - c := Client{Key: testKey} - cert, certURL, err := c.CreateCert(context.Background(), ts.URL, csrb, notAfter.Sub(notBefore), false) - if err != nil { - t.Fatal(err) - } - if cert == nil { - t.Errorf("cert is nil") - } - if certURL != "https://ca.tld/acme/cert/1" { - t.Errorf("certURL = %q; want https://ca.tld/acme/cert/1", certURL) - } -} - -func TestFetchCert(t *testing.T) { - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.Write([]byte{1}) - })) - defer ts.Close() - res, err := (&Client{}).FetchCert(context.Background(), ts.URL, false) - if err != nil { - t.Fatalf("FetchCert: %v", err) - } - cert := [][]byte{{1}} - if !reflect.DeepEqual(res, cert) { - t.Errorf("res = %v; want %v", res, cert) - } -} - -func TestFetchCertRetry(t *testing.T) { - var count int - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - if count < 1 { - w.Header().Set("retry-after", "0") - w.WriteHeader(http.StatusAccepted) - count++ - return - } - w.Write([]byte{1}) - })) - defer ts.Close() - res, err := (&Client{}).FetchCert(context.Background(), ts.URL, false) - if err != nil { - t.Fatalf("FetchCert: %v", err) - } - cert := [][]byte{{1}} - if !reflect.DeepEqual(res, cert) { - t.Errorf("res = %v; want %v", res, cert) - } -} - -func TestFetchCertCancel(t *testing.T) { - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.Header().Set("retry-after", "0") - w.WriteHeader(http.StatusAccepted) - })) - defer ts.Close() - ctx, cancel := context.WithCancel(context.Background()) - done := make(chan struct{}) - var err error - go func() { - _, err = (&Client{}).FetchCert(ctx, ts.URL, false) - close(done) - }() - cancel() - <-done - if err != context.Canceled { - t.Errorf("err = %v; want %v", err, context.Canceled) - } -} - -func TestFetchNonce(t *testing.T) { - tests := []struct { - code int - nonce string - }{ - {http.StatusOK, "nonce1"}, - {http.StatusBadRequest, "nonce2"}, - {http.StatusOK, ""}, - } - var i int - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - if r.Method != "HEAD" { - t.Errorf("%d: r.Method = %q; want HEAD", i, r.Method) - } - w.Header().Set("replay-nonce", tests[i].nonce) - w.WriteHeader(tests[i].code) - })) - defer ts.Close() - for ; i < len(tests); i++ { - test := tests[i] - n, err := fetchNonce(http.DefaultClient, ts.URL) - if n != test.nonce { - t.Errorf("%d: n=%q; want %q", i, n, test.nonce) - } - switch { - case err == nil && test.nonce == "": - t.Errorf("%d: n=%q, err=%v; want non-nil error", i, n, err) - case err != nil && test.nonce != "": - t.Errorf("%d: n=%q, err=%v; want %q", i, n, err, test.nonce) - } - } -} - -func TestLinkHeader(t *testing.T) { - h := http.Header{"Link": { - `;rel="next"`, - `; rel=recover`, - `; foo=bar; rel="terms-of-service"`, - }} - tests := []struct{ in, out string }{ - {"next", "https://example.com/acme/new-authz"}, - {"recover", "https://example.com/acme/recover-reg"}, - {"terms-of-service", "https://example.com/acme/terms"}, - {"empty", ""}, - } - for i, test := range tests { - if v := linkHeader(h, test.in); v != test.out { - t.Errorf("%d: parseLinkHeader(%q): %q; want %q", i, test.in, v, test.out) - } - } -} - -func TestErrorResponse(t *testing.T) { - s := `{ - "status": 400, - "type": "urn:acme:error:xxx", - "detail": "text" - }` - res := &http.Response{ - StatusCode: 400, - Status: "400 Bad Request", - Body: ioutil.NopCloser(strings.NewReader(s)), - Header: http.Header{"X-Foo": {"bar"}}, - } - err := responseError(res) - v, ok := err.(*Error) - if !ok { - t.Fatalf("err = %+v (%T); want *Error type", err, err) - } - if v.StatusCode != 400 { - t.Errorf("v.StatusCode = %v; want 400", v.StatusCode) - } - if v.ProblemType != "urn:acme:error:xxx" { - t.Errorf("v.ProblemType = %q; want urn:acme:error:xxx", v.ProblemType) - } - if v.Detail != "text" { - t.Errorf("v.Detail = %q; want text", v.Detail) - } - if !reflect.DeepEqual(v.Header, res.Header) { - t.Errorf("v.Header = %+v; want %+v", v.Header, res.Header) - } -} diff --git a/vendor/golang.org/x/crypto/acme/internal/acme/jws.go b/vendor/golang.org/x/crypto/acme/internal/acme/jws.go deleted file mode 100644 index c277529..0000000 --- a/vendor/golang.org/x/crypto/acme/internal/acme/jws.go +++ /dev/null @@ -1,67 +0,0 @@ -// 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/rand" - "crypto/rsa" - "crypto/sha256" - "encoding/base64" - "encoding/json" - "fmt" - "math/big" -) - -// jwsEncodeJSON signs claimset using provided key and a nonce. -// The result is serialized in JSON format. -// See https://tools.ietf.org/html/rfc7515#section-7. -func jwsEncodeJSON(claimset interface{}, key *rsa.PrivateKey, nonce string) ([]byte, error) { - jwk := jwkEncode(&key.PublicKey) - phead := fmt.Sprintf(`{"alg":"RS256","jwk":%s,"nonce":%q}`, jwk, nonce) - phead = base64.RawURLEncoding.EncodeToString([]byte(phead)) - cs, err := json.Marshal(claimset) - if err != nil { - return nil, err - } - payload := base64.RawURLEncoding.EncodeToString(cs) - h := sha256.New() - h.Write([]byte(phead + "." + payload)) - sig, err := rsa.SignPKCS1v15(rand.Reader, key, crypto.SHA256, h.Sum(nil)) - if err != nil { - return nil, err - } - enc := struct { - Protected string `json:"protected"` - Payload string `json:"payload"` - Sig string `json:"signature"` - }{ - Protected: phead, - Payload: payload, - Sig: base64.RawURLEncoding.EncodeToString(sig), - } - return json.Marshal(&enc) -} - -// jwkEncode encodes public part of an RSA key into a JWK. -// The result is also suitable for creating a JWK thumbprint. -func jwkEncode(pub *rsa.PublicKey) string { - n := pub.N - e := big.NewInt(int64(pub.E)) - // fields 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()), - ) -} - -// JWKThumbprint creates a JWK thumbprint out of pub -// as specified in https://tools.ietf.org/html/rfc7638. -func JWKThumbprint(pub *rsa.PublicKey) string { - jwk := jwkEncode(pub) - b := sha256.Sum256([]byte(jwk)) - return base64.RawURLEncoding.EncodeToString(b[:]) -} diff --git a/vendor/golang.org/x/crypto/acme/internal/acme/jws_test.go b/vendor/golang.org/x/crypto/acme/internal/acme/jws_test.go deleted file mode 100644 index 7afd950..0000000 --- a/vendor/golang.org/x/crypto/acme/internal/acme/jws_test.go +++ /dev/null @@ -1,139 +0,0 @@ -// 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/rsa" - "crypto/x509" - "encoding/base64" - "encoding/json" - "encoding/pem" - "math/big" - "testing" -) - -const testKeyPEM = ` ------BEGIN RSA PRIVATE KEY----- -MIIEowIBAAKCAQEA4xgZ3eRPkwoRvy7qeRUbmMDe0V+xH9eWLdu0iheeLlrmD2mq -WXfP9IeSKApbn34g8TuAS9g5zhq8ELQ3kmjr+KV86GAMgI6VAcGlq3QrzpTCf/30 -Ab7+zawrfRaFONa1HwEzPY1KHnGVkxJc85gNkwYI9SY2RHXtvln3zs5wITNrdosq -EXeaIkVYBEhbhNu54pp3kxo6TuWLi9e6pXeWetEwmlBwtWZlPoib2j3TxLBksKZf -oyFyek380mHgJAumQ/I2fjj98/97mk3ihOY4AgVdCDj1z/GCoZkG5Rq7nbCGyosy -KWyDX00Zs+nNqVhoLeIvXC4nnWdJMZ6rogxyQQIDAQABAoIBACIEZTOI1Kao9nmV -9IeIsuaR1Y61b9neOF/MLmIVIZu+AAJFCMB4Iw11FV6sFodwpEyeZhx2WkpWVN+H -r19eGiLX3zsL0DOdqBJoSIHDWCCMxgnYJ6nvS0nRxX3qVrBp8R2g12Ub+gNPbmFm -ecf/eeERIVxfifd9VsyRu34eDEvcmKFuLYbElFcPh62xE3x12UZvV/sN7gXbawpP -G+w255vbE5MoaKdnnO83cTFlcHvhn24M/78qP7Te5OAeelr1R89kYxQLpuGe4fbS -zc6E3ym5Td6urDetGGrSY1Eu10/8sMusX+KNWkm+RsBRbkyKq72ks/qKpOxOa+c6 -9gm+Y8ECgYEA/iNUyg1ubRdH11p82l8KHtFC1DPE0V1gSZsX29TpM5jS4qv46K+s -8Ym1zmrORM8x+cynfPx1VQZQ34EYeCMIX212ryJ+zDATl4NE0I4muMvSiH9vx6Xc -7FmhNnaYzPsBL5Tm9nmtQuP09YEn8poiOJFiDs/4olnD5ogA5O4THGkCgYEA5MIL -qWYBUuqbEWLRtMruUtpASclrBqNNsJEsMGbeqBJmoMxdHeSZckbLOrqm7GlMyNRJ -Ne/5uWRGSzaMYuGmwsPpERzqEvYFnSrpjW5YtXZ+JtxFXNVfm9Z1gLLgvGpOUCIU -RbpoDckDe1vgUuk3y5+DjZihs+rqIJ45XzXTzBkCgYBWuf3segruJZy5rEKhTv+o -JqeUvRn0jNYYKFpLBeyTVBrbie6GkbUGNIWbrK05pC+c3K9nosvzuRUOQQL1tJbd -4gA3oiD9U4bMFNr+BRTHyZ7OQBcIXdz3t1qhuHVKtnngIAN1p25uPlbRFUNpshnt -jgeVoHlsBhApcs5DUc+pyQKBgDzeHPg/+g4z+nrPznjKnktRY1W+0El93kgi+J0Q -YiJacxBKEGTJ1MKBb8X6sDurcRDm22wMpGfd9I5Cv2v4GsUsF7HD/cx5xdih+G73 -c4clNj/k0Ff5Nm1izPUno4C+0IOl7br39IPmfpSuR6wH/h6iHQDqIeybjxyKvT1G -N0rRAoGBAKGD+4ZI/E1MoJ5CXB8cDDMHagbE3cq/DtmYzE2v1DFpQYu5I4PCm5c7 -EQeIP6dZtv8IMgtGIb91QX9pXvP0aznzQKwYIA8nZgoENCPfiMTPiEDT9e/0lObO -9XWsXpbSTsRPj0sv1rB+UzBJ0PgjK4q2zOF0sNo7b1+6nlM3BWPx ------END RSA PRIVATE KEY----- -` - -// This thumbprint is for the testKey defined above. -const testKeyThumbprint = "6nicxzh6WETQlrvdchkz-U3e3DOQZ4heJKU63rfqMqQ" - -var testKey *rsa.PrivateKey - -func init() { - d, _ := pem.Decode([]byte(testKeyPEM)) - if d == nil { - panic("no block found in testKeyPEM") - } - var err error - testKey, err = x509.ParsePKCS1PrivateKey(d.Bytes) - if err != nil { - panic(err.Error()) - } -} - -func TestJWSEncodeJSON(t *testing.T) { - claims := struct{ Msg string }{"Hello JWS"} - // JWS signed with testKey and "nonce" as the nonce value - // JSON-serialized JWS fields are split for easier testing - const ( - // {"alg":"RS256","jwk":{"e":"AQAB","kty":"RSA","n":"..."},"nonce":"nonce"} - protected = "eyJhbGciOiJSUzI1NiIsImp3ayI6eyJlIjoiQVFBQiIsImt0eSI6" + - "IlJTQSIsIm4iOiI0eGdaM2VSUGt3b1J2eTdxZVJVYm1NRGUwVi14" + - "SDllV0xkdTBpaGVlTGxybUQybXFXWGZQOUllU0tBcGJuMzRnOFR1" + - "QVM5ZzV6aHE4RUxRM2ttanItS1Y4NkdBTWdJNlZBY0dscTNRcnpw" + - "VENmXzMwQWI3LXphd3JmUmFGT05hMUh3RXpQWTFLSG5HVmt4SmM4" + - "NWdOa3dZSTlTWTJSSFh0dmxuM3pzNXdJVE5yZG9zcUVYZWFJa1ZZ" + - "QkVoYmhOdTU0cHAza3hvNlR1V0xpOWU2cFhlV2V0RXdtbEJ3dFda" + - "bFBvaWIyajNUeExCa3NLWmZveUZ5ZWszODBtSGdKQXVtUV9JMmZq" + - "ajk4Xzk3bWszaWhPWTRBZ1ZkQ0RqMXpfR0NvWmtHNVJxN25iQ0d5" + - "b3N5S1d5RFgwMFpzLW5OcVZob0xlSXZYQzRubldkSk1aNnJvZ3h5" + - "UVEifSwibm9uY2UiOiJub25jZSJ9" - // {"Msg":"Hello JWS"} - payload = "eyJNc2ciOiJIZWxsbyBKV1MifQ" - signature = "eAGUikStX_UxyiFhxSLMyuyBcIB80GeBkFROCpap2sW3EmkU_ggF" + - "knaQzxrTfItICSAXsCLIquZ5BbrSWA_4vdEYrwWtdUj7NqFKjHRa" + - "zpLHcoR7r1rEHvkoP1xj49lS5fc3Wjjq8JUhffkhGbWZ8ZVkgPdC" + - "4tMBWiQDoth-x8jELP_3LYOB_ScUXi2mETBawLgOT2K8rA0Vbbmx" + - "hWNlOWuUf-8hL5YX4IOEwsS8JK_TrTq5Zc9My0zHJmaieqDV0UlP" + - "k0onFjPFkGm7MrPSgd0MqRG-4vSAg2O4hDo7rKv4n8POjjXlNQvM" + - "9IPLr8qZ7usYBKhEGwX3yq_eicAwBw" - ) - - b, err := jwsEncodeJSON(claims, testKey, "nonce") - if err != nil { - t.Fatal(err) - } - var jws struct{ Protected, Payload, Signature string } - if err := json.Unmarshal(b, &jws); err != nil { - t.Fatal(err) - } - if jws.Protected != protected { - t.Errorf("protected:\n%s\nwant:\n%s", jws.Protected, protected) - } - if jws.Payload != payload { - t.Errorf("payload:\n%s\nwant:\n%s", jws.Payload, payload) - } - if jws.Signature != signature { - t.Errorf("signature:\n%s\nwant:\n%s", jws.Signature, signature) - } -} - -func TestJWKThumbprint(t *testing.T) { - // Key example from RFC 7638 - const base64N = "0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAt" + - "VT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMstn6" + - "4tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FD" + - "W2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n9" + - "1CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINH" + - "aQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw" - const base64E = "AQAB" - const expected = "NzbLsXh8uDCcd-6MNwXF4W_7noWXFZAfHkxZsRGC9Xs" - - bytes, err := base64.RawURLEncoding.DecodeString(base64N) - if err != nil { - t.Fatalf("Error parsing example key N: %v", err) - } - n := new(big.Int).SetBytes(bytes) - - bytes, err = base64.RawURLEncoding.DecodeString(base64E) - if err != nil { - t.Fatalf("Error parsing example key E: %v", err) - } - e := new(big.Int).SetBytes(bytes) - - pub := &rsa.PublicKey{N: n, E: int(e.Uint64())} - th := JWKThumbprint(pub) - if th != expected { - t.Errorf("th = %q; want %q", th, expected) - } -} diff --git a/vendor/golang.org/x/crypto/acme/internal/acme/types.go b/vendor/golang.org/x/crypto/acme/internal/acme/types.go deleted file mode 100644 index e64dc11..0000000 --- a/vendor/golang.org/x/crypto/acme/internal/acme/types.go +++ /dev/null @@ -1,181 +0,0 @@ -package acme - -import ( - "fmt" - "net/http" -) - -// ACME server response statuses used to describe Authorization and Challenge states. -const ( - StatusUnknown = "unknown" - StatusPending = "pending" - StatusProcessing = "processing" - StatusValid = "valid" - StatusInvalid = "invalid" - StatusRevoked = "revoked" -) - -// Account is a user account. It is associated with a private key. -type Account struct { - // URI is the account unique ID, which is also a URL used to retrieve - // account data from the CA. - URI string - - // Contact is a slice of contact info used during registration. - Contact []string - - // The terms user has agreed to. - // Zero value indicates that the user hasn't agreed yet. - AgreedTerms string - - // Actual terms of a CA. - CurrentTerms string - - // Authz is the authorization URL used to initiate a new authz flow. - Authz string - - // Authorizations is a URI from which a list of authorizations - // granted to this account can be fetched via a GET request. - Authorizations string - - // Certificates is a URI from which a list of certificates - // issued for this account can be fetched via a GET request. - Certificates string -} - -// Directory is ACME server discovery data. -type Directory struct { - // RegURL is an account endpoint URL, allowing for creating new - // and modifying existing accounts. - RegURL string - - // AuthzURL is used to initiate Identifier Authorization flow. - AuthzURL string - - // CertURL is a new certificate issuance endpoint URL. - CertURL string - - // RevokeURL is used to initiate a certificate revocation flow. - RevokeURL 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 -} - -// Challenge encodes a returned CA challenge. -type Challenge struct { - // Type is the challenge type, e.g. "http-01", "tls-sni-02", "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. - Status string -} - -// Authorization encodes an authorization response. -type Authorization struct { - // URI uniquely identifies a authorization. - URI string - - // Status identifies the status of an authorization. - Status string - - // Identifier is what the account is authorized to represent. - Identifier AuthzID - - // Challenges that the client needs to fulfill in order to prove possession - // of the identifier (for pending authorizations). - // For final authorizations, the challenges that were used. - 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. - Combinations [][]int -} - -// AuthzID is an identifier that an account is authorized to represent. -type AuthzID struct { - Type string // The type of identifier, e.g. "dns". - Value string // The identifier itself, e.g. "example.org". -} - -// 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 - // Header is the original server error response headers. - Header http.Header -} - -func (e *Error) Error() string { - return fmt.Sprintf("%d %s: %s", e.StatusCode, e.ProblemType, e.Detail) -} - -// wireAuthz is ACME JSON representation of Authorization objects. -type wireAuthz struct { - Status string - Challenges []wireChallenge - Combinations [][]int - Identifier struct { - Type string - Value string - } -} - -func (z *wireAuthz) authorization(uri string) *Authorization { - a := &Authorization{ - URI: uri, - Status: z.Status, - Identifier: AuthzID{Type: z.Identifier.Type, Value: z.Identifier.Value}, - Combinations: z.Combinations, // shallow copy - Challenges: make([]*Challenge, len(z.Challenges)), - } - for i, v := range z.Challenges { - a.Challenges[i] = v.challenge() - } - return a -} - -// wireChallenge is ACME JSON challenge representation. -type wireChallenge struct { - URI string `json:"uri"` - Type string - Token string - Status string -} - -func (c *wireChallenge) challenge() *Challenge { - v := &Challenge{ - URI: c.URI, - Type: c.Type, - Token: c.Token, - Status: c.Status, - } - if v.Status == "" { - v.Status = StatusPending - } - return v -} diff --git a/vendor/golang.org/x/crypto/bcrypt/base64.go b/vendor/golang.org/x/crypto/bcrypt/base64.go deleted file mode 100644 index fc31160..0000000 --- a/vendor/golang.org/x/crypto/bcrypt/base64.go +++ /dev/null @@ -1,35 +0,0 @@ -// 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 deleted file mode 100644 index f8b807f..0000000 --- a/vendor/golang.org/x/crypto/bcrypt/bcrypt.go +++ /dev/null @@ -1,294 +0,0 @@ -// 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" - "golang.org/x/crypto/blowfish" - "io" - "strconv" -) - -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. - ckey := append(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 += 1 - copy(arr[n:], []byte(fmt.Sprintf("%02d", p.cost))) - n += 2 - arr[n] = '$' - n += 1 - 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/bcrypt/bcrypt_test.go b/vendor/golang.org/x/crypto/bcrypt/bcrypt_test.go deleted file mode 100644 index f08a6f5..0000000 --- a/vendor/golang.org/x/crypto/bcrypt/bcrypt_test.go +++ /dev/null @@ -1,226 +0,0 @@ -// 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 ( - "bytes" - "fmt" - "testing" -) - -func TestBcryptingIsEasy(t *testing.T) { - pass := []byte("mypassword") - hp, err := GenerateFromPassword(pass, 0) - if err != nil { - t.Fatalf("GenerateFromPassword error: %s", err) - } - - if CompareHashAndPassword(hp, pass) != nil { - t.Errorf("%v should hash %s correctly", hp, pass) - } - - notPass := "notthepass" - err = CompareHashAndPassword(hp, []byte(notPass)) - if err != ErrMismatchedHashAndPassword { - t.Errorf("%v and %s should be mismatched", hp, notPass) - } -} - -func TestBcryptingIsCorrect(t *testing.T) { - pass := []byte("allmine") - salt := []byte("XajjQvNhvvRt5GSeFk1xFe") - expectedHash := []byte("$2a$10$XajjQvNhvvRt5GSeFk1xFeyqRrsxkhBkUiQeg0dt.wU1qD4aFDcga") - - hash, err := bcrypt(pass, 10, salt) - if err != nil { - t.Fatalf("bcrypt blew up: %v", err) - } - if !bytes.HasSuffix(expectedHash, hash) { - t.Errorf("%v should be the suffix of %v", hash, expectedHash) - } - - h, err := newFromHash(expectedHash) - if err != nil { - t.Errorf("Unable to parse %s: %v", string(expectedHash), err) - } - - // This is not the safe way to compare these hashes. We do this only for - // testing clarity. Use bcrypt.CompareHashAndPassword() - if err == nil && !bytes.Equal(expectedHash, h.Hash()) { - t.Errorf("Parsed hash %v should equal %v", h.Hash(), expectedHash) - } -} - -func TestVeryShortPasswords(t *testing.T) { - key := []byte("k") - salt := []byte("XajjQvNhvvRt5GSeFk1xFe") - _, err := bcrypt(key, 10, salt) - if err != nil { - t.Errorf("One byte key resulted in error: %s", err) - } -} - -func TestTooLongPasswordsWork(t *testing.T) { - salt := []byte("XajjQvNhvvRt5GSeFk1xFe") - // One byte over the usual 56 byte limit that blowfish has - tooLongPass := []byte("012345678901234567890123456789012345678901234567890123456") - tooLongExpected := []byte("$2a$10$XajjQvNhvvRt5GSeFk1xFe5l47dONXg781AmZtd869sO8zfsHuw7C") - hash, err := bcrypt(tooLongPass, 10, salt) - if err != nil { - t.Fatalf("bcrypt blew up on long password: %v", err) - } - if !bytes.HasSuffix(tooLongExpected, hash) { - t.Errorf("%v should be the suffix of %v", hash, tooLongExpected) - } -} - -type InvalidHashTest struct { - err error - hash []byte -} - -var invalidTests = []InvalidHashTest{ - {ErrHashTooShort, []byte("$2a$10$fooo")}, - {ErrHashTooShort, []byte("$2a")}, - {HashVersionTooNewError('3'), []byte("$3a$10$sssssssssssssssssssssshhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh")}, - {InvalidHashPrefixError('%'), []byte("%2a$10$sssssssssssssssssssssshhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh")}, - {InvalidCostError(32), []byte("$2a$32$sssssssssssssssssssssshhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh")}, -} - -func TestInvalidHashErrors(t *testing.T) { - check := func(name string, expected, err error) { - if err == nil { - t.Errorf("%s: Should have returned an error", name) - } - if err != nil && err != expected { - t.Errorf("%s gave err %v but should have given %v", name, err, expected) - } - } - for _, iht := range invalidTests { - _, err := newFromHash(iht.hash) - check("newFromHash", iht.err, err) - err = CompareHashAndPassword(iht.hash, []byte("anything")) - check("CompareHashAndPassword", iht.err, err) - } -} - -func TestUnpaddedBase64Encoding(t *testing.T) { - original := []byte{101, 201, 101, 75, 19, 227, 199, 20, 239, 236, 133, 32, 30, 109, 243, 30} - encodedOriginal := []byte("XajjQvNhvvRt5GSeFk1xFe") - - encoded := base64Encode(original) - - if !bytes.Equal(encodedOriginal, encoded) { - t.Errorf("Encoded %v should have equaled %v", encoded, encodedOriginal) - } - - decoded, err := base64Decode(encodedOriginal) - if err != nil { - t.Fatalf("base64Decode blew up: %s", err) - } - - if !bytes.Equal(decoded, original) { - t.Errorf("Decoded %v should have equaled %v", decoded, original) - } -} - -func TestCost(t *testing.T) { - suffix := "XajjQvNhvvRt5GSeFk1xFe5l47dONXg781AmZtd869sO8zfsHuw7C" - for _, vers := range []string{"2a", "2"} { - for _, cost := range []int{4, 10} { - s := fmt.Sprintf("$%s$%02d$%s", vers, cost, suffix) - h := []byte(s) - actual, err := Cost(h) - if err != nil { - t.Errorf("Cost, error: %s", err) - continue - } - if actual != cost { - t.Errorf("Cost, expected: %d, actual: %d", cost, actual) - } - } - } - _, err := Cost([]byte("$a$a$" + suffix)) - if err == nil { - t.Errorf("Cost, malformed but no error returned") - } -} - -func TestCostValidationInHash(t *testing.T) { - if testing.Short() { - return - } - - pass := []byte("mypassword") - - for c := 0; c < MinCost; c++ { - p, _ := newFromPassword(pass, c) - if p.cost != DefaultCost { - t.Errorf("newFromPassword should default costs below %d to %d, but was %d", MinCost, DefaultCost, p.cost) - } - } - - p, _ := newFromPassword(pass, 14) - if p.cost != 14 { - t.Errorf("newFromPassword should default cost to 14, but was %d", p.cost) - } - - hp, _ := newFromHash(p.Hash()) - if p.cost != hp.cost { - t.Errorf("newFromHash should maintain the cost at %d, but was %d", p.cost, hp.cost) - } - - _, err := newFromPassword(pass, 32) - if err == nil { - t.Fatalf("newFromPassword: should return a cost error") - } - if err != InvalidCostError(32) { - t.Errorf("newFromPassword: should return cost error, got %#v", err) - } -} - -func TestCostReturnsWithLeadingZeroes(t *testing.T) { - hp, _ := newFromPassword([]byte("abcdefgh"), 7) - cost := hp.Hash()[4:7] - expected := []byte("07$") - - if !bytes.Equal(expected, cost) { - t.Errorf("single digit costs in hash should have leading zeros: was %v instead of %v", cost, expected) - } -} - -func TestMinorNotRequired(t *testing.T) { - noMinorHash := []byte("$2$10$XajjQvNhvvRt5GSeFk1xFeyqRrsxkhBkUiQeg0dt.wU1qD4aFDcga") - h, err := newFromHash(noMinorHash) - if err != nil { - t.Fatalf("No minor hash blew up: %s", err) - } - if h.minor != 0 { - t.Errorf("Should leave minor version at 0, but was %d", h.minor) - } - - if !bytes.Equal(noMinorHash, h.Hash()) { - t.Errorf("Should generate hash %v, but created %v", noMinorHash, h.Hash()) - } -} - -func BenchmarkEqual(b *testing.B) { - b.StopTimer() - passwd := []byte("somepasswordyoulike") - hash, _ := GenerateFromPassword(passwd, 10) - b.StartTimer() - for i := 0; i < b.N; i++ { - CompareHashAndPassword(hash, passwd) - } -} - -func BenchmarkGeneration(b *testing.B) { - b.StopTimer() - passwd := []byte("mylongpassword1234") - b.StartTimer() - for i := 0; i < b.N; i++ { - GenerateFromPassword(passwd, 10) - } -} diff --git a/vendor/golang.org/x/crypto/blowfish/block.go b/vendor/golang.org/x/crypto/blowfish/block.go deleted file mode 100644 index 9d80f19..0000000 --- a/vendor/golang.org/x/crypto/blowfish/block.go +++ /dev/null @@ -1,159 +0,0 @@ -// 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 blowfish - -// getNextWord returns the next big-endian uint32 value from the byte slice -// at the given position in a circular manner, updating the position. -func getNextWord(b []byte, pos *int) uint32 { - var w uint32 - j := *pos - for i := 0; i < 4; i++ { - w = w<<8 | uint32(b[j]) - j++ - if j >= len(b) { - j = 0 - } - } - *pos = j - return w -} - -// ExpandKey performs a key expansion on the given *Cipher. Specifically, it -// performs the Blowfish algorithm's key schedule which sets up the *Cipher's -// pi and substitution tables for calls to Encrypt. This is used, primarily, -// by the bcrypt package to reuse the Blowfish key schedule during its -// set up. It's unlikely that you need to use this directly. -func ExpandKey(key []byte, c *Cipher) { - j := 0 - for i := 0; i < 18; i++ { - // Using inlined getNextWord for performance. - var d uint32 - for k := 0; k < 4; k++ { - d = d<<8 | uint32(key[j]) - j++ - if j >= len(key) { - j = 0 - } - } - c.p[i] ^= d - } - - var l, r uint32 - for i := 0; i < 18; i += 2 { - l, r = encryptBlock(l, r, c) - c.p[i], c.p[i+1] = l, r - } - - for i := 0; i < 256; i += 2 { - l, r = encryptBlock(l, r, c) - c.s0[i], c.s0[i+1] = l, r - } - for i := 0; i < 256; i += 2 { - l, r = encryptBlock(l, r, c) - c.s1[i], c.s1[i+1] = l, r - } - for i := 0; i < 256; i += 2 { - l, r = encryptBlock(l, r, c) - c.s2[i], c.s2[i+1] = l, r - } - for i := 0; i < 256; i += 2 { - l, r = encryptBlock(l, r, c) - c.s3[i], c.s3[i+1] = l, r - } -} - -// This is similar to ExpandKey, but folds the salt during the key -// schedule. While ExpandKey is essentially expandKeyWithSalt with an all-zero -// salt passed in, reusing ExpandKey turns out to be a place of inefficiency -// and specializing it here is useful. -func expandKeyWithSalt(key []byte, salt []byte, c *Cipher) { - j := 0 - for i := 0; i < 18; i++ { - c.p[i] ^= getNextWord(key, &j) - } - - j = 0 - var l, r uint32 - for i := 0; i < 18; i += 2 { - l ^= getNextWord(salt, &j) - r ^= getNextWord(salt, &j) - l, r = encryptBlock(l, r, c) - c.p[i], c.p[i+1] = l, r - } - - for i := 0; i < 256; i += 2 { - l ^= getNextWord(salt, &j) - r ^= getNextWord(salt, &j) - l, r = encryptBlock(l, r, c) - c.s0[i], c.s0[i+1] = l, r - } - - for i := 0; i < 256; i += 2 { - l ^= getNextWord(salt, &j) - r ^= getNextWord(salt, &j) - l, r = encryptBlock(l, r, c) - c.s1[i], c.s1[i+1] = l, r - } - - for i := 0; i < 256; i += 2 { - l ^= getNextWord(salt, &j) - r ^= getNextWord(salt, &j) - l, r = encryptBlock(l, r, c) - c.s2[i], c.s2[i+1] = l, r - } - - for i := 0; i < 256; i += 2 { - l ^= getNextWord(salt, &j) - r ^= getNextWord(salt, &j) - l, r = encryptBlock(l, r, c) - c.s3[i], c.s3[i+1] = l, r - } -} - -func encryptBlock(l, r uint32, c *Cipher) (uint32, uint32) { - xl, xr := l, r - xl ^= c.p[0] - xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[1] - xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[2] - xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[3] - xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[4] - xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[5] - xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[6] - xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[7] - xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[8] - xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[9] - xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[10] - xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[11] - xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[12] - xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[13] - xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[14] - xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[15] - xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[16] - xr ^= c.p[17] - return xr, xl -} - -func decryptBlock(l, r uint32, c *Cipher) (uint32, uint32) { - xl, xr := l, r - xl ^= c.p[17] - xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[16] - xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[15] - xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[14] - xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[13] - xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[12] - xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[11] - xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[10] - xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[9] - xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[8] - xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[7] - xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[6] - xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[5] - xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[4] - xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[3] - xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[2] - xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[1] - xr ^= c.p[0] - return xr, xl -} diff --git a/vendor/golang.org/x/crypto/blowfish/blowfish_test.go b/vendor/golang.org/x/crypto/blowfish/blowfish_test.go deleted file mode 100644 index 7afa1fd..0000000 --- a/vendor/golang.org/x/crypto/blowfish/blowfish_test.go +++ /dev/null @@ -1,274 +0,0 @@ -// 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 blowfish - -import "testing" - -type CryptTest struct { - key []byte - in []byte - out []byte -} - -// Test vector values are from http://www.schneier.com/code/vectors.txt. -var encryptTests = []CryptTest{ - { - []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - []byte{0x4E, 0xF9, 0x97, 0x45, 0x61, 0x98, 0xDD, 0x78}}, - { - []byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, - []byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, - []byte{0x51, 0x86, 0x6F, 0xD5, 0xB8, 0x5E, 0xCB, 0x8A}}, - { - []byte{0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - []byte{0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, - []byte{0x7D, 0x85, 0x6F, 0x9A, 0x61, 0x30, 0x63, 0xF2}}, - { - []byte{0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}, - []byte{0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}, - []byte{0x24, 0x66, 0xDD, 0x87, 0x8B, 0x96, 0x3C, 0x9D}}, - - { - []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}, - []byte{0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}, - []byte{0x61, 0xF9, 0xC3, 0x80, 0x22, 0x81, 0xB0, 0x96}}, - { - []byte{0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}, - []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}, - []byte{0x7D, 0x0C, 0xC6, 0x30, 0xAF, 0xDA, 0x1E, 0xC7}}, - { - []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - []byte{0x4E, 0xF9, 0x97, 0x45, 0x61, 0x98, 0xDD, 0x78}}, - { - []byte{0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}, - []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}, - []byte{0x0A, 0xCE, 0xAB, 0x0F, 0xC6, 0xA0, 0xA2, 0x8D}}, - { - []byte{0x7C, 0xA1, 0x10, 0x45, 0x4A, 0x1A, 0x6E, 0x57}, - []byte{0x01, 0xA1, 0xD6, 0xD0, 0x39, 0x77, 0x67, 0x42}, - []byte{0x59, 0xC6, 0x82, 0x45, 0xEB, 0x05, 0x28, 0x2B}}, - { - []byte{0x01, 0x31, 0xD9, 0x61, 0x9D, 0xC1, 0x37, 0x6E}, - []byte{0x5C, 0xD5, 0x4C, 0xA8, 0x3D, 0xEF, 0x57, 0xDA}, - []byte{0xB1, 0xB8, 0xCC, 0x0B, 0x25, 0x0F, 0x09, 0xA0}}, - { - []byte{0x07, 0xA1, 0x13, 0x3E, 0x4A, 0x0B, 0x26, 0x86}, - []byte{0x02, 0x48, 0xD4, 0x38, 0x06, 0xF6, 0x71, 0x72}, - []byte{0x17, 0x30, 0xE5, 0x77, 0x8B, 0xEA, 0x1D, 0xA4}}, - { - []byte{0x38, 0x49, 0x67, 0x4C, 0x26, 0x02, 0x31, 0x9E}, - []byte{0x51, 0x45, 0x4B, 0x58, 0x2D, 0xDF, 0x44, 0x0A}, - []byte{0xA2, 0x5E, 0x78, 0x56, 0xCF, 0x26, 0x51, 0xEB}}, - { - []byte{0x04, 0xB9, 0x15, 0xBA, 0x43, 0xFE, 0xB5, 0xB6}, - []byte{0x42, 0xFD, 0x44, 0x30, 0x59, 0x57, 0x7F, 0xA2}, - []byte{0x35, 0x38, 0x82, 0xB1, 0x09, 0xCE, 0x8F, 0x1A}}, - { - []byte{0x01, 0x13, 0xB9, 0x70, 0xFD, 0x34, 0xF2, 0xCE}, - []byte{0x05, 0x9B, 0x5E, 0x08, 0x51, 0xCF, 0x14, 0x3A}, - []byte{0x48, 0xF4, 0xD0, 0x88, 0x4C, 0x37, 0x99, 0x18}}, - { - []byte{0x01, 0x70, 0xF1, 0x75, 0x46, 0x8F, 0xB5, 0xE6}, - []byte{0x07, 0x56, 0xD8, 0xE0, 0x77, 0x47, 0x61, 0xD2}, - []byte{0x43, 0x21, 0x93, 0xB7, 0x89, 0x51, 0xFC, 0x98}}, - { - []byte{0x43, 0x29, 0x7F, 0xAD, 0x38, 0xE3, 0x73, 0xFE}, - []byte{0x76, 0x25, 0x14, 0xB8, 0x29, 0xBF, 0x48, 0x6A}, - []byte{0x13, 0xF0, 0x41, 0x54, 0xD6, 0x9D, 0x1A, 0xE5}}, - { - []byte{0x07, 0xA7, 0x13, 0x70, 0x45, 0xDA, 0x2A, 0x16}, - []byte{0x3B, 0xDD, 0x11, 0x90, 0x49, 0x37, 0x28, 0x02}, - []byte{0x2E, 0xED, 0xDA, 0x93, 0xFF, 0xD3, 0x9C, 0x79}}, - { - []byte{0x04, 0x68, 0x91, 0x04, 0xC2, 0xFD, 0x3B, 0x2F}, - []byte{0x26, 0x95, 0x5F, 0x68, 0x35, 0xAF, 0x60, 0x9A}, - []byte{0xD8, 0x87, 0xE0, 0x39, 0x3C, 0x2D, 0xA6, 0xE3}}, - { - []byte{0x37, 0xD0, 0x6B, 0xB5, 0x16, 0xCB, 0x75, 0x46}, - []byte{0x16, 0x4D, 0x5E, 0x40, 0x4F, 0x27, 0x52, 0x32}, - []byte{0x5F, 0x99, 0xD0, 0x4F, 0x5B, 0x16, 0x39, 0x69}}, - { - []byte{0x1F, 0x08, 0x26, 0x0D, 0x1A, 0xC2, 0x46, 0x5E}, - []byte{0x6B, 0x05, 0x6E, 0x18, 0x75, 0x9F, 0x5C, 0xCA}, - []byte{0x4A, 0x05, 0x7A, 0x3B, 0x24, 0xD3, 0x97, 0x7B}}, - { - []byte{0x58, 0x40, 0x23, 0x64, 0x1A, 0xBA, 0x61, 0x76}, - []byte{0x00, 0x4B, 0xD6, 0xEF, 0x09, 0x17, 0x60, 0x62}, - []byte{0x45, 0x20, 0x31, 0xC1, 0xE4, 0xFA, 0xDA, 0x8E}}, - { - []byte{0x02, 0x58, 0x16, 0x16, 0x46, 0x29, 0xB0, 0x07}, - []byte{0x48, 0x0D, 0x39, 0x00, 0x6E, 0xE7, 0x62, 0xF2}, - []byte{0x75, 0x55, 0xAE, 0x39, 0xF5, 0x9B, 0x87, 0xBD}}, - { - []byte{0x49, 0x79, 0x3E, 0xBC, 0x79, 0xB3, 0x25, 0x8F}, - []byte{0x43, 0x75, 0x40, 0xC8, 0x69, 0x8F, 0x3C, 0xFA}, - []byte{0x53, 0xC5, 0x5F, 0x9C, 0xB4, 0x9F, 0xC0, 0x19}}, - { - []byte{0x4F, 0xB0, 0x5E, 0x15, 0x15, 0xAB, 0x73, 0xA7}, - []byte{0x07, 0x2D, 0x43, 0xA0, 0x77, 0x07, 0x52, 0x92}, - []byte{0x7A, 0x8E, 0x7B, 0xFA, 0x93, 0x7E, 0x89, 0xA3}}, - { - []byte{0x49, 0xE9, 0x5D, 0x6D, 0x4C, 0xA2, 0x29, 0xBF}, - []byte{0x02, 0xFE, 0x55, 0x77, 0x81, 0x17, 0xF1, 0x2A}, - []byte{0xCF, 0x9C, 0x5D, 0x7A, 0x49, 0x86, 0xAD, 0xB5}}, - { - []byte{0x01, 0x83, 0x10, 0xDC, 0x40, 0x9B, 0x26, 0xD6}, - []byte{0x1D, 0x9D, 0x5C, 0x50, 0x18, 0xF7, 0x28, 0xC2}, - []byte{0xD1, 0xAB, 0xB2, 0x90, 0x65, 0x8B, 0xC7, 0x78}}, - { - []byte{0x1C, 0x58, 0x7F, 0x1C, 0x13, 0x92, 0x4F, 0xEF}, - []byte{0x30, 0x55, 0x32, 0x28, 0x6D, 0x6F, 0x29, 0x5A}, - []byte{0x55, 0xCB, 0x37, 0x74, 0xD1, 0x3E, 0xF2, 0x01}}, - { - []byte{0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}, - []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}, - []byte{0xFA, 0x34, 0xEC, 0x48, 0x47, 0xB2, 0x68, 0xB2}}, - { - []byte{0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E}, - []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}, - []byte{0xA7, 0x90, 0x79, 0x51, 0x08, 0xEA, 0x3C, 0xAE}}, - { - []byte{0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE}, - []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}, - []byte{0xC3, 0x9E, 0x07, 0x2D, 0x9F, 0xAC, 0x63, 0x1D}}, - { - []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - []byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, - []byte{0x01, 0x49, 0x33, 0xE0, 0xCD, 0xAF, 0xF6, 0xE4}}, - { - []byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, - []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - []byte{0xF2, 0x1E, 0x9A, 0x77, 0xB7, 0x1C, 0x49, 0xBC}}, - { - []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}, - []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - []byte{0x24, 0x59, 0x46, 0x88, 0x57, 0x54, 0x36, 0x9A}}, - { - []byte{0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}, - []byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, - []byte{0x6B, 0x5C, 0x5A, 0x9C, 0x5D, 0x9E, 0x0A, 0x5A}}, -} - -func TestCipherEncrypt(t *testing.T) { - for i, tt := range encryptTests { - c, err := NewCipher(tt.key) - if err != nil { - t.Errorf("NewCipher(%d bytes) = %s", len(tt.key), err) - continue - } - ct := make([]byte, len(tt.out)) - c.Encrypt(ct, tt.in) - for j, v := range ct { - if v != tt.out[j] { - t.Errorf("Cipher.Encrypt, test vector #%d: cipher-text[%d] = %#x, expected %#x", i, j, v, tt.out[j]) - break - } - } - } -} - -func TestCipherDecrypt(t *testing.T) { - for i, tt := range encryptTests { - c, err := NewCipher(tt.key) - if err != nil { - t.Errorf("NewCipher(%d bytes) = %s", len(tt.key), err) - continue - } - pt := make([]byte, len(tt.in)) - c.Decrypt(pt, tt.out) - for j, v := range pt { - if v != tt.in[j] { - t.Errorf("Cipher.Decrypt, test vector #%d: plain-text[%d] = %#x, expected %#x", i, j, v, tt.in[j]) - break - } - } - } -} - -func TestSaltedCipherKeyLength(t *testing.T) { - if _, err := NewSaltedCipher(nil, []byte{'a'}); err != KeySizeError(0) { - t.Errorf("NewSaltedCipher with short key, gave error %#v, expected %#v", err, KeySizeError(0)) - } - - // A 57-byte key. One over the typical blowfish restriction. - key := []byte("012345678901234567890123456789012345678901234567890123456") - if _, err := NewSaltedCipher(key, []byte{'a'}); err != nil { - t.Errorf("NewSaltedCipher with long key, gave error %#v", err) - } -} - -// Test vectors generated with Blowfish from OpenSSH. -var saltedVectors = [][8]byte{ - {0x0c, 0x82, 0x3b, 0x7b, 0x8d, 0x01, 0x4b, 0x7e}, - {0xd1, 0xe1, 0x93, 0xf0, 0x70, 0xa6, 0xdb, 0x12}, - {0xfc, 0x5e, 0xba, 0xde, 0xcb, 0xf8, 0x59, 0xad}, - {0x8a, 0x0c, 0x76, 0xe7, 0xdd, 0x2c, 0xd3, 0xa8}, - {0x2c, 0xcb, 0x7b, 0xee, 0xac, 0x7b, 0x7f, 0xf8}, - {0xbb, 0xf6, 0x30, 0x6f, 0xe1, 0x5d, 0x62, 0xbf}, - {0x97, 0x1e, 0xc1, 0x3d, 0x3d, 0xe0, 0x11, 0xe9}, - {0x06, 0xd7, 0x4d, 0xb1, 0x80, 0xa3, 0xb1, 0x38}, - {0x67, 0xa1, 0xa9, 0x75, 0x0e, 0x5b, 0xc6, 0xb4}, - {0x51, 0x0f, 0x33, 0x0e, 0x4f, 0x67, 0xd2, 0x0c}, - {0xf1, 0x73, 0x7e, 0xd8, 0x44, 0xea, 0xdb, 0xe5}, - {0x14, 0x0e, 0x16, 0xce, 0x7f, 0x4a, 0x9c, 0x7b}, - {0x4b, 0xfe, 0x43, 0xfd, 0xbf, 0x36, 0x04, 0x47}, - {0xb1, 0xeb, 0x3e, 0x15, 0x36, 0xa7, 0xbb, 0xe2}, - {0x6d, 0x0b, 0x41, 0xdd, 0x00, 0x98, 0x0b, 0x19}, - {0xd3, 0xce, 0x45, 0xce, 0x1d, 0x56, 0xb7, 0xfc}, - {0xd9, 0xf0, 0xfd, 0xda, 0xc0, 0x23, 0xb7, 0x93}, - {0x4c, 0x6f, 0xa1, 0xe4, 0x0c, 0xa8, 0xca, 0x57}, - {0xe6, 0x2f, 0x28, 0xa7, 0x0c, 0x94, 0x0d, 0x08}, - {0x8f, 0xe3, 0xf0, 0xb6, 0x29, 0xe3, 0x44, 0x03}, - {0xff, 0x98, 0xdd, 0x04, 0x45, 0xb4, 0x6d, 0x1f}, - {0x9e, 0x45, 0x4d, 0x18, 0x40, 0x53, 0xdb, 0xef}, - {0xb7, 0x3b, 0xef, 0x29, 0xbe, 0xa8, 0x13, 0x71}, - {0x02, 0x54, 0x55, 0x41, 0x8e, 0x04, 0xfc, 0xad}, - {0x6a, 0x0a, 0xee, 0x7c, 0x10, 0xd9, 0x19, 0xfe}, - {0x0a, 0x22, 0xd9, 0x41, 0xcc, 0x23, 0x87, 0x13}, - {0x6e, 0xff, 0x1f, 0xff, 0x36, 0x17, 0x9c, 0xbe}, - {0x79, 0xad, 0xb7, 0x40, 0xf4, 0x9f, 0x51, 0xa6}, - {0x97, 0x81, 0x99, 0xa4, 0xde, 0x9e, 0x9f, 0xb6}, - {0x12, 0x19, 0x7a, 0x28, 0xd0, 0xdc, 0xcc, 0x92}, - {0x81, 0xda, 0x60, 0x1e, 0x0e, 0xdd, 0x65, 0x56}, - {0x7d, 0x76, 0x20, 0xb2, 0x73, 0xc9, 0x9e, 0xee}, -} - -func TestSaltedCipher(t *testing.T) { - var key, salt [32]byte - for i := range key { - key[i] = byte(i) - salt[i] = byte(i + 32) - } - for i, v := range saltedVectors { - c, err := NewSaltedCipher(key[:], salt[:i]) - if err != nil { - t.Fatal(err) - } - var buf [8]byte - c.Encrypt(buf[:], buf[:]) - if v != buf { - t.Errorf("%d: expected %x, got %x", i, v, buf) - } - } -} - -func BenchmarkExpandKeyWithSalt(b *testing.B) { - key := make([]byte, 32) - salt := make([]byte, 16) - c, _ := NewCipher(key) - for i := 0; i < b.N; i++ { - expandKeyWithSalt(key, salt, c) - } -} - -func BenchmarkExpandKey(b *testing.B) { - key := make([]byte, 32) - c, _ := NewCipher(key) - for i := 0; i < b.N; i++ { - ExpandKey(key, c) - } -} diff --git a/vendor/golang.org/x/crypto/blowfish/cipher.go b/vendor/golang.org/x/crypto/blowfish/cipher.go deleted file mode 100644 index a73954f..0000000 --- a/vendor/golang.org/x/crypto/blowfish/cipher.go +++ /dev/null @@ -1,91 +0,0 @@ -// 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 blowfish implements Bruce Schneier's Blowfish encryption algorithm. -package blowfish // import "golang.org/x/crypto/blowfish" - -// The code is a port of Bruce Schneier's C implementation. -// See http://www.schneier.com/blowfish.html. - -import "strconv" - -// The Blowfish block size in bytes. -const BlockSize = 8 - -// A Cipher is an instance of Blowfish encryption using a particular key. -type Cipher struct { - p [18]uint32 - s0, s1, s2, s3 [256]uint32 -} - -type KeySizeError int - -func (k KeySizeError) Error() string { - return "crypto/blowfish: invalid key size " + strconv.Itoa(int(k)) -} - -// NewCipher creates and returns a Cipher. -// The key argument should be the Blowfish key, from 1 to 56 bytes. -func NewCipher(key []byte) (*Cipher, error) { - var result Cipher - if k := len(key); k < 1 || k > 56 { - return nil, KeySizeError(k) - } - initCipher(&result) - ExpandKey(key, &result) - return &result, nil -} - -// NewSaltedCipher creates a returns a Cipher that folds a salt into its key -// schedule. For most purposes, NewCipher, instead of NewSaltedCipher, is -// sufficient and desirable. For bcrypt compatibility, the key can be over 56 -// bytes. -func NewSaltedCipher(key, salt []byte) (*Cipher, error) { - if len(salt) == 0 { - return NewCipher(key) - } - var result Cipher - if k := len(key); k < 1 { - return nil, KeySizeError(k) - } - initCipher(&result) - expandKeyWithSalt(key, salt, &result) - return &result, nil -} - -// BlockSize returns the Blowfish 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 k -// 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) { - 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 = encryptBlock(l, r, c) - dst[0], dst[1], dst[2], dst[3] = byte(l>>24), byte(l>>16), byte(l>>8), byte(l) - dst[4], dst[5], dst[6], dst[7] = byte(r>>24), byte(r>>16), byte(r>>8), byte(r) -} - -// Decrypt decrypts the 8-byte buffer src using the key k -// and stores the result in dst. -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 = decryptBlock(l, r, c) - dst[0], dst[1], dst[2], dst[3] = byte(l>>24), byte(l>>16), byte(l>>8), byte(l) - dst[4], dst[5], dst[6], dst[7] = byte(r>>24), byte(r>>16), byte(r>>8), byte(r) -} - -func initCipher(c *Cipher) { - copy(c.p[0:], p[0:]) - copy(c.s0[0:], s0[0:]) - copy(c.s1[0:], s1[0:]) - copy(c.s2[0:], s2[0:]) - copy(c.s3[0:], s3[0:]) -} diff --git a/vendor/golang.org/x/crypto/blowfish/const.go b/vendor/golang.org/x/crypto/blowfish/const.go deleted file mode 100644 index 8c5ee4c..0000000 --- a/vendor/golang.org/x/crypto/blowfish/const.go +++ /dev/null @@ -1,199 +0,0 @@ -// 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. - -// The startup permutation array and substitution boxes. -// They are the hexadecimal digits of PI; see: -// http://www.schneier.com/code/constants.txt. - -package blowfish - -var s0 = [256]uint32{ - 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, 0x6a267e96, - 0xba7c9045, 0xf12c7f99, 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, - 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, 0x0d95748f, 0x728eb658, - 0x718bcd58, 0x82154aee, 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013, - 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, 0x8e79dcb0, 0x603a180e, - 0x6c9e0e8b, 0xb01e8a3e, 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, - 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, 0x55ca396a, 0x2aab10b6, - 0xb4cc5c34, 0x1141e8ce, 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a, - 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, 0xafd6ba33, 0x6c24cf5c, - 0x7a325381, 0x28958677, 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, - 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, 0xef845d5d, 0xe98575b1, - 0xdc262302, 0xeb651b88, 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239, - 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, 0x21c66842, 0xf6e96c9a, - 0x670c9c61, 0xabd388f0, 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, - 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, 0xa1f1651d, 0x39af0176, - 0x66ca593e, 0x82430e88, 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe, - 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, 0x4ed3aa62, 0x363f7706, - 0x1bfedf72, 0x429b023d, 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, - 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, 0xe3fe501a, 0xb6794c3b, - 0x976ce0bd, 0x04c006ba, 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463, - 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, 0x6dfc511f, 0x9b30952c, - 0xcc814544, 0xaf5ebd09, 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, - 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, 0x5579c0bd, 0x1a60320a, - 0xd6a100c6, 0x402c7279, 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8, - 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, 0x323db5fa, 0xfd238760, - 0x53317b48, 0x3e00df82, 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, - 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, 0x695b27b0, 0xbbca58c8, - 0xe1ffa35d, 0xb8f011a0, 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b, - 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, 0xe1ddf2da, 0xa4cb7e33, - 0x62fb1341, 0xcee4c6e8, 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, - 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, 0xd08ed1d0, 0xafc725e0, - 0x8e3c5b2f, 0x8e7594b7, 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c, - 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, 0x2f2f2218, 0xbe0e1777, - 0xea752dfe, 0x8b021fa1, 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, - 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, 0x165fa266, 0x80957705, - 0x93cc7314, 0x211a1477, 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf, - 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, 0x00250e2d, 0x2071b35e, - 0x226800bb, 0x57b8e0af, 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, - 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, 0x83260376, 0x6295cfa9, - 0x11c81968, 0x4e734a41, 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915, - 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, 0x08ba6fb5, 0x571be91f, - 0xf296ec6b, 0x2a0dd915, 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, - 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a, -} - -var s1 = [256]uint32{ - 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, 0xad6ea6b0, 0x49a7df7d, - 0x9cee60b8, 0x8fedb266, 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, - 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, 0x3f54989a, 0x5b429d65, - 0x6b8fe4d6, 0x99f73fd6, 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1, - 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, 0x09686b3f, 0x3ebaefc9, - 0x3c971814, 0x6b6a70a1, 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, - 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, 0xb03ada37, 0xf0500c0d, - 0xf01c1f04, 0x0200b3ff, 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd, - 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, 0x3ae5e581, 0x37c2dadc, - 0xc8b57634, 0x9af3dda7, 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, - 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, 0x4e548b38, 0x4f6db908, - 0x6f420d03, 0xf60a04bf, 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af, - 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, 0x5512721f, 0x2e6b7124, - 0x501adde6, 0x9f84cd87, 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, - 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, 0xef1c1847, 0x3215d908, - 0xdd433b37, 0x24c2ba16, 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd, - 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, 0x043556f1, 0xd7a3c76b, - 0x3c11183b, 0x5924a509, 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, - 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, 0x771fe71c, 0x4e3d06fa, - 0x2965dcb9, 0x99e71d0f, 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a, - 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, 0xf2f74ea7, 0x361d2b3d, - 0x1939260f, 0x19c27960, 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, - 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28, 0xc332ddef, 0xbe6c5aa5, - 0x65582185, 0x68ab9802, 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84, - 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, 0x13cca830, 0xeb61bd96, - 0x0334fe1e, 0xaa0363cf, 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, - 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, 0x648b1eaf, 0x19bdf0ca, - 0xa02369b9, 0x655abb50, 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7, - 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, 0xf837889a, 0x97e32d77, - 0x11ed935f, 0x16681281, 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, - 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, 0xcdb30aeb, 0x532e3054, - 0x8fd948e4, 0x6dbc3128, 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73, - 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, 0x45eee2b6, 0xa3aaabea, - 0xdb6c4f15, 0xfacb4fd0, 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, - 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, 0xcf62a1f2, 0x5b8d2646, - 0xfc8883a0, 0xc1c7b6a3, 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285, - 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, 0x58428d2a, 0x0c55f5ea, - 0x1dadf43e, 0x233f7061, 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, - 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, 0xa6078084, 0x19f8509e, - 0xe8efd855, 0x61d99735, 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc, - 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, 0xdb73dbd3, 0x105588cd, - 0x675fda79, 0xe3674340, 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, - 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7, -} - -var s2 = [256]uint32{ - 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, 0x411520f7, 0x7602d4f7, - 0xbcf46b2e, 0xd4a20068, 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, - 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, 0x4d95fc1d, 0x96b591af, - 0x70f4ddd3, 0x66a02f45, 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504, - 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, 0x28507825, 0x530429f4, - 0x0a2c86da, 0xe9b66dfb, 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, - 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6, 0xaace1e7c, 0xd3375fec, - 0xce78a399, 0x406b2a42, 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b, - 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, 0x3a6efa74, 0xdd5b4332, - 0x6841e7f7, 0xca7820fb, 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, - 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b, 0x55a867bc, 0xa1159a58, - 0xcca92963, 0x99e1db33, 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c, - 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, 0x95c11548, 0xe4c66d22, - 0x48c1133f, 0xc70f86dc, 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, - 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, 0x257b7834, 0x602a9c60, - 0xdff8e8a3, 0x1f636c1b, 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115, - 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, 0x85b2a20e, 0xe6ba0d99, - 0xde720c8c, 0x2da2f728, 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, - 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, 0x0a476341, 0x992eff74, - 0x3a6f6eab, 0xf4f8fd37, 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d, - 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, 0xf1290dc7, 0xcc00ffa3, - 0xb5390f92, 0x690fed0b, 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, - 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb, 0x37392eb3, 0xcc115979, - 0x8026e297, 0xf42e312d, 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c, - 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, 0x1a6b1018, 0x11caedfa, - 0x3d25bdd8, 0xe2e1c3c9, 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, - 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe, 0x9dbc8057, 0xf0f7c086, - 0x60787bf8, 0x6003604d, 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc, - 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, 0x77a057be, 0xbde8ae24, - 0x55464299, 0xbf582e61, 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, - 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9, 0x7aeb2661, 0x8b1ddf84, - 0x846a0e79, 0x915f95e2, 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c, - 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, 0xb77f19b6, 0xe0a9dc09, - 0x662d09a1, 0xc4324633, 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, - 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, 0xdcb7da83, 0x573906fe, - 0xa1e2ce9b, 0x4fcd7f52, 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027, - 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, 0xf0177a28, 0xc0f586e0, - 0x006058aa, 0x30dc7d62, 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, - 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, 0x6f05e409, 0x4b7c0188, - 0x39720a3d, 0x7c927c24, 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc, - 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, 0x1e50ef5e, 0xb161e6f8, - 0xa28514d9, 0x6c51133c, 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, - 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0, -} - -var s3 = [256]uint32{ - 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, 0x5cb0679e, 0x4fa33742, - 0xd3822740, 0x99bc9bbe, 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, - 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, 0x5748ab2f, 0xbc946e79, - 0xc6a376d2, 0x6549c2c8, 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6, - 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, 0xa1fad5f0, 0x6a2d519a, - 0x63ef8ce2, 0x9a86ee22, 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, - 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, 0x2826a2f9, 0xa73a3ae1, - 0x4ba99586, 0xef5562e9, 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59, - 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, 0xe990fd5a, 0x9e34d797, - 0x2cf0b7d9, 0x022b8b51, 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, - 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, 0xe029ac71, 0xe019a5e6, - 0x47b0acfd, 0xed93fa9b, 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28, - 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, 0x15056dd4, 0x88f46dba, - 0x03a16125, 0x0564f0bd, 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, - 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, 0x7533d928, 0xb155fdf5, - 0x03563482, 0x8aba3cbb, 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f, - 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, 0xea7a90c2, 0xfb3e7bce, - 0x5121ce64, 0x774fbe32, 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, - 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, 0xb39a460a, 0x6445c0dd, - 0x586cdecf, 0x1c20c8ae, 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb, - 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, 0x72eacea8, 0xfa6484bb, - 0x8d6612ae, 0xbf3c6f47, 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, - 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, 0x4040cb08, 0x4eb4e2cc, - 0x34d2466a, 0x0115af84, 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048, - 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, 0x611560b1, 0xe7933fdc, - 0xbb3a792b, 0x344525bd, 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, - 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, 0x1a908749, 0xd44fbd9a, - 0xd0dadecb, 0xd50ada38, 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f, - 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, 0xbf97222c, 0x15e6fc2a, - 0x0f91fc71, 0x9b941525, 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, - 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, 0xe0ec6e0e, 0x1698db3b, - 0x4c98a0be, 0x3278e964, 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e, - 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, 0xdf359f8d, 0x9b992f2e, - 0xe60b6f47, 0x0fe3f11d, 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, - 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, 0xf523f357, 0xa6327623, - 0x93a83531, 0x56cccd02, 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc, - 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, 0xe6c6c7bd, 0x327a140a, - 0x45e1d006, 0xc3f27b9a, 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, - 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, 0x53113ec0, 0x1640e3d3, - 0x38abbd60, 0x2547adf0, 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060, - 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, 0x1948c25c, 0x02fb8a8c, - 0x01c36ae4, 0xd6ebe1f9, 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, - 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6, -} - -var p = [18]uint32{ - 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, 0xa4093822, 0x299f31d0, - 0x082efa98, 0xec4e6c89, 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, - 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, 0x9216d5d9, 0x8979fb1b, -} diff --git a/vendor/golang.org/x/crypto/bn256/bn256.go b/vendor/golang.org/x/crypto/bn256/bn256.go deleted file mode 100644 index 014f8b3..0000000 --- a/vendor/golang.org/x/crypto/bn256/bn256.go +++ /dev/null @@ -1,404 +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. - -// Package bn256 implements a particular bilinear group at the 128-bit security level. -// -// 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. -package bn256 // import "golang.org/x/crypto/bn256" - -import ( - "crypto/rand" - "io" - "math/big" -) - -// BUG(agl): this implementation is not constant time. -// TODO(agl): keep GF(p²) elements in Mongomery form. - -// 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 (g *G1) String() string { - return "bn256.G1" + g.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. -// BUG(agl): this function is not complete: a==b fails. -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 (n *G1) Marshal() []byte { - n.p.MakeAffine(nil) - - xBytes := new(big.Int).Mod(n.p.x, p).Bytes() - yBytes := new(big.Int).Mod(n.p.y, p).Bytes() - - // Each value is a 256-bit number. - const numBytes = 256 / 8 - - 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 (g *G2) String() string { - return "bn256.G2" + g.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. -// BUG(agl): this function is not complete: a==b fails. -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 { - 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() - - // Each value is a 256-bit number. - const numBytes = 256 / 8 - - 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 (g *GT) String() string { - return "bn256.GT" + g.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 >{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/bn256_test.go b/vendor/golang.org/x/crypto/bn256/bn256_test.go deleted file mode 100644 index 1cec388..0000000 --- a/vendor/golang.org/x/crypto/bn256/bn256_test.go +++ /dev/null @@ -1,304 +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. - -package bn256 - -import ( - "bytes" - "crypto/rand" - "math/big" - "testing" -) - -func TestGFp2Invert(t *testing.T) { - pool := new(bnPool) - - a := newGFp2(pool) - a.x.SetString("23423492374", 10) - a.y.SetString("12934872398472394827398470", 10) - - inv := newGFp2(pool) - inv.Invert(a, pool) - - b := newGFp2(pool).Mul(inv, a, pool) - if b.x.Int64() != 0 || b.y.Int64() != 1 { - t.Fatalf("bad result for a^-1*a: %s %s", b.x, b.y) - } - - a.Put(pool) - b.Put(pool) - inv.Put(pool) - - if c := pool.Count(); c > 0 { - t.Errorf("Pool count non-zero: %d\n", c) - } -} - -func isZero(n *big.Int) bool { - return new(big.Int).Mod(n, p).Int64() == 0 -} - -func isOne(n *big.Int) bool { - return new(big.Int).Mod(n, p).Int64() == 1 -} - -func TestGFp6Invert(t *testing.T) { - pool := new(bnPool) - - a := newGFp6(pool) - a.x.x.SetString("239487238491", 10) - a.x.y.SetString("2356249827341", 10) - a.y.x.SetString("082659782", 10) - a.y.y.SetString("182703523765", 10) - a.z.x.SetString("978236549263", 10) - a.z.y.SetString("64893242", 10) - - inv := newGFp6(pool) - inv.Invert(a, pool) - - b := newGFp6(pool).Mul(inv, a, pool) - if !isZero(b.x.x) || - !isZero(b.x.y) || - !isZero(b.y.x) || - !isZero(b.y.y) || - !isZero(b.z.x) || - !isOne(b.z.y) { - t.Fatalf("bad result for a^-1*a: %s", b) - } - - a.Put(pool) - b.Put(pool) - inv.Put(pool) - - if c := pool.Count(); c > 0 { - t.Errorf("Pool count non-zero: %d\n", c) - } -} - -func TestGFp12Invert(t *testing.T) { - pool := new(bnPool) - - a := newGFp12(pool) - a.x.x.x.SetString("239846234862342323958623", 10) - a.x.x.y.SetString("2359862352529835623", 10) - a.x.y.x.SetString("928836523", 10) - a.x.y.y.SetString("9856234", 10) - a.x.z.x.SetString("235635286", 10) - a.x.z.y.SetString("5628392833", 10) - a.y.x.x.SetString("252936598265329856238956532167968", 10) - a.y.x.y.SetString("23596239865236954178968", 10) - a.y.y.x.SetString("95421692834", 10) - a.y.y.y.SetString("236548", 10) - a.y.z.x.SetString("924523", 10) - a.y.z.y.SetString("12954623", 10) - - inv := newGFp12(pool) - inv.Invert(a, pool) - - b := newGFp12(pool).Mul(inv, a, pool) - if !isZero(b.x.x.x) || - !isZero(b.x.x.y) || - !isZero(b.x.y.x) || - !isZero(b.x.y.y) || - !isZero(b.x.z.x) || - !isZero(b.x.z.y) || - !isZero(b.y.x.x) || - !isZero(b.y.x.y) || - !isZero(b.y.y.x) || - !isZero(b.y.y.y) || - !isZero(b.y.z.x) || - !isOne(b.y.z.y) { - t.Fatalf("bad result for a^-1*a: %s", b) - } - - a.Put(pool) - b.Put(pool) - inv.Put(pool) - - if c := pool.Count(); c > 0 { - t.Errorf("Pool count non-zero: %d\n", c) - } -} - -func TestCurveImpl(t *testing.T) { - pool := new(bnPool) - - g := &curvePoint{ - pool.Get().SetInt64(1), - pool.Get().SetInt64(-2), - pool.Get().SetInt64(1), - pool.Get().SetInt64(0), - } - - x := pool.Get().SetInt64(32498273234) - X := newCurvePoint(pool).Mul(g, x, pool) - - y := pool.Get().SetInt64(98732423523) - Y := newCurvePoint(pool).Mul(g, y, pool) - - s1 := newCurvePoint(pool).Mul(X, y, pool).MakeAffine(pool) - s2 := newCurvePoint(pool).Mul(Y, x, pool).MakeAffine(pool) - - if s1.x.Cmp(s2.x) != 0 || - s2.x.Cmp(s1.x) != 0 { - t.Errorf("DH points don't match: (%s, %s) (%s, %s)", s1.x, s1.y, s2.x, s2.y) - } - - pool.Put(x) - X.Put(pool) - pool.Put(y) - Y.Put(pool) - s1.Put(pool) - s2.Put(pool) - g.Put(pool) - - if c := pool.Count(); c > 0 { - t.Errorf("Pool count non-zero: %d\n", c) - } -} - -func TestOrderG1(t *testing.T) { - g := new(G1).ScalarBaseMult(Order) - if !g.p.IsInfinity() { - t.Error("G1 has incorrect order") - } - - one := new(G1).ScalarBaseMult(new(big.Int).SetInt64(1)) - g.Add(g, one) - g.p.MakeAffine(nil) - if g.p.x.Cmp(one.p.x) != 0 || g.p.y.Cmp(one.p.y) != 0 { - t.Errorf("1+0 != 1 in G1") - } -} - -func TestOrderG2(t *testing.T) { - g := new(G2).ScalarBaseMult(Order) - if !g.p.IsInfinity() { - t.Error("G2 has incorrect order") - } - - one := new(G2).ScalarBaseMult(new(big.Int).SetInt64(1)) - g.Add(g, one) - g.p.MakeAffine(nil) - if g.p.x.x.Cmp(one.p.x.x) != 0 || - g.p.x.y.Cmp(one.p.x.y) != 0 || - g.p.y.x.Cmp(one.p.y.x) != 0 || - g.p.y.y.Cmp(one.p.y.y) != 0 { - t.Errorf("1+0 != 1 in G2") - } -} - -func TestOrderGT(t *testing.T) { - gt := Pair(&G1{curveGen}, &G2{twistGen}) - g := new(GT).ScalarMult(gt, Order) - if !g.p.IsOne() { - t.Error("GT has incorrect order") - } -} - -func TestBilinearity(t *testing.T) { - for i := 0; i < 2; i++ { - a, p1, _ := RandomG1(rand.Reader) - b, p2, _ := RandomG2(rand.Reader) - e1 := Pair(p1, p2) - - e2 := Pair(&G1{curveGen}, &G2{twistGen}) - e2.ScalarMult(e2, a) - e2.ScalarMult(e2, b) - - minusE2 := new(GT).Neg(e2) - e1.Add(e1, minusE2) - - if !e1.p.IsOne() { - t.Fatalf("bad pairing result: %s", e1) - } - } -} - -func TestG1Marshal(t *testing.T) { - g := new(G1).ScalarBaseMult(new(big.Int).SetInt64(1)) - form := g.Marshal() - _, ok := new(G1).Unmarshal(form) - if !ok { - t.Fatalf("failed to unmarshal") - } - - g.ScalarBaseMult(Order) - form = g.Marshal() - g2, ok := new(G1).Unmarshal(form) - if !ok { - t.Fatalf("failed to unmarshal ∞") - } - if !g2.p.IsInfinity() { - t.Fatalf("∞ unmarshaled incorrectly") - } -} - -func TestG2Marshal(t *testing.T) { - g := new(G2).ScalarBaseMult(new(big.Int).SetInt64(1)) - form := g.Marshal() - _, ok := new(G2).Unmarshal(form) - if !ok { - t.Fatalf("failed to unmarshal") - } - - g.ScalarBaseMult(Order) - form = g.Marshal() - g2, ok := new(G2).Unmarshal(form) - if !ok { - t.Fatalf("failed to unmarshal ∞") - } - if !g2.p.IsInfinity() { - t.Fatalf("∞ unmarshaled incorrectly") - } -} - -func TestG1Identity(t *testing.T) { - g := new(G1).ScalarBaseMult(new(big.Int).SetInt64(0)) - if !g.p.IsInfinity() { - t.Error("failure") - } -} - -func TestG2Identity(t *testing.T) { - g := new(G2).ScalarBaseMult(new(big.Int).SetInt64(0)) - if !g.p.IsInfinity() { - t.Error("failure") - } -} - -func TestTripartiteDiffieHellman(t *testing.T) { - a, _ := rand.Int(rand.Reader, Order) - b, _ := rand.Int(rand.Reader, Order) - c, _ := rand.Int(rand.Reader, Order) - - pa, _ := new(G1).Unmarshal(new(G1).ScalarBaseMult(a).Marshal()) - qa, _ := new(G2).Unmarshal(new(G2).ScalarBaseMult(a).Marshal()) - pb, _ := new(G1).Unmarshal(new(G1).ScalarBaseMult(b).Marshal()) - qb, _ := new(G2).Unmarshal(new(G2).ScalarBaseMult(b).Marshal()) - pc, _ := new(G1).Unmarshal(new(G1).ScalarBaseMult(c).Marshal()) - qc, _ := new(G2).Unmarshal(new(G2).ScalarBaseMult(c).Marshal()) - - k1 := Pair(pb, qc) - k1.ScalarMult(k1, a) - k1Bytes := k1.Marshal() - - k2 := Pair(pc, qa) - k2.ScalarMult(k2, b) - k2Bytes := k2.Marshal() - - k3 := Pair(pa, qb) - k3.ScalarMult(k3, c) - k3Bytes := k3.Marshal() - - if !bytes.Equal(k1Bytes, k2Bytes) || !bytes.Equal(k2Bytes, k3Bytes) { - t.Errorf("keys didn't agree") - } -} - -func BenchmarkPairing(b *testing.B) { - for i := 0; i < b.N; i++ { - Pair(&G1{curveGen}, &G2{twistGen}) - } -} diff --git a/vendor/golang.org/x/crypto/bn256/constants.go b/vendor/golang.org/x/crypto/bn256/constants.go deleted file mode 100644 index 08ccfdf..0000000 --- a/vendor/golang.org/x/crypto/bn256/constants.go +++ /dev/null @@ -1,44 +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. - -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 deleted file mode 100644 index 55b7063..0000000 --- a/vendor/golang.org/x/crypto/bn256/curve.go +++ /dev/null @@ -1,278 +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. - -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 -} - -func (c *curvePoint) MakeAffine(pool *bnPool) *curvePoint { - if words := c.z.Bits(); len(words) == 1 && words[0] == 1 { - 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/example_test.go b/vendor/golang.org/x/crypto/bn256/example_test.go deleted file mode 100644 index b2d1980..0000000 --- a/vendor/golang.org/x/crypto/bn256/example_test.go +++ /dev/null @@ -1,43 +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. - -package bn256 - -import ( - "crypto/rand" -) - -func ExamplePair() { - // This implements the tripartite Diffie-Hellman algorithm from "A One - // Round Protocol for Tripartite Diffie-Hellman", A. Joux. - // http://www.springerlink.com/content/cddc57yyva0hburb/fulltext.pdf - - // Each of three parties, a, b and c, generate a private value. - a, _ := rand.Int(rand.Reader, Order) - b, _ := rand.Int(rand.Reader, Order) - c, _ := rand.Int(rand.Reader, Order) - - // Then each party calculates g₁ and g₂ times their private value. - pa := new(G1).ScalarBaseMult(a) - qa := new(G2).ScalarBaseMult(a) - - pb := new(G1).ScalarBaseMult(b) - qb := new(G2).ScalarBaseMult(b) - - pc := new(G1).ScalarBaseMult(c) - qc := new(G2).ScalarBaseMult(c) - - // Now each party exchanges its public values with the other two and - // all parties can calculate the shared key. - k1 := Pair(pb, qc) - k1.ScalarMult(k1, a) - - k2 := Pair(pc, qa) - k2.ScalarMult(k2, b) - - k3 := Pair(pa, qb) - k3.ScalarMult(k3, c) - - // k1, k2 and k3 will all be equal. -} diff --git a/vendor/golang.org/x/crypto/bn256/gfp12.go b/vendor/golang.org/x/crypto/bn256/gfp12.go deleted file mode 100644 index f084edd..0000000 --- a/vendor/golang.org/x/crypto/bn256/gfp12.go +++ /dev/null @@ -1,200 +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. - -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(e.x, b, pool) - e.y.Mul(e.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 deleted file mode 100644 index 97f3f1f..0000000 --- a/vendor/golang.org/x/crypto/bn256/gfp2.go +++ /dev/null @@ -1,219 +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. - -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 deleted file mode 100644 index f98ae78..0000000 --- a/vendor/golang.org/x/crypto/bn256/gfp6.go +++ /dev/null @@ -1,296 +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. - -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 deleted file mode 100644 index 7ae0746..0000000 --- a/vendor/golang.org/x/crypto/bn256/optate.go +++ /dev/null @@ -1,395 +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. - -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 deleted file mode 100644 index 4f8b3fe..0000000 --- a/vendor/golang.org/x/crypto/bn256/twist.go +++ /dev/null @@ -1,249 +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. - -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 -} - -func (c *twistPoint) MakeAffine(pool *bnPool) *twistPoint { - if c.z.IsOne() { - 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 deleted file mode 100644 index 0b4af37..0000000 --- a/vendor/golang.org/x/crypto/cast5/cast5.go +++ /dev/null @@ -1,526 +0,0 @@ -// 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 common -// OpenPGP cipher. -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/cast5/cast5_test.go b/vendor/golang.org/x/crypto/cast5/cast5_test.go deleted file mode 100644 index 778b272..0000000 --- a/vendor/golang.org/x/crypto/cast5/cast5_test.go +++ /dev/null @@ -1,106 +0,0 @@ -// 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 - -import ( - "bytes" - "encoding/hex" - "testing" -) - -// This test vector is taken from RFC 2144, App B.1. -// Since the other two test vectors are for reduced-round variants, we can't -// use them. -var basicTests = []struct { - key, plainText, cipherText string -}{ - { - "0123456712345678234567893456789a", - "0123456789abcdef", - "238b4fe5847e44b2", - }, -} - -func TestBasic(t *testing.T) { - for i, test := range basicTests { - key, _ := hex.DecodeString(test.key) - plainText, _ := hex.DecodeString(test.plainText) - expected, _ := hex.DecodeString(test.cipherText) - - c, err := NewCipher(key) - if err != nil { - t.Errorf("#%d: failed to create Cipher: %s", i, err) - continue - } - var cipherText [BlockSize]byte - c.Encrypt(cipherText[:], plainText) - if !bytes.Equal(cipherText[:], expected) { - t.Errorf("#%d: got:%x want:%x", i, cipherText, expected) - } - - var plainTextAgain [BlockSize]byte - c.Decrypt(plainTextAgain[:], cipherText[:]) - if !bytes.Equal(plainTextAgain[:], plainText) { - t.Errorf("#%d: got:%x want:%x", i, plainTextAgain, plainText) - } - } -} - -// TestFull performs the test specified in RFC 2144, App B.2. -// However, due to the length of time taken, it's disabled here and a more -// limited version is included, below. -func TestFull(t *testing.T) { - if testing.Short() { - // This is too slow for normal testing - return - } - - a, b := iterate(1000000) - - const expectedA = "eea9d0a249fd3ba6b3436fb89d6dca92" - const expectedB = "b2c95eb00c31ad7180ac05b8e83d696e" - - if hex.EncodeToString(a) != expectedA { - t.Errorf("a: got:%x want:%s", a, expectedA) - } - if hex.EncodeToString(b) != expectedB { - t.Errorf("b: got:%x want:%s", b, expectedB) - } -} - -func iterate(iterations int) ([]byte, []byte) { - const initValueHex = "0123456712345678234567893456789a" - - initValue, _ := hex.DecodeString(initValueHex) - - var a, b [16]byte - copy(a[:], initValue) - copy(b[:], initValue) - - for i := 0; i < iterations; i++ { - c, _ := NewCipher(b[:]) - c.Encrypt(a[:8], a[:8]) - c.Encrypt(a[8:], a[8:]) - c, _ = NewCipher(a[:]) - c.Encrypt(b[:8], b[:8]) - c.Encrypt(b[8:], b[8:]) - } - - return a[:], b[:] -} - -func TestLimited(t *testing.T) { - a, b := iterate(1000) - - const expectedA = "23f73b14b02a2ad7dfb9f2c35644798d" - const expectedB = "e5bf37eff14c456a40b21ce369370a9f" - - if hex.EncodeToString(a) != expectedA { - t.Errorf("a: got:%x want:%s", a, expectedA) - } - if hex.EncodeToString(b) != expectedB { - t.Errorf("b: got:%x want:%s", b, expectedB) - } -} diff --git a/vendor/golang.org/x/crypto/codereview.cfg b/vendor/golang.org/x/crypto/codereview.cfg deleted file mode 100644 index 3f8b14b..0000000 --- a/vendor/golang.org/x/crypto/codereview.cfg +++ /dev/null @@ -1 +0,0 @@ -issuerepo: golang/go diff --git a/vendor/golang.org/x/crypto/curve25519/const_amd64.s b/vendor/golang.org/x/crypto/curve25519/const_amd64.s deleted file mode 100644 index 797f9b0..0000000 --- a/vendor/golang.org/x/crypto/curve25519/const_amd64.s +++ /dev/null @@ -1,20 +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: http://bench.cr.yp.to/supercop.html - -// +build amd64,!gccgo,!appengine - -DATA ·REDMASK51(SB)/8, $0x0007FFFFFFFFFFFF -GLOBL ·REDMASK51(SB), 8, $8 - -DATA ·_121666_213(SB)/8, $996687872 -GLOBL ·_121666_213(SB), 8, $8 - -DATA ·_2P0(SB)/8, $0xFFFFFFFFFFFDA -GLOBL ·_2P0(SB), 8, $8 - -DATA ·_2P1234(SB)/8, $0xFFFFFFFFFFFFE -GLOBL ·_2P1234(SB), 8, $8 diff --git a/vendor/golang.org/x/crypto/curve25519/cswap_amd64.s b/vendor/golang.org/x/crypto/curve25519/cswap_amd64.s deleted file mode 100644 index 45484d1..0000000 --- a/vendor/golang.org/x/crypto/curve25519/cswap_amd64.s +++ /dev/null @@ -1,88 +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: http://bench.cr.yp.to/supercop.html - -// +build amd64,!gccgo,!appengine - -// func cswap(inout *[5]uint64, v uint64) -TEXT ·cswap(SB),7,$0 - MOVQ inout+0(FP),DI - MOVQ v+8(FP),SI - - CMPQ SI,$1 - MOVQ 0(DI),SI - MOVQ 80(DI),DX - MOVQ 8(DI),CX - MOVQ 88(DI),R8 - MOVQ SI,R9 - CMOVQEQ DX,SI - CMOVQEQ R9,DX - MOVQ CX,R9 - CMOVQEQ R8,CX - CMOVQEQ R9,R8 - MOVQ SI,0(DI) - MOVQ DX,80(DI) - MOVQ CX,8(DI) - MOVQ R8,88(DI) - MOVQ 16(DI),SI - MOVQ 96(DI),DX - MOVQ 24(DI),CX - MOVQ 104(DI),R8 - MOVQ SI,R9 - CMOVQEQ DX,SI - CMOVQEQ R9,DX - MOVQ CX,R9 - CMOVQEQ R8,CX - CMOVQEQ R9,R8 - MOVQ SI,16(DI) - MOVQ DX,96(DI) - MOVQ CX,24(DI) - MOVQ R8,104(DI) - MOVQ 32(DI),SI - MOVQ 112(DI),DX - MOVQ 40(DI),CX - MOVQ 120(DI),R8 - MOVQ SI,R9 - CMOVQEQ DX,SI - CMOVQEQ R9,DX - MOVQ CX,R9 - CMOVQEQ R8,CX - CMOVQEQ R9,R8 - MOVQ SI,32(DI) - MOVQ DX,112(DI) - MOVQ CX,40(DI) - MOVQ R8,120(DI) - MOVQ 48(DI),SI - MOVQ 128(DI),DX - MOVQ 56(DI),CX - MOVQ 136(DI),R8 - MOVQ SI,R9 - CMOVQEQ DX,SI - CMOVQEQ R9,DX - MOVQ CX,R9 - CMOVQEQ R8,CX - CMOVQEQ R9,R8 - MOVQ SI,48(DI) - MOVQ DX,128(DI) - MOVQ CX,56(DI) - MOVQ R8,136(DI) - MOVQ 64(DI),SI - MOVQ 144(DI),DX - MOVQ 72(DI),CX - MOVQ 152(DI),R8 - MOVQ SI,R9 - CMOVQEQ DX,SI - CMOVQEQ R9,DX - MOVQ CX,R9 - CMOVQEQ R8,CX - CMOVQEQ R9,R8 - MOVQ SI,64(DI) - MOVQ DX,144(DI) - MOVQ CX,72(DI) - MOVQ R8,152(DI) - MOVQ DI,AX - MOVQ SI,DX - RET diff --git a/vendor/golang.org/x/crypto/curve25519/curve25519.go b/vendor/golang.org/x/crypto/curve25519/curve25519.go deleted file mode 100644 index 6918c47..0000000 --- a/vendor/golang.org/x/crypto/curve25519/curve25519.go +++ /dev/null @@ -1,841 +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. - -// We have a implementation in amd64 assembly so this code is only run on -// non-amd64 platforms. The amd64 assembly does not support gccgo. -// +build !amd64 gccgo appengine - -package curve25519 - -// This code is a port of the public domain, "ref10" implementation of -// curve25519 from SUPERCOP 20130419 by D. J. Bernstein. - -// fieldElement represents an element of the field GF(2^255 - 19). An element -// t, entries t[0]...t[9], represents the integer t[0]+2^26 t[1]+2^51 t[2]+2^77 -// t[3]+2^102 t[4]+...+2^230 t[9]. Bounds on each t[i] vary depending on -// context. -type fieldElement [10]int32 - -func feZero(fe *fieldElement) { - for i := range fe { - fe[i] = 0 - } -} - -func feOne(fe *fieldElement) { - feZero(fe) - fe[0] = 1 -} - -func feAdd(dst, a, b *fieldElement) { - for i := range dst { - dst[i] = a[i] + b[i] - } -} - -func feSub(dst, a, b *fieldElement) { - for i := range dst { - dst[i] = a[i] - b[i] - } -} - -func feCopy(dst, src *fieldElement) { - for i := range dst { - dst[i] = src[i] - } -} - -// feCSwap replaces (f,g) with (g,f) if b == 1; replaces (f,g) with (f,g) if b == 0. -// -// Preconditions: b in {0,1}. -func feCSwap(f, g *fieldElement, b int32) { - var x fieldElement - b = -b - for i := range x { - x[i] = b & (f[i] ^ g[i]) - } - - for i := range f { - f[i] ^= x[i] - } - for i := range g { - g[i] ^= x[i] - } -} - -// load3 reads a 24-bit, little-endian value from in. -func load3(in []byte) int64 { - var r int64 - r = int64(in[0]) - r |= int64(in[1]) << 8 - r |= int64(in[2]) << 16 - return r -} - -// load4 reads a 32-bit, little-endian value from in. -func load4(in []byte) int64 { - var r int64 - r = int64(in[0]) - r |= int64(in[1]) << 8 - r |= int64(in[2]) << 16 - r |= int64(in[3]) << 24 - return r -} - -func feFromBytes(dst *fieldElement, src *[32]byte) { - h0 := load4(src[:]) - h1 := load3(src[4:]) << 6 - h2 := load3(src[7:]) << 5 - h3 := load3(src[10:]) << 3 - h4 := load3(src[13:]) << 2 - h5 := load4(src[16:]) - h6 := load3(src[20:]) << 7 - h7 := load3(src[23:]) << 5 - h8 := load3(src[26:]) << 4 - h9 := load3(src[29:]) << 2 - - var carry [10]int64 - carry[9] = (h9 + 1<<24) >> 25 - h0 += carry[9] * 19 - h9 -= carry[9] << 25 - carry[1] = (h1 + 1<<24) >> 25 - h2 += carry[1] - h1 -= carry[1] << 25 - carry[3] = (h3 + 1<<24) >> 25 - h4 += carry[3] - h3 -= carry[3] << 25 - carry[5] = (h5 + 1<<24) >> 25 - h6 += carry[5] - h5 -= carry[5] << 25 - carry[7] = (h7 + 1<<24) >> 25 - h8 += carry[7] - h7 -= carry[7] << 25 - - carry[0] = (h0 + 1<<25) >> 26 - h1 += carry[0] - h0 -= carry[0] << 26 - carry[2] = (h2 + 1<<25) >> 26 - h3 += carry[2] - h2 -= carry[2] << 26 - carry[4] = (h4 + 1<<25) >> 26 - h5 += carry[4] - h4 -= carry[4] << 26 - carry[6] = (h6 + 1<<25) >> 26 - h7 += carry[6] - h6 -= carry[6] << 26 - carry[8] = (h8 + 1<<25) >> 26 - h9 += carry[8] - h8 -= carry[8] << 26 - - dst[0] = int32(h0) - dst[1] = int32(h1) - dst[2] = int32(h2) - dst[3] = int32(h3) - dst[4] = int32(h4) - dst[5] = int32(h5) - dst[6] = int32(h6) - dst[7] = int32(h7) - dst[8] = int32(h8) - dst[9] = int32(h9) -} - -// feToBytes marshals h to s. -// Preconditions: -// |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. -// -// Write p=2^255-19; q=floor(h/p). -// Basic claim: q = floor(2^(-255)(h + 19 2^(-25)h9 + 2^(-1))). -// -// Proof: -// Have |h|<=p so |q|<=1 so |19^2 2^(-255) q|<1/4. -// Also have |h-2^230 h9|<2^230 so |19 2^(-255)(h-2^230 h9)|<1/4. -// -// Write y=2^(-1)-19^2 2^(-255)q-19 2^(-255)(h-2^230 h9). -// Then 0> 25 - q = (h[0] + q) >> 26 - q = (h[1] + q) >> 25 - q = (h[2] + q) >> 26 - q = (h[3] + q) >> 25 - q = (h[4] + q) >> 26 - q = (h[5] + q) >> 25 - q = (h[6] + q) >> 26 - q = (h[7] + q) >> 25 - q = (h[8] + q) >> 26 - q = (h[9] + q) >> 25 - - // Goal: Output h-(2^255-19)q, which is between 0 and 2^255-20. - h[0] += 19 * q - // Goal: Output h-2^255 q, which is between 0 and 2^255-20. - - carry[0] = h[0] >> 26 - h[1] += carry[0] - h[0] -= carry[0] << 26 - carry[1] = h[1] >> 25 - h[2] += carry[1] - h[1] -= carry[1] << 25 - carry[2] = h[2] >> 26 - h[3] += carry[2] - h[2] -= carry[2] << 26 - carry[3] = h[3] >> 25 - h[4] += carry[3] - h[3] -= carry[3] << 25 - carry[4] = h[4] >> 26 - h[5] += carry[4] - h[4] -= carry[4] << 26 - carry[5] = h[5] >> 25 - h[6] += carry[5] - h[5] -= carry[5] << 25 - carry[6] = h[6] >> 26 - h[7] += carry[6] - h[6] -= carry[6] << 26 - carry[7] = h[7] >> 25 - h[8] += carry[7] - h[7] -= carry[7] << 25 - carry[8] = h[8] >> 26 - h[9] += carry[8] - h[8] -= carry[8] << 26 - carry[9] = h[9] >> 25 - h[9] -= carry[9] << 25 - // h10 = carry9 - - // Goal: Output h[0]+...+2^255 h10-2^255 q, which is between 0 and 2^255-20. - // Have h[0]+...+2^230 h[9] between 0 and 2^255-1; - // evidently 2^255 h10-2^255 q = 0. - // Goal: Output h[0]+...+2^230 h[9]. - - s[0] = byte(h[0] >> 0) - s[1] = byte(h[0] >> 8) - s[2] = byte(h[0] >> 16) - s[3] = byte((h[0] >> 24) | (h[1] << 2)) - s[4] = byte(h[1] >> 6) - s[5] = byte(h[1] >> 14) - s[6] = byte((h[1] >> 22) | (h[2] << 3)) - s[7] = byte(h[2] >> 5) - s[8] = byte(h[2] >> 13) - s[9] = byte((h[2] >> 21) | (h[3] << 5)) - s[10] = byte(h[3] >> 3) - s[11] = byte(h[3] >> 11) - s[12] = byte((h[3] >> 19) | (h[4] << 6)) - s[13] = byte(h[4] >> 2) - s[14] = byte(h[4] >> 10) - s[15] = byte(h[4] >> 18) - s[16] = byte(h[5] >> 0) - s[17] = byte(h[5] >> 8) - s[18] = byte(h[5] >> 16) - s[19] = byte((h[5] >> 24) | (h[6] << 1)) - s[20] = byte(h[6] >> 7) - s[21] = byte(h[6] >> 15) - s[22] = byte((h[6] >> 23) | (h[7] << 3)) - s[23] = byte(h[7] >> 5) - s[24] = byte(h[7] >> 13) - s[25] = byte((h[7] >> 21) | (h[8] << 4)) - s[26] = byte(h[8] >> 4) - s[27] = byte(h[8] >> 12) - s[28] = byte((h[8] >> 20) | (h[9] << 6)) - s[29] = byte(h[9] >> 2) - s[30] = byte(h[9] >> 10) - s[31] = byte(h[9] >> 18) -} - -// feMul calculates h = f * g -// Can overlap h with f or g. -// -// Preconditions: -// |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. -// |g| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. -// -// Postconditions: -// |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. -// -// Notes on implementation strategy: -// -// Using schoolbook multiplication. -// Karatsuba would save a little in some cost models. -// -// Most multiplications by 2 and 19 are 32-bit precomputations; -// cheaper than 64-bit postcomputations. -// -// There is one remaining multiplication by 19 in the carry chain; -// one *19 precomputation can be merged into this, -// but the resulting data flow is considerably less clean. -// -// There are 12 carries below. -// 10 of them are 2-way parallelizable and vectorizable. -// Can get away with 11 carries, but then data flow is much deeper. -// -// With tighter constraints on inputs can squeeze carries into int32. -func feMul(h, f, g *fieldElement) { - f0 := f[0] - f1 := f[1] - f2 := f[2] - f3 := f[3] - f4 := f[4] - f5 := f[5] - f6 := f[6] - f7 := f[7] - f8 := f[8] - f9 := f[9] - g0 := g[0] - g1 := g[1] - g2 := g[2] - g3 := g[3] - g4 := g[4] - g5 := g[5] - g6 := g[6] - g7 := g[7] - g8 := g[8] - g9 := g[9] - g1_19 := 19 * g1 // 1.4*2^29 - g2_19 := 19 * g2 // 1.4*2^30; still ok - g3_19 := 19 * g3 - g4_19 := 19 * g4 - g5_19 := 19 * g5 - g6_19 := 19 * g6 - g7_19 := 19 * g7 - g8_19 := 19 * g8 - g9_19 := 19 * g9 - f1_2 := 2 * f1 - f3_2 := 2 * f3 - f5_2 := 2 * f5 - f7_2 := 2 * f7 - f9_2 := 2 * f9 - f0g0 := int64(f0) * int64(g0) - f0g1 := int64(f0) * int64(g1) - f0g2 := int64(f0) * int64(g2) - f0g3 := int64(f0) * int64(g3) - f0g4 := int64(f0) * int64(g4) - f0g5 := int64(f0) * int64(g5) - f0g6 := int64(f0) * int64(g6) - f0g7 := int64(f0) * int64(g7) - f0g8 := int64(f0) * int64(g8) - f0g9 := int64(f0) * int64(g9) - f1g0 := int64(f1) * int64(g0) - f1g1_2 := int64(f1_2) * int64(g1) - f1g2 := int64(f1) * int64(g2) - f1g3_2 := int64(f1_2) * int64(g3) - f1g4 := int64(f1) * int64(g4) - f1g5_2 := int64(f1_2) * int64(g5) - f1g6 := int64(f1) * int64(g6) - f1g7_2 := int64(f1_2) * int64(g7) - f1g8 := int64(f1) * int64(g8) - f1g9_38 := int64(f1_2) * int64(g9_19) - f2g0 := int64(f2) * int64(g0) - f2g1 := int64(f2) * int64(g1) - f2g2 := int64(f2) * int64(g2) - f2g3 := int64(f2) * int64(g3) - f2g4 := int64(f2) * int64(g4) - f2g5 := int64(f2) * int64(g5) - f2g6 := int64(f2) * int64(g6) - f2g7 := int64(f2) * int64(g7) - f2g8_19 := int64(f2) * int64(g8_19) - f2g9_19 := int64(f2) * int64(g9_19) - f3g0 := int64(f3) * int64(g0) - f3g1_2 := int64(f3_2) * int64(g1) - f3g2 := int64(f3) * int64(g2) - f3g3_2 := int64(f3_2) * int64(g3) - f3g4 := int64(f3) * int64(g4) - f3g5_2 := int64(f3_2) * int64(g5) - f3g6 := int64(f3) * int64(g6) - f3g7_38 := int64(f3_2) * int64(g7_19) - f3g8_19 := int64(f3) * int64(g8_19) - f3g9_38 := int64(f3_2) * int64(g9_19) - f4g0 := int64(f4) * int64(g0) - f4g1 := int64(f4) * int64(g1) - f4g2 := int64(f4) * int64(g2) - f4g3 := int64(f4) * int64(g3) - f4g4 := int64(f4) * int64(g4) - f4g5 := int64(f4) * int64(g5) - f4g6_19 := int64(f4) * int64(g6_19) - f4g7_19 := int64(f4) * int64(g7_19) - f4g8_19 := int64(f4) * int64(g8_19) - f4g9_19 := int64(f4) * int64(g9_19) - f5g0 := int64(f5) * int64(g0) - f5g1_2 := int64(f5_2) * int64(g1) - f5g2 := int64(f5) * int64(g2) - f5g3_2 := int64(f5_2) * int64(g3) - f5g4 := int64(f5) * int64(g4) - f5g5_38 := int64(f5_2) * int64(g5_19) - f5g6_19 := int64(f5) * int64(g6_19) - f5g7_38 := int64(f5_2) * int64(g7_19) - f5g8_19 := int64(f5) * int64(g8_19) - f5g9_38 := int64(f5_2) * int64(g9_19) - f6g0 := int64(f6) * int64(g0) - f6g1 := int64(f6) * int64(g1) - f6g2 := int64(f6) * int64(g2) - f6g3 := int64(f6) * int64(g3) - f6g4_19 := int64(f6) * int64(g4_19) - f6g5_19 := int64(f6) * int64(g5_19) - f6g6_19 := int64(f6) * int64(g6_19) - f6g7_19 := int64(f6) * int64(g7_19) - f6g8_19 := int64(f6) * int64(g8_19) - f6g9_19 := int64(f6) * int64(g9_19) - f7g0 := int64(f7) * int64(g0) - f7g1_2 := int64(f7_2) * int64(g1) - f7g2 := int64(f7) * int64(g2) - f7g3_38 := int64(f7_2) * int64(g3_19) - f7g4_19 := int64(f7) * int64(g4_19) - f7g5_38 := int64(f7_2) * int64(g5_19) - f7g6_19 := int64(f7) * int64(g6_19) - f7g7_38 := int64(f7_2) * int64(g7_19) - f7g8_19 := int64(f7) * int64(g8_19) - f7g9_38 := int64(f7_2) * int64(g9_19) - f8g0 := int64(f8) * int64(g0) - f8g1 := int64(f8) * int64(g1) - f8g2_19 := int64(f8) * int64(g2_19) - f8g3_19 := int64(f8) * int64(g3_19) - f8g4_19 := int64(f8) * int64(g4_19) - f8g5_19 := int64(f8) * int64(g5_19) - f8g6_19 := int64(f8) * int64(g6_19) - f8g7_19 := int64(f8) * int64(g7_19) - f8g8_19 := int64(f8) * int64(g8_19) - f8g9_19 := int64(f8) * int64(g9_19) - f9g0 := int64(f9) * int64(g0) - f9g1_38 := int64(f9_2) * int64(g1_19) - f9g2_19 := int64(f9) * int64(g2_19) - f9g3_38 := int64(f9_2) * int64(g3_19) - f9g4_19 := int64(f9) * int64(g4_19) - f9g5_38 := int64(f9_2) * int64(g5_19) - f9g6_19 := int64(f9) * int64(g6_19) - f9g7_38 := int64(f9_2) * int64(g7_19) - f9g8_19 := int64(f9) * int64(g8_19) - f9g9_38 := int64(f9_2) * int64(g9_19) - h0 := f0g0 + f1g9_38 + f2g8_19 + f3g7_38 + f4g6_19 + f5g5_38 + f6g4_19 + f7g3_38 + f8g2_19 + f9g1_38 - h1 := f0g1 + f1g0 + f2g9_19 + f3g8_19 + f4g7_19 + f5g6_19 + f6g5_19 + f7g4_19 + f8g3_19 + f9g2_19 - h2 := f0g2 + f1g1_2 + f2g0 + f3g9_38 + f4g8_19 + f5g7_38 + f6g6_19 + f7g5_38 + f8g4_19 + f9g3_38 - h3 := f0g3 + f1g2 + f2g1 + f3g0 + f4g9_19 + f5g8_19 + f6g7_19 + f7g6_19 + f8g5_19 + f9g4_19 - h4 := f0g4 + f1g3_2 + f2g2 + f3g1_2 + f4g0 + f5g9_38 + f6g8_19 + f7g7_38 + f8g6_19 + f9g5_38 - h5 := f0g5 + f1g4 + f2g3 + f3g2 + f4g1 + f5g0 + f6g9_19 + f7g8_19 + f8g7_19 + f9g6_19 - h6 := f0g6 + f1g5_2 + f2g4 + f3g3_2 + f4g2 + f5g1_2 + f6g0 + f7g9_38 + f8g8_19 + f9g7_38 - h7 := f0g7 + f1g6 + f2g5 + f3g4 + f4g3 + f5g2 + f6g1 + f7g0 + f8g9_19 + f9g8_19 - h8 := f0g8 + f1g7_2 + f2g6 + f3g5_2 + f4g4 + f5g3_2 + f6g2 + f7g1_2 + f8g0 + f9g9_38 - h9 := f0g9 + f1g8 + f2g7 + f3g6 + f4g5 + f5g4 + f6g3 + f7g2 + f8g1 + f9g0 - var carry [10]int64 - - // |h0| <= (1.1*1.1*2^52*(1+19+19+19+19)+1.1*1.1*2^50*(38+38+38+38+38)) - // i.e. |h0| <= 1.2*2^59; narrower ranges for h2, h4, h6, h8 - // |h1| <= (1.1*1.1*2^51*(1+1+19+19+19+19+19+19+19+19)) - // i.e. |h1| <= 1.5*2^58; narrower ranges for h3, h5, h7, h9 - - carry[0] = (h0 + (1 << 25)) >> 26 - h1 += carry[0] - h0 -= carry[0] << 26 - carry[4] = (h4 + (1 << 25)) >> 26 - h5 += carry[4] - h4 -= carry[4] << 26 - // |h0| <= 2^25 - // |h4| <= 2^25 - // |h1| <= 1.51*2^58 - // |h5| <= 1.51*2^58 - - carry[1] = (h1 + (1 << 24)) >> 25 - h2 += carry[1] - h1 -= carry[1] << 25 - carry[5] = (h5 + (1 << 24)) >> 25 - h6 += carry[5] - h5 -= carry[5] << 25 - // |h1| <= 2^24; from now on fits into int32 - // |h5| <= 2^24; from now on fits into int32 - // |h2| <= 1.21*2^59 - // |h6| <= 1.21*2^59 - - carry[2] = (h2 + (1 << 25)) >> 26 - h3 += carry[2] - h2 -= carry[2] << 26 - carry[6] = (h6 + (1 << 25)) >> 26 - h7 += carry[6] - h6 -= carry[6] << 26 - // |h2| <= 2^25; from now on fits into int32 unchanged - // |h6| <= 2^25; from now on fits into int32 unchanged - // |h3| <= 1.51*2^58 - // |h7| <= 1.51*2^58 - - carry[3] = (h3 + (1 << 24)) >> 25 - h4 += carry[3] - h3 -= carry[3] << 25 - carry[7] = (h7 + (1 << 24)) >> 25 - h8 += carry[7] - h7 -= carry[7] << 25 - // |h3| <= 2^24; from now on fits into int32 unchanged - // |h7| <= 2^24; from now on fits into int32 unchanged - // |h4| <= 1.52*2^33 - // |h8| <= 1.52*2^33 - - carry[4] = (h4 + (1 << 25)) >> 26 - h5 += carry[4] - h4 -= carry[4] << 26 - carry[8] = (h8 + (1 << 25)) >> 26 - h9 += carry[8] - h8 -= carry[8] << 26 - // |h4| <= 2^25; from now on fits into int32 unchanged - // |h8| <= 2^25; from now on fits into int32 unchanged - // |h5| <= 1.01*2^24 - // |h9| <= 1.51*2^58 - - carry[9] = (h9 + (1 << 24)) >> 25 - h0 += carry[9] * 19 - h9 -= carry[9] << 25 - // |h9| <= 2^24; from now on fits into int32 unchanged - // |h0| <= 1.8*2^37 - - carry[0] = (h0 + (1 << 25)) >> 26 - h1 += carry[0] - h0 -= carry[0] << 26 - // |h0| <= 2^25; from now on fits into int32 unchanged - // |h1| <= 1.01*2^24 - - h[0] = int32(h0) - h[1] = int32(h1) - h[2] = int32(h2) - h[3] = int32(h3) - h[4] = int32(h4) - h[5] = int32(h5) - h[6] = int32(h6) - h[7] = int32(h7) - h[8] = int32(h8) - h[9] = int32(h9) -} - -// feSquare calculates h = f*f. Can overlap h with f. -// -// Preconditions: -// |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. -// -// Postconditions: -// |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. -func feSquare(h, f *fieldElement) { - f0 := f[0] - f1 := f[1] - f2 := f[2] - f3 := f[3] - f4 := f[4] - f5 := f[5] - f6 := f[6] - f7 := f[7] - f8 := f[8] - f9 := f[9] - f0_2 := 2 * f0 - f1_2 := 2 * f1 - f2_2 := 2 * f2 - f3_2 := 2 * f3 - f4_2 := 2 * f4 - f5_2 := 2 * f5 - f6_2 := 2 * f6 - f7_2 := 2 * f7 - f5_38 := 38 * f5 // 1.31*2^30 - f6_19 := 19 * f6 // 1.31*2^30 - f7_38 := 38 * f7 // 1.31*2^30 - f8_19 := 19 * f8 // 1.31*2^30 - f9_38 := 38 * f9 // 1.31*2^30 - f0f0 := int64(f0) * int64(f0) - f0f1_2 := int64(f0_2) * int64(f1) - f0f2_2 := int64(f0_2) * int64(f2) - f0f3_2 := int64(f0_2) * int64(f3) - f0f4_2 := int64(f0_2) * int64(f4) - f0f5_2 := int64(f0_2) * int64(f5) - f0f6_2 := int64(f0_2) * int64(f6) - f0f7_2 := int64(f0_2) * int64(f7) - f0f8_2 := int64(f0_2) * int64(f8) - f0f9_2 := int64(f0_2) * int64(f9) - f1f1_2 := int64(f1_2) * int64(f1) - f1f2_2 := int64(f1_2) * int64(f2) - f1f3_4 := int64(f1_2) * int64(f3_2) - f1f4_2 := int64(f1_2) * int64(f4) - f1f5_4 := int64(f1_2) * int64(f5_2) - f1f6_2 := int64(f1_2) * int64(f6) - f1f7_4 := int64(f1_2) * int64(f7_2) - f1f8_2 := int64(f1_2) * int64(f8) - f1f9_76 := int64(f1_2) * int64(f9_38) - f2f2 := int64(f2) * int64(f2) - f2f3_2 := int64(f2_2) * int64(f3) - f2f4_2 := int64(f2_2) * int64(f4) - f2f5_2 := int64(f2_2) * int64(f5) - f2f6_2 := int64(f2_2) * int64(f6) - f2f7_2 := int64(f2_2) * int64(f7) - f2f8_38 := int64(f2_2) * int64(f8_19) - f2f9_38 := int64(f2) * int64(f9_38) - f3f3_2 := int64(f3_2) * int64(f3) - f3f4_2 := int64(f3_2) * int64(f4) - f3f5_4 := int64(f3_2) * int64(f5_2) - f3f6_2 := int64(f3_2) * int64(f6) - f3f7_76 := int64(f3_2) * int64(f7_38) - f3f8_38 := int64(f3_2) * int64(f8_19) - f3f9_76 := int64(f3_2) * int64(f9_38) - f4f4 := int64(f4) * int64(f4) - f4f5_2 := int64(f4_2) * int64(f5) - f4f6_38 := int64(f4_2) * int64(f6_19) - f4f7_38 := int64(f4) * int64(f7_38) - f4f8_38 := int64(f4_2) * int64(f8_19) - f4f9_38 := int64(f4) * int64(f9_38) - f5f5_38 := int64(f5) * int64(f5_38) - f5f6_38 := int64(f5_2) * int64(f6_19) - f5f7_76 := int64(f5_2) * int64(f7_38) - f5f8_38 := int64(f5_2) * int64(f8_19) - f5f9_76 := int64(f5_2) * int64(f9_38) - f6f6_19 := int64(f6) * int64(f6_19) - f6f7_38 := int64(f6) * int64(f7_38) - f6f8_38 := int64(f6_2) * int64(f8_19) - f6f9_38 := int64(f6) * int64(f9_38) - f7f7_38 := int64(f7) * int64(f7_38) - f7f8_38 := int64(f7_2) * int64(f8_19) - f7f9_76 := int64(f7_2) * int64(f9_38) - f8f8_19 := int64(f8) * int64(f8_19) - f8f9_38 := int64(f8) * int64(f9_38) - f9f9_38 := int64(f9) * int64(f9_38) - h0 := f0f0 + f1f9_76 + f2f8_38 + f3f7_76 + f4f6_38 + f5f5_38 - h1 := f0f1_2 + f2f9_38 + f3f8_38 + f4f7_38 + f5f6_38 - h2 := f0f2_2 + f1f1_2 + f3f9_76 + f4f8_38 + f5f7_76 + f6f6_19 - h3 := f0f3_2 + f1f2_2 + f4f9_38 + f5f8_38 + f6f7_38 - h4 := f0f4_2 + f1f3_4 + f2f2 + f5f9_76 + f6f8_38 + f7f7_38 - h5 := f0f5_2 + f1f4_2 + f2f3_2 + f6f9_38 + f7f8_38 - h6 := f0f6_2 + f1f5_4 + f2f4_2 + f3f3_2 + f7f9_76 + f8f8_19 - h7 := f0f7_2 + f1f6_2 + f2f5_2 + f3f4_2 + f8f9_38 - h8 := f0f8_2 + f1f7_4 + f2f6_2 + f3f5_4 + f4f4 + f9f9_38 - h9 := f0f9_2 + f1f8_2 + f2f7_2 + f3f6_2 + f4f5_2 - var carry [10]int64 - - carry[0] = (h0 + (1 << 25)) >> 26 - h1 += carry[0] - h0 -= carry[0] << 26 - carry[4] = (h4 + (1 << 25)) >> 26 - h5 += carry[4] - h4 -= carry[4] << 26 - - carry[1] = (h1 + (1 << 24)) >> 25 - h2 += carry[1] - h1 -= carry[1] << 25 - carry[5] = (h5 + (1 << 24)) >> 25 - h6 += carry[5] - h5 -= carry[5] << 25 - - carry[2] = (h2 + (1 << 25)) >> 26 - h3 += carry[2] - h2 -= carry[2] << 26 - carry[6] = (h6 + (1 << 25)) >> 26 - h7 += carry[6] - h6 -= carry[6] << 26 - - carry[3] = (h3 + (1 << 24)) >> 25 - h4 += carry[3] - h3 -= carry[3] << 25 - carry[7] = (h7 + (1 << 24)) >> 25 - h8 += carry[7] - h7 -= carry[7] << 25 - - carry[4] = (h4 + (1 << 25)) >> 26 - h5 += carry[4] - h4 -= carry[4] << 26 - carry[8] = (h8 + (1 << 25)) >> 26 - h9 += carry[8] - h8 -= carry[8] << 26 - - carry[9] = (h9 + (1 << 24)) >> 25 - h0 += carry[9] * 19 - h9 -= carry[9] << 25 - - carry[0] = (h0 + (1 << 25)) >> 26 - h1 += carry[0] - h0 -= carry[0] << 26 - - h[0] = int32(h0) - h[1] = int32(h1) - h[2] = int32(h2) - h[3] = int32(h3) - h[4] = int32(h4) - h[5] = int32(h5) - h[6] = int32(h6) - h[7] = int32(h7) - h[8] = int32(h8) - h[9] = int32(h9) -} - -// feMul121666 calculates h = f * 121666. Can overlap h with f. -// -// Preconditions: -// |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. -// -// Postconditions: -// |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. -func feMul121666(h, f *fieldElement) { - h0 := int64(f[0]) * 121666 - h1 := int64(f[1]) * 121666 - h2 := int64(f[2]) * 121666 - h3 := int64(f[3]) * 121666 - h4 := int64(f[4]) * 121666 - h5 := int64(f[5]) * 121666 - h6 := int64(f[6]) * 121666 - h7 := int64(f[7]) * 121666 - h8 := int64(f[8]) * 121666 - h9 := int64(f[9]) * 121666 - var carry [10]int64 - - carry[9] = (h9 + (1 << 24)) >> 25 - h0 += carry[9] * 19 - h9 -= carry[9] << 25 - carry[1] = (h1 + (1 << 24)) >> 25 - h2 += carry[1] - h1 -= carry[1] << 25 - carry[3] = (h3 + (1 << 24)) >> 25 - h4 += carry[3] - h3 -= carry[3] << 25 - carry[5] = (h5 + (1 << 24)) >> 25 - h6 += carry[5] - h5 -= carry[5] << 25 - carry[7] = (h7 + (1 << 24)) >> 25 - h8 += carry[7] - h7 -= carry[7] << 25 - - carry[0] = (h0 + (1 << 25)) >> 26 - h1 += carry[0] - h0 -= carry[0] << 26 - carry[2] = (h2 + (1 << 25)) >> 26 - h3 += carry[2] - h2 -= carry[2] << 26 - carry[4] = (h4 + (1 << 25)) >> 26 - h5 += carry[4] - h4 -= carry[4] << 26 - carry[6] = (h6 + (1 << 25)) >> 26 - h7 += carry[6] - h6 -= carry[6] << 26 - carry[8] = (h8 + (1 << 25)) >> 26 - h9 += carry[8] - h8 -= carry[8] << 26 - - h[0] = int32(h0) - h[1] = int32(h1) - h[2] = int32(h2) - h[3] = int32(h3) - h[4] = int32(h4) - h[5] = int32(h5) - h[6] = int32(h6) - h[7] = int32(h7) - h[8] = int32(h8) - h[9] = int32(h9) -} - -// feInvert sets out = z^-1. -func feInvert(out, z *fieldElement) { - var t0, t1, t2, t3 fieldElement - var i int - - feSquare(&t0, z) - for i = 1; i < 1; i++ { - feSquare(&t0, &t0) - } - feSquare(&t1, &t0) - for i = 1; i < 2; i++ { - feSquare(&t1, &t1) - } - feMul(&t1, z, &t1) - feMul(&t0, &t0, &t1) - feSquare(&t2, &t0) - for i = 1; i < 1; i++ { - feSquare(&t2, &t2) - } - feMul(&t1, &t1, &t2) - feSquare(&t2, &t1) - for i = 1; i < 5; i++ { - feSquare(&t2, &t2) - } - feMul(&t1, &t2, &t1) - feSquare(&t2, &t1) - for i = 1; i < 10; i++ { - feSquare(&t2, &t2) - } - feMul(&t2, &t2, &t1) - feSquare(&t3, &t2) - for i = 1; i < 20; i++ { - feSquare(&t3, &t3) - } - feMul(&t2, &t3, &t2) - feSquare(&t2, &t2) - for i = 1; i < 10; i++ { - feSquare(&t2, &t2) - } - feMul(&t1, &t2, &t1) - feSquare(&t2, &t1) - for i = 1; i < 50; i++ { - feSquare(&t2, &t2) - } - feMul(&t2, &t2, &t1) - feSquare(&t3, &t2) - for i = 1; i < 100; i++ { - feSquare(&t3, &t3) - } - feMul(&t2, &t3, &t2) - feSquare(&t2, &t2) - for i = 1; i < 50; i++ { - feSquare(&t2, &t2) - } - feMul(&t1, &t2, &t1) - feSquare(&t1, &t1) - for i = 1; i < 5; i++ { - feSquare(&t1, &t1) - } - feMul(out, &t1, &t0) -} - -func scalarMult(out, in, base *[32]byte) { - var e [32]byte - - copy(e[:], in[:]) - e[0] &= 248 - e[31] &= 127 - e[31] |= 64 - - var x1, x2, z2, x3, z3, tmp0, tmp1 fieldElement - feFromBytes(&x1, base) - feOne(&x2) - feCopy(&x3, &x1) - feOne(&z3) - - swap := int32(0) - for pos := 254; pos >= 0; pos-- { - b := e[pos/8] >> uint(pos&7) - b &= 1 - swap ^= int32(b) - feCSwap(&x2, &x3, swap) - feCSwap(&z2, &z3, swap) - swap = int32(b) - - feSub(&tmp0, &x3, &z3) - feSub(&tmp1, &x2, &z2) - feAdd(&x2, &x2, &z2) - feAdd(&z2, &x3, &z3) - feMul(&z3, &tmp0, &x2) - feMul(&z2, &z2, &tmp1) - feSquare(&tmp0, &tmp1) - feSquare(&tmp1, &x2) - feAdd(&x3, &z3, &z2) - feSub(&z2, &z3, &z2) - feMul(&x2, &tmp1, &tmp0) - feSub(&tmp1, &tmp1, &tmp0) - feSquare(&z2, &z2) - feMul121666(&z3, &tmp1) - feSquare(&x3, &x3) - feAdd(&tmp0, &tmp0, &z3) - feMul(&z3, &x1, &z2) - feMul(&z2, &tmp1, &tmp0) - } - - feCSwap(&x2, &x3, swap) - feCSwap(&z2, &z3, swap) - - feInvert(&z2, &z2) - feMul(&x2, &x2, &z2) - feToBytes(out, &x2) -} diff --git a/vendor/golang.org/x/crypto/curve25519/curve25519_test.go b/vendor/golang.org/x/crypto/curve25519/curve25519_test.go deleted file mode 100644 index 14b0ee8..0000000 --- a/vendor/golang.org/x/crypto/curve25519/curve25519_test.go +++ /dev/null @@ -1,29 +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. - -package curve25519 - -import ( - "fmt" - "testing" -) - -const expectedHex = "89161fde887b2b53de549af483940106ecc114d6982daa98256de23bdf77661a" - -func TestBaseScalarMult(t *testing.T) { - var a, b [32]byte - in := &a - out := &b - a[0] = 1 - - for i := 0; i < 200; i++ { - ScalarBaseMult(out, in) - in, out = out, in - } - - result := fmt.Sprintf("%x", in[:]) - if result != expectedHex { - t.Errorf("incorrect result: got %s, want %s", result, expectedHex) - } -} diff --git a/vendor/golang.org/x/crypto/curve25519/doc.go b/vendor/golang.org/x/crypto/curve25519/doc.go deleted file mode 100644 index ebeea3c..0000000 --- a/vendor/golang.org/x/crypto/curve25519/doc.go +++ /dev/null @@ -1,23 +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. - -// Package curve25519 provides an implementation of scalar multiplication on -// the elliptic curve known as curve25519. See http://cr.yp.to/ecdh.html -package curve25519 // import "golang.org/x/crypto/curve25519" - -// basePoint is the x coordinate of the generator of the curve. -var basePoint = [32]byte{9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - -// ScalarMult sets dst to the product in*base where dst and base are the x -// coordinates of group points and all values are in little-endian form. -func ScalarMult(dst, in, base *[32]byte) { - scalarMult(dst, in, base) -} - -// ScalarBaseMult sets dst to the product in*base where dst and base are the x -// coordinates of group points, base is the standard generator and all values -// are in little-endian form. -func ScalarBaseMult(dst, in *[32]byte) { - ScalarMult(dst, in, &basePoint) -} diff --git a/vendor/golang.org/x/crypto/curve25519/freeze_amd64.s b/vendor/golang.org/x/crypto/curve25519/freeze_amd64.s deleted file mode 100644 index 37599fa..0000000 --- a/vendor/golang.org/x/crypto/curve25519/freeze_amd64.s +++ /dev/null @@ -1,94 +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: http://bench.cr.yp.to/supercop.html - -// +build amd64,!gccgo,!appengine - -// func freeze(inout *[5]uint64) -TEXT ·freeze(SB),7,$96-8 - MOVQ inout+0(FP), DI - - MOVQ SP,R11 - MOVQ $31,CX - NOTQ CX - ANDQ CX,SP - ADDQ $32,SP - - MOVQ R11,0(SP) - MOVQ R12,8(SP) - MOVQ R13,16(SP) - MOVQ R14,24(SP) - MOVQ R15,32(SP) - MOVQ BX,40(SP) - MOVQ BP,48(SP) - MOVQ 0(DI),SI - MOVQ 8(DI),DX - MOVQ 16(DI),CX - MOVQ 24(DI),R8 - MOVQ 32(DI),R9 - MOVQ ·REDMASK51(SB),AX - MOVQ AX,R10 - SUBQ $18,R10 - MOVQ $3,R11 -REDUCELOOP: - MOVQ SI,R12 - SHRQ $51,R12 - ANDQ AX,SI - ADDQ R12,DX - MOVQ DX,R12 - SHRQ $51,R12 - ANDQ AX,DX - ADDQ R12,CX - MOVQ CX,R12 - SHRQ $51,R12 - ANDQ AX,CX - ADDQ R12,R8 - MOVQ R8,R12 - SHRQ $51,R12 - ANDQ AX,R8 - ADDQ R12,R9 - MOVQ R9,R12 - SHRQ $51,R12 - ANDQ AX,R9 - IMUL3Q $19,R12,R12 - ADDQ R12,SI - SUBQ $1,R11 - JA REDUCELOOP - MOVQ $1,R12 - CMPQ R10,SI - CMOVQLT R11,R12 - CMPQ AX,DX - CMOVQNE R11,R12 - CMPQ AX,CX - CMOVQNE R11,R12 - CMPQ AX,R8 - CMOVQNE R11,R12 - CMPQ AX,R9 - CMOVQNE R11,R12 - NEGQ R12 - ANDQ R12,AX - ANDQ R12,R10 - SUBQ R10,SI - SUBQ AX,DX - SUBQ AX,CX - SUBQ AX,R8 - SUBQ AX,R9 - MOVQ SI,0(DI) - MOVQ DX,8(DI) - MOVQ CX,16(DI) - MOVQ R8,24(DI) - MOVQ R9,32(DI) - MOVQ 0(SP),R11 - MOVQ 8(SP),R12 - MOVQ 16(SP),R13 - MOVQ 24(SP),R14 - MOVQ 32(SP),R15 - MOVQ 40(SP),BX - MOVQ 48(SP),BP - MOVQ R11,SP - MOVQ DI,AX - MOVQ SI,DX - RET diff --git a/vendor/golang.org/x/crypto/curve25519/ladderstep_amd64.s b/vendor/golang.org/x/crypto/curve25519/ladderstep_amd64.s deleted file mode 100644 index 3949f9c..0000000 --- a/vendor/golang.org/x/crypto/curve25519/ladderstep_amd64.s +++ /dev/null @@ -1,1398 +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: http://bench.cr.yp.to/supercop.html - -// +build amd64,!gccgo,!appengine - -// func ladderstep(inout *[5][5]uint64) -TEXT ·ladderstep(SB),0,$384-8 - MOVQ inout+0(FP),DI - - MOVQ SP,R11 - MOVQ $31,CX - NOTQ CX - ANDQ CX,SP - ADDQ $32,SP - - MOVQ R11,0(SP) - MOVQ R12,8(SP) - MOVQ R13,16(SP) - MOVQ R14,24(SP) - MOVQ R15,32(SP) - MOVQ BX,40(SP) - MOVQ BP,48(SP) - MOVQ 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,56(SP) - MOVQ DX,64(SP) - MOVQ CX,72(SP) - MOVQ R8,80(SP) - MOVQ R9,88(SP) - MOVQ AX,96(SP) - MOVQ R10,104(SP) - MOVQ R11,112(SP) - MOVQ R12,120(SP) - MOVQ R13,128(SP) - MOVQ 96(SP),AX - MULQ 96(SP) - MOVQ AX,SI - MOVQ DX,CX - MOVQ 96(SP),AX - SHLQ $1,AX - MULQ 104(SP) - MOVQ AX,R8 - MOVQ DX,R9 - MOVQ 96(SP),AX - SHLQ $1,AX - MULQ 112(SP) - MOVQ AX,R10 - MOVQ DX,R11 - MOVQ 96(SP),AX - SHLQ $1,AX - MULQ 120(SP) - MOVQ AX,R12 - MOVQ DX,R13 - MOVQ 96(SP),AX - SHLQ $1,AX - MULQ 128(SP) - MOVQ AX,R14 - MOVQ DX,R15 - MOVQ 104(SP),AX - MULQ 104(SP) - ADDQ AX,R10 - ADCQ DX,R11 - MOVQ 104(SP),AX - SHLQ $1,AX - MULQ 112(SP) - ADDQ AX,R12 - ADCQ DX,R13 - MOVQ 104(SP),AX - SHLQ $1,AX - MULQ 120(SP) - ADDQ AX,R14 - ADCQ DX,R15 - MOVQ 104(SP),DX - IMUL3Q $38,DX,AX - MULQ 128(SP) - ADDQ AX,SI - ADCQ DX,CX - MOVQ 112(SP),AX - MULQ 112(SP) - ADDQ AX,R14 - ADCQ DX,R15 - MOVQ 112(SP),DX - IMUL3Q $38,DX,AX - MULQ 120(SP) - ADDQ AX,SI - ADCQ DX,CX - MOVQ 112(SP),DX - IMUL3Q $38,DX,AX - MULQ 128(SP) - ADDQ AX,R8 - ADCQ DX,R9 - MOVQ 120(SP),DX - IMUL3Q $19,DX,AX - MULQ 120(SP) - ADDQ AX,R8 - ADCQ DX,R9 - MOVQ 120(SP),DX - IMUL3Q $38,DX,AX - MULQ 128(SP) - ADDQ AX,R10 - ADCQ DX,R11 - MOVQ 128(SP),DX - IMUL3Q $19,DX,AX - MULQ 128(SP) - ADDQ AX,R12 - ADCQ DX,R13 - MOVQ ·REDMASK51(SB),DX - SHLQ $13,CX:SI - ANDQ DX,SI - SHLQ $13,R9:R8 - ANDQ DX,R8 - ADDQ CX,R8 - SHLQ $13,R11:R10 - ANDQ DX,R10 - ADDQ R9,R10 - SHLQ $13,R13:R12 - ANDQ DX,R12 - ADDQ R11,R12 - SHLQ $13,R15:R14 - 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,136(SP) - MOVQ R8,144(SP) - MOVQ R9,152(SP) - MOVQ AX,160(SP) - MOVQ R10,168(SP) - MOVQ 56(SP),AX - MULQ 56(SP) - MOVQ AX,SI - MOVQ DX,CX - MOVQ 56(SP),AX - SHLQ $1,AX - MULQ 64(SP) - MOVQ AX,R8 - MOVQ DX,R9 - MOVQ 56(SP),AX - SHLQ $1,AX - MULQ 72(SP) - MOVQ AX,R10 - MOVQ DX,R11 - MOVQ 56(SP),AX - SHLQ $1,AX - MULQ 80(SP) - MOVQ AX,R12 - MOVQ DX,R13 - MOVQ 56(SP),AX - SHLQ $1,AX - MULQ 88(SP) - MOVQ AX,R14 - MOVQ DX,R15 - MOVQ 64(SP),AX - MULQ 64(SP) - ADDQ AX,R10 - ADCQ DX,R11 - MOVQ 64(SP),AX - SHLQ $1,AX - MULQ 72(SP) - ADDQ AX,R12 - ADCQ DX,R13 - MOVQ 64(SP),AX - SHLQ $1,AX - MULQ 80(SP) - ADDQ AX,R14 - ADCQ DX,R15 - MOVQ 64(SP),DX - IMUL3Q $38,DX,AX - MULQ 88(SP) - ADDQ AX,SI - ADCQ DX,CX - MOVQ 72(SP),AX - MULQ 72(SP) - ADDQ AX,R14 - ADCQ DX,R15 - MOVQ 72(SP),DX - IMUL3Q $38,DX,AX - MULQ 80(SP) - ADDQ AX,SI - ADCQ DX,CX - MOVQ 72(SP),DX - IMUL3Q $38,DX,AX - MULQ 88(SP) - ADDQ AX,R8 - ADCQ DX,R9 - MOVQ 80(SP),DX - IMUL3Q $19,DX,AX - MULQ 80(SP) - ADDQ AX,R8 - ADCQ DX,R9 - MOVQ 80(SP),DX - IMUL3Q $38,DX,AX - MULQ 88(SP) - ADDQ AX,R10 - ADCQ DX,R11 - MOVQ 88(SP),DX - IMUL3Q $19,DX,AX - MULQ 88(SP) - ADDQ AX,R12 - ADCQ DX,R13 - MOVQ ·REDMASK51(SB),DX - SHLQ $13,CX:SI - ANDQ DX,SI - SHLQ $13,R9:R8 - ANDQ DX,R8 - ADDQ CX,R8 - SHLQ $13,R11:R10 - ANDQ DX,R10 - ADDQ R9,R10 - SHLQ $13,R13:R12 - ANDQ DX,R12 - ADDQ R11,R12 - SHLQ $13,R15:R14 - 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,176(SP) - MOVQ R8,184(SP) - MOVQ R9,192(SP) - MOVQ AX,200(SP) - MOVQ R10,208(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 136(SP),SI - SUBQ 144(SP),DX - SUBQ 152(SP),CX - SUBQ 160(SP),R8 - SUBQ 168(SP),R9 - MOVQ SI,216(SP) - MOVQ DX,224(SP) - MOVQ CX,232(SP) - MOVQ R8,240(SP) - MOVQ R9,248(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,256(SP) - MOVQ DX,264(SP) - MOVQ CX,272(SP) - MOVQ R8,280(SP) - MOVQ R9,288(SP) - MOVQ AX,296(SP) - MOVQ R10,304(SP) - MOVQ R11,312(SP) - MOVQ R12,320(SP) - MOVQ R13,328(SP) - MOVQ 280(SP),SI - IMUL3Q $19,SI,AX - MOVQ AX,336(SP) - MULQ 112(SP) - MOVQ AX,SI - MOVQ DX,CX - MOVQ 288(SP),DX - IMUL3Q $19,DX,AX - MOVQ AX,344(SP) - MULQ 104(SP) - ADDQ AX,SI - ADCQ DX,CX - MOVQ 256(SP),AX - MULQ 96(SP) - ADDQ AX,SI - ADCQ DX,CX - MOVQ 256(SP),AX - MULQ 104(SP) - MOVQ AX,R8 - MOVQ DX,R9 - MOVQ 256(SP),AX - MULQ 112(SP) - MOVQ AX,R10 - MOVQ DX,R11 - MOVQ 256(SP),AX - MULQ 120(SP) - MOVQ AX,R12 - MOVQ DX,R13 - MOVQ 256(SP),AX - MULQ 128(SP) - MOVQ AX,R14 - MOVQ DX,R15 - MOVQ 264(SP),AX - MULQ 96(SP) - ADDQ AX,R8 - ADCQ DX,R9 - MOVQ 264(SP),AX - MULQ 104(SP) - ADDQ AX,R10 - ADCQ DX,R11 - MOVQ 264(SP),AX - MULQ 112(SP) - ADDQ AX,R12 - ADCQ DX,R13 - MOVQ 264(SP),AX - MULQ 120(SP) - ADDQ AX,R14 - ADCQ DX,R15 - MOVQ 264(SP),DX - IMUL3Q $19,DX,AX - MULQ 128(SP) - ADDQ AX,SI - ADCQ DX,CX - MOVQ 272(SP),AX - MULQ 96(SP) - ADDQ AX,R10 - ADCQ DX,R11 - MOVQ 272(SP),AX - MULQ 104(SP) - ADDQ AX,R12 - ADCQ DX,R13 - MOVQ 272(SP),AX - MULQ 112(SP) - ADDQ AX,R14 - ADCQ DX,R15 - MOVQ 272(SP),DX - IMUL3Q $19,DX,AX - MULQ 120(SP) - ADDQ AX,SI - ADCQ DX,CX - MOVQ 272(SP),DX - IMUL3Q $19,DX,AX - MULQ 128(SP) - ADDQ AX,R8 - ADCQ DX,R9 - MOVQ 280(SP),AX - MULQ 96(SP) - ADDQ AX,R12 - ADCQ DX,R13 - MOVQ 280(SP),AX - MULQ 104(SP) - ADDQ AX,R14 - ADCQ DX,R15 - MOVQ 336(SP),AX - MULQ 120(SP) - ADDQ AX,R8 - ADCQ DX,R9 - MOVQ 336(SP),AX - MULQ 128(SP) - ADDQ AX,R10 - ADCQ DX,R11 - MOVQ 288(SP),AX - MULQ 96(SP) - ADDQ AX,R14 - ADCQ DX,R15 - MOVQ 344(SP),AX - MULQ 112(SP) - ADDQ AX,R8 - ADCQ DX,R9 - MOVQ 344(SP),AX - MULQ 120(SP) - ADDQ AX,R10 - ADCQ DX,R11 - MOVQ 344(SP),AX - MULQ 128(SP) - ADDQ AX,R12 - ADCQ DX,R13 - MOVQ ·REDMASK51(SB),DX - SHLQ $13,CX:SI - ANDQ DX,SI - SHLQ $13,R9:R8 - ANDQ DX,R8 - ADDQ CX,R8 - SHLQ $13,R11:R10 - ANDQ DX,R10 - ADDQ R9,R10 - SHLQ $13,R13:R12 - ANDQ DX,R12 - ADDQ R11,R12 - SHLQ $13,R15:R14 - 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,96(SP) - MOVQ R8,104(SP) - MOVQ R9,112(SP) - MOVQ AX,120(SP) - MOVQ R10,128(SP) - MOVQ 320(SP),SI - IMUL3Q $19,SI,AX - MOVQ AX,256(SP) - MULQ 72(SP) - MOVQ AX,SI - MOVQ DX,CX - MOVQ 328(SP),DX - IMUL3Q $19,DX,AX - MOVQ AX,264(SP) - MULQ 64(SP) - ADDQ AX,SI - ADCQ DX,CX - MOVQ 296(SP),AX - MULQ 56(SP) - ADDQ AX,SI - ADCQ DX,CX - MOVQ 296(SP),AX - MULQ 64(SP) - MOVQ AX,R8 - MOVQ DX,R9 - MOVQ 296(SP),AX - MULQ 72(SP) - MOVQ AX,R10 - MOVQ DX,R11 - MOVQ 296(SP),AX - MULQ 80(SP) - MOVQ AX,R12 - MOVQ DX,R13 - MOVQ 296(SP),AX - MULQ 88(SP) - MOVQ AX,R14 - MOVQ DX,R15 - MOVQ 304(SP),AX - MULQ 56(SP) - ADDQ AX,R8 - ADCQ DX,R9 - MOVQ 304(SP),AX - MULQ 64(SP) - ADDQ AX,R10 - ADCQ DX,R11 - MOVQ 304(SP),AX - MULQ 72(SP) - ADDQ AX,R12 - ADCQ DX,R13 - MOVQ 304(SP),AX - MULQ 80(SP) - ADDQ AX,R14 - ADCQ DX,R15 - MOVQ 304(SP),DX - IMUL3Q $19,DX,AX - MULQ 88(SP) - ADDQ AX,SI - ADCQ DX,CX - MOVQ 312(SP),AX - MULQ 56(SP) - ADDQ AX,R10 - ADCQ DX,R11 - MOVQ 312(SP),AX - MULQ 64(SP) - ADDQ AX,R12 - ADCQ DX,R13 - MOVQ 312(SP),AX - MULQ 72(SP) - ADDQ AX,R14 - ADCQ DX,R15 - MOVQ 312(SP),DX - IMUL3Q $19,DX,AX - MULQ 80(SP) - ADDQ AX,SI - ADCQ DX,CX - MOVQ 312(SP),DX - IMUL3Q $19,DX,AX - MULQ 88(SP) - ADDQ AX,R8 - ADCQ DX,R9 - MOVQ 320(SP),AX - MULQ 56(SP) - ADDQ AX,R12 - ADCQ DX,R13 - MOVQ 320(SP),AX - MULQ 64(SP) - ADDQ AX,R14 - ADCQ DX,R15 - MOVQ 256(SP),AX - MULQ 80(SP) - ADDQ AX,R8 - ADCQ DX,R9 - MOVQ 256(SP),AX - MULQ 88(SP) - ADDQ AX,R10 - ADCQ DX,R11 - MOVQ 328(SP),AX - MULQ 56(SP) - ADDQ AX,R14 - ADCQ DX,R15 - MOVQ 264(SP),AX - MULQ 72(SP) - ADDQ AX,R8 - ADCQ DX,R9 - MOVQ 264(SP),AX - MULQ 80(SP) - ADDQ AX,R10 - ADCQ DX,R11 - MOVQ 264(SP),AX - MULQ 88(SP) - ADDQ AX,R12 - ADCQ DX,R13 - MOVQ ·REDMASK51(SB),DX - SHLQ $13,CX:SI - ANDQ DX,SI - SHLQ $13,R9:R8 - ANDQ DX,R8 - ADDQ CX,R8 - SHLQ $13,R11:R10 - ANDQ DX,R10 - ADDQ R9,R10 - SHLQ $13,R13:R12 - ANDQ DX,R12 - ADDQ R11,R12 - SHLQ $13,R15:R14 - 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 96(SP),SI - ADDQ 104(SP),R8 - ADDQ 112(SP),R9 - ADDQ 120(SP),AX - ADDQ 128(SP),R10 - SUBQ 96(SP),DX - SUBQ 104(SP),CX - SUBQ 112(SP),R11 - SUBQ 120(SP),R12 - SUBQ 128(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(SB),DX - SHLQ $13,CX:SI - ANDQ DX,SI - SHLQ $13,R9:R8 - ANDQ DX,R8 - ADDQ CX,R8 - SHLQ $13,R11:R10 - ANDQ DX,R10 - ADDQ R9,R10 - SHLQ $13,R13:R12 - ANDQ DX,R12 - ADDQ R11,R12 - SHLQ $13,R15:R14 - 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(SB),DX - SHLQ $13,CX:SI - ANDQ DX,SI - SHLQ $13,R9:R8 - ANDQ DX,R8 - ADDQ CX,R8 - SHLQ $13,R11:R10 - ANDQ DX,R10 - ADDQ R9,R10 - SHLQ $13,R13:R12 - ANDQ DX,R12 - ADDQ R11,R12 - SHLQ $13,R15:R14 - 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,56(SP) - MULQ 16(DI) - MOVQ AX,SI - MOVQ DX,CX - MOVQ 192(DI),DX - IMUL3Q $19,DX,AX - MOVQ AX,64(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 56(SP),AX - MULQ 24(DI) - ADDQ AX,R8 - ADCQ DX,R9 - MOVQ 56(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 64(SP),AX - MULQ 16(DI) - ADDQ AX,R8 - ADCQ DX,R9 - MOVQ 64(SP),AX - MULQ 24(DI) - ADDQ AX,R10 - ADCQ DX,R11 - MOVQ 64(SP),AX - MULQ 32(DI) - ADDQ AX,R12 - ADCQ DX,R13 - MOVQ ·REDMASK51(SB),DX - SHLQ $13,CX:SI - ANDQ DX,SI - SHLQ $13,R9:R8 - ANDQ DX,R8 - ADDQ CX,R8 - SHLQ $13,R11:R10 - ANDQ DX,R10 - ADDQ R9,R10 - SHLQ $13,R13:R12 - ANDQ DX,R12 - ADDQ R11,R12 - SHLQ $13,R15:R14 - 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 200(SP),SI - IMUL3Q $19,SI,AX - MOVQ AX,56(SP) - MULQ 152(SP) - MOVQ AX,SI - MOVQ DX,CX - MOVQ 208(SP),DX - IMUL3Q $19,DX,AX - MOVQ AX,64(SP) - MULQ 144(SP) - ADDQ AX,SI - ADCQ DX,CX - MOVQ 176(SP),AX - MULQ 136(SP) - ADDQ AX,SI - ADCQ DX,CX - MOVQ 176(SP),AX - MULQ 144(SP) - MOVQ AX,R8 - MOVQ DX,R9 - MOVQ 176(SP),AX - MULQ 152(SP) - MOVQ AX,R10 - MOVQ DX,R11 - MOVQ 176(SP),AX - MULQ 160(SP) - MOVQ AX,R12 - MOVQ DX,R13 - MOVQ 176(SP),AX - MULQ 168(SP) - MOVQ AX,R14 - MOVQ DX,R15 - MOVQ 184(SP),AX - MULQ 136(SP) - ADDQ AX,R8 - ADCQ DX,R9 - MOVQ 184(SP),AX - MULQ 144(SP) - ADDQ AX,R10 - ADCQ DX,R11 - MOVQ 184(SP),AX - MULQ 152(SP) - ADDQ AX,R12 - ADCQ DX,R13 - MOVQ 184(SP),AX - MULQ 160(SP) - ADDQ AX,R14 - ADCQ DX,R15 - MOVQ 184(SP),DX - IMUL3Q $19,DX,AX - MULQ 168(SP) - ADDQ AX,SI - ADCQ DX,CX - MOVQ 192(SP),AX - MULQ 136(SP) - ADDQ AX,R10 - ADCQ DX,R11 - MOVQ 192(SP),AX - MULQ 144(SP) - ADDQ AX,R12 - ADCQ DX,R13 - MOVQ 192(SP),AX - MULQ 152(SP) - ADDQ AX,R14 - ADCQ DX,R15 - MOVQ 192(SP),DX - IMUL3Q $19,DX,AX - MULQ 160(SP) - ADDQ AX,SI - ADCQ DX,CX - MOVQ 192(SP),DX - IMUL3Q $19,DX,AX - MULQ 168(SP) - ADDQ AX,R8 - ADCQ DX,R9 - MOVQ 200(SP),AX - MULQ 136(SP) - ADDQ AX,R12 - ADCQ DX,R13 - MOVQ 200(SP),AX - MULQ 144(SP) - ADDQ AX,R14 - ADCQ DX,R15 - MOVQ 56(SP),AX - MULQ 160(SP) - ADDQ AX,R8 - ADCQ DX,R9 - MOVQ 56(SP),AX - MULQ 168(SP) - ADDQ AX,R10 - ADCQ DX,R11 - MOVQ 208(SP),AX - MULQ 136(SP) - ADDQ AX,R14 - ADCQ DX,R15 - MOVQ 64(SP),AX - MULQ 152(SP) - ADDQ AX,R8 - ADCQ DX,R9 - MOVQ 64(SP),AX - MULQ 160(SP) - ADDQ AX,R10 - ADCQ DX,R11 - MOVQ 64(SP),AX - MULQ 168(SP) - ADDQ AX,R12 - ADCQ DX,R13 - MOVQ ·REDMASK51(SB),DX - SHLQ $13,CX:SI - ANDQ DX,SI - SHLQ $13,R9:R8 - ANDQ DX,R8 - ADDQ CX,R8 - SHLQ $13,R11:R10 - ANDQ DX,R10 - ADDQ R9,R10 - SHLQ $13,R13:R12 - ANDQ DX,R12 - ADDQ R11,R12 - SHLQ $13,R15:R14 - 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 216(SP),AX - MULQ ·_121666_213(SB) - SHRQ $13,AX - MOVQ AX,SI - MOVQ DX,CX - MOVQ 224(SP),AX - MULQ ·_121666_213(SB) - SHRQ $13,AX - ADDQ AX,CX - MOVQ DX,R8 - MOVQ 232(SP),AX - MULQ ·_121666_213(SB) - SHRQ $13,AX - ADDQ AX,R8 - MOVQ DX,R9 - MOVQ 240(SP),AX - MULQ ·_121666_213(SB) - SHRQ $13,AX - ADDQ AX,R9 - MOVQ DX,R10 - MOVQ 248(SP),AX - MULQ ·_121666_213(SB) - SHRQ $13,AX - ADDQ AX,R10 - IMUL3Q $19,DX,DX - ADDQ DX,SI - ADDQ 136(SP),SI - ADDQ 144(SP),CX - ADDQ 152(SP),R8 - ADDQ 160(SP),R9 - ADDQ 168(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,56(SP) - MULQ 232(SP) - MOVQ AX,SI - MOVQ DX,CX - MOVQ 112(DI),DX - IMUL3Q $19,DX,AX - MOVQ AX,64(SP) - MULQ 224(SP) - ADDQ AX,SI - ADCQ DX,CX - MOVQ 80(DI),AX - MULQ 216(SP) - ADDQ AX,SI - ADCQ DX,CX - MOVQ 80(DI),AX - MULQ 224(SP) - MOVQ AX,R8 - MOVQ DX,R9 - MOVQ 80(DI),AX - MULQ 232(SP) - MOVQ AX,R10 - MOVQ DX,R11 - MOVQ 80(DI),AX - MULQ 240(SP) - MOVQ AX,R12 - MOVQ DX,R13 - MOVQ 80(DI),AX - MULQ 248(SP) - MOVQ AX,R14 - MOVQ DX,R15 - MOVQ 88(DI),AX - MULQ 216(SP) - ADDQ AX,R8 - ADCQ DX,R9 - MOVQ 88(DI),AX - MULQ 224(SP) - ADDQ AX,R10 - ADCQ DX,R11 - MOVQ 88(DI),AX - MULQ 232(SP) - ADDQ AX,R12 - ADCQ DX,R13 - MOVQ 88(DI),AX - MULQ 240(SP) - ADDQ AX,R14 - ADCQ DX,R15 - MOVQ 88(DI),DX - IMUL3Q $19,DX,AX - MULQ 248(SP) - ADDQ AX,SI - ADCQ DX,CX - MOVQ 96(DI),AX - MULQ 216(SP) - ADDQ AX,R10 - ADCQ DX,R11 - MOVQ 96(DI),AX - MULQ 224(SP) - ADDQ AX,R12 - ADCQ DX,R13 - MOVQ 96(DI),AX - MULQ 232(SP) - ADDQ AX,R14 - ADCQ DX,R15 - MOVQ 96(DI),DX - IMUL3Q $19,DX,AX - MULQ 240(SP) - ADDQ AX,SI - ADCQ DX,CX - MOVQ 96(DI),DX - IMUL3Q $19,DX,AX - MULQ 248(SP) - ADDQ AX,R8 - ADCQ DX,R9 - MOVQ 104(DI),AX - MULQ 216(SP) - ADDQ AX,R12 - ADCQ DX,R13 - MOVQ 104(DI),AX - MULQ 224(SP) - ADDQ AX,R14 - ADCQ DX,R15 - MOVQ 56(SP),AX - MULQ 240(SP) - ADDQ AX,R8 - ADCQ DX,R9 - MOVQ 56(SP),AX - MULQ 248(SP) - ADDQ AX,R10 - ADCQ DX,R11 - MOVQ 112(DI),AX - MULQ 216(SP) - ADDQ AX,R14 - ADCQ DX,R15 - MOVQ 64(SP),AX - MULQ 232(SP) - ADDQ AX,R8 - ADCQ DX,R9 - MOVQ 64(SP),AX - MULQ 240(SP) - ADDQ AX,R10 - ADCQ DX,R11 - MOVQ 64(SP),AX - MULQ 248(SP) - ADDQ AX,R12 - ADCQ DX,R13 - MOVQ ·REDMASK51(SB),DX - SHLQ $13,CX:SI - ANDQ DX,SI - SHLQ $13,R9:R8 - ANDQ DX,R8 - ADDQ CX,R8 - SHLQ $13,R11:R10 - ANDQ DX,R10 - ADDQ R9,R10 - SHLQ $13,R13:R12 - ANDQ DX,R12 - ADDQ R11,R12 - SHLQ $13,R15:R14 - 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) - MOVQ 0(SP),R11 - MOVQ 8(SP),R12 - MOVQ 16(SP),R13 - MOVQ 24(SP),R14 - MOVQ 32(SP),R15 - MOVQ 40(SP),BX - MOVQ 48(SP),BP - MOVQ R11,SP - MOVQ DI,AX - MOVQ SI,DX - RET diff --git a/vendor/golang.org/x/crypto/curve25519/mont25519_amd64.go b/vendor/golang.org/x/crypto/curve25519/mont25519_amd64.go deleted file mode 100644 index 5822bd5..0000000 --- a/vendor/golang.org/x/crypto/curve25519/mont25519_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 - -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/mul_amd64.s b/vendor/golang.org/x/crypto/curve25519/mul_amd64.s deleted file mode 100644 index e48d183..0000000 --- a/vendor/golang.org/x/crypto/curve25519/mul_amd64.s +++ /dev/null @@ -1,191 +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: http://bench.cr.yp.to/supercop.html - -// +build amd64,!gccgo,!appengine - -// func mul(dest, a, b *[5]uint64) -TEXT ·mul(SB),0,$128-24 - MOVQ dest+0(FP), DI - MOVQ a+8(FP), SI - MOVQ b+16(FP), DX - - MOVQ SP,R11 - MOVQ $31,CX - NOTQ CX - ANDQ CX,SP - ADDQ $32,SP - - MOVQ R11,0(SP) - MOVQ R12,8(SP) - MOVQ R13,16(SP) - MOVQ R14,24(SP) - MOVQ R15,32(SP) - MOVQ BX,40(SP) - MOVQ BP,48(SP) - MOVQ DI,56(SP) - MOVQ DX,CX - MOVQ 24(SI),DX - IMUL3Q $19,DX,AX - MOVQ AX,64(SP) - MULQ 16(CX) - MOVQ AX,R8 - MOVQ DX,R9 - MOVQ 32(SI),DX - IMUL3Q $19,DX,AX - MOVQ AX,72(SP) - MULQ 8(CX) - ADDQ AX,R8 - ADCQ DX,R9 - MOVQ 0(SI),AX - MULQ 0(CX) - ADDQ AX,R8 - ADCQ DX,R9 - MOVQ 0(SI),AX - MULQ 8(CX) - MOVQ AX,R10 - MOVQ DX,R11 - MOVQ 0(SI),AX - MULQ 16(CX) - MOVQ AX,R12 - MOVQ DX,R13 - MOVQ 0(SI),AX - MULQ 24(CX) - MOVQ AX,R14 - MOVQ DX,R15 - MOVQ 0(SI),AX - MULQ 32(CX) - MOVQ AX,BX - MOVQ DX,BP - MOVQ 8(SI),AX - MULQ 0(CX) - ADDQ AX,R10 - ADCQ DX,R11 - MOVQ 8(SI),AX - MULQ 8(CX) - ADDQ AX,R12 - ADCQ DX,R13 - MOVQ 8(SI),AX - MULQ 16(CX) - ADDQ AX,R14 - ADCQ DX,R15 - MOVQ 8(SI),AX - MULQ 24(CX) - ADDQ AX,BX - ADCQ DX,BP - MOVQ 8(SI),DX - IMUL3Q $19,DX,AX - MULQ 32(CX) - ADDQ AX,R8 - ADCQ DX,R9 - MOVQ 16(SI),AX - MULQ 0(CX) - ADDQ AX,R12 - ADCQ DX,R13 - MOVQ 16(SI),AX - MULQ 8(CX) - ADDQ AX,R14 - ADCQ DX,R15 - MOVQ 16(SI),AX - MULQ 16(CX) - ADDQ AX,BX - ADCQ DX,BP - MOVQ 16(SI),DX - IMUL3Q $19,DX,AX - MULQ 24(CX) - ADDQ AX,R8 - ADCQ DX,R9 - MOVQ 16(SI),DX - IMUL3Q $19,DX,AX - MULQ 32(CX) - ADDQ AX,R10 - ADCQ DX,R11 - MOVQ 24(SI),AX - MULQ 0(CX) - ADDQ AX,R14 - ADCQ DX,R15 - MOVQ 24(SI),AX - MULQ 8(CX) - ADDQ AX,BX - ADCQ DX,BP - MOVQ 64(SP),AX - MULQ 24(CX) - ADDQ AX,R10 - ADCQ DX,R11 - MOVQ 64(SP),AX - MULQ 32(CX) - ADDQ AX,R12 - ADCQ DX,R13 - MOVQ 32(SI),AX - MULQ 0(CX) - ADDQ AX,BX - ADCQ DX,BP - MOVQ 72(SP),AX - MULQ 16(CX) - ADDQ AX,R10 - ADCQ DX,R11 - MOVQ 72(SP),AX - MULQ 24(CX) - ADDQ AX,R12 - ADCQ DX,R13 - MOVQ 72(SP),AX - MULQ 32(CX) - ADDQ AX,R14 - ADCQ DX,R15 - MOVQ ·REDMASK51(SB),SI - SHLQ $13,R9:R8 - ANDQ SI,R8 - SHLQ $13,R11:R10 - ANDQ SI,R10 - ADDQ R9,R10 - SHLQ $13,R13:R12 - ANDQ SI,R12 - ADDQ R11,R12 - SHLQ $13,R15:R14 - ANDQ SI,R14 - ADDQ R13,R14 - SHLQ $13,BP:BX - ANDQ SI,BX - ADDQ R15,BX - IMUL3Q $19,BP,DX - ADDQ DX,R8 - MOVQ R8,DX - SHRQ $51,DX - ADDQ R10,DX - MOVQ DX,CX - SHRQ $51,DX - ANDQ SI,R8 - ADDQ R12,DX - MOVQ DX,R9 - SHRQ $51,DX - ANDQ SI,CX - ADDQ R14,DX - MOVQ DX,AX - SHRQ $51,DX - ANDQ SI,R9 - ADDQ BX,DX - MOVQ DX,R10 - SHRQ $51,DX - ANDQ SI,AX - IMUL3Q $19,DX,DX - ADDQ DX,R8 - ANDQ SI,R10 - MOVQ R8,0(DI) - MOVQ CX,8(DI) - MOVQ R9,16(DI) - MOVQ AX,24(DI) - MOVQ R10,32(DI) - MOVQ 0(SP),R11 - MOVQ 8(SP),R12 - MOVQ 16(SP),R13 - MOVQ 24(SP),R14 - MOVQ 32(SP),R15 - MOVQ 40(SP),BX - MOVQ 48(SP),BP - MOVQ R11,SP - MOVQ DI,AX - MOVQ SI,DX - RET diff --git a/vendor/golang.org/x/crypto/curve25519/square_amd64.s b/vendor/golang.org/x/crypto/curve25519/square_amd64.s deleted file mode 100644 index 78d1a50..0000000 --- a/vendor/golang.org/x/crypto/curve25519/square_amd64.s +++ /dev/null @@ -1,153 +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: http://bench.cr.yp.to/supercop.html - -// +build amd64,!gccgo,!appengine - -// func square(out, in *[5]uint64) -TEXT ·square(SB),7,$96-16 - MOVQ out+0(FP), DI - MOVQ in+8(FP), SI - - MOVQ SP,R11 - MOVQ $31,CX - NOTQ CX - ANDQ CX,SP - ADDQ $32, SP - - MOVQ R11,0(SP) - MOVQ R12,8(SP) - MOVQ R13,16(SP) - MOVQ R14,24(SP) - MOVQ R15,32(SP) - MOVQ BX,40(SP) - MOVQ BP,48(SP) - MOVQ 0(SI),AX - MULQ 0(SI) - MOVQ AX,CX - MOVQ DX,R8 - MOVQ 0(SI),AX - SHLQ $1,AX - MULQ 8(SI) - MOVQ AX,R9 - MOVQ DX,R10 - MOVQ 0(SI),AX - SHLQ $1,AX - MULQ 16(SI) - MOVQ AX,R11 - MOVQ DX,R12 - MOVQ 0(SI),AX - SHLQ $1,AX - MULQ 24(SI) - MOVQ AX,R13 - MOVQ DX,R14 - MOVQ 0(SI),AX - SHLQ $1,AX - MULQ 32(SI) - MOVQ AX,R15 - MOVQ DX,BX - MOVQ 8(SI),AX - MULQ 8(SI) - ADDQ AX,R11 - ADCQ DX,R12 - MOVQ 8(SI),AX - SHLQ $1,AX - MULQ 16(SI) - ADDQ AX,R13 - ADCQ DX,R14 - MOVQ 8(SI),AX - SHLQ $1,AX - MULQ 24(SI) - ADDQ AX,R15 - ADCQ DX,BX - MOVQ 8(SI),DX - IMUL3Q $38,DX,AX - MULQ 32(SI) - ADDQ AX,CX - ADCQ DX,R8 - MOVQ 16(SI),AX - MULQ 16(SI) - ADDQ AX,R15 - ADCQ DX,BX - MOVQ 16(SI),DX - IMUL3Q $38,DX,AX - MULQ 24(SI) - ADDQ AX,CX - ADCQ DX,R8 - MOVQ 16(SI),DX - IMUL3Q $38,DX,AX - MULQ 32(SI) - ADDQ AX,R9 - ADCQ DX,R10 - MOVQ 24(SI),DX - IMUL3Q $19,DX,AX - MULQ 24(SI) - ADDQ AX,R9 - ADCQ DX,R10 - MOVQ 24(SI),DX - IMUL3Q $38,DX,AX - MULQ 32(SI) - ADDQ AX,R11 - ADCQ DX,R12 - MOVQ 32(SI),DX - IMUL3Q $19,DX,AX - MULQ 32(SI) - ADDQ AX,R13 - ADCQ DX,R14 - MOVQ ·REDMASK51(SB),SI - SHLQ $13,R8:CX - ANDQ SI,CX - SHLQ $13,R10:R9 - ANDQ SI,R9 - ADDQ R8,R9 - SHLQ $13,R12:R11 - ANDQ SI,R11 - ADDQ R10,R11 - SHLQ $13,R14:R13 - ANDQ SI,R13 - ADDQ R12,R13 - SHLQ $13,BX:R15 - ANDQ SI,R15 - ADDQ R14,R15 - IMUL3Q $19,BX,DX - ADDQ DX,CX - MOVQ CX,DX - SHRQ $51,DX - ADDQ R9,DX - ANDQ SI,CX - MOVQ DX,R8 - SHRQ $51,DX - ADDQ R11,DX - ANDQ SI,R8 - MOVQ DX,R9 - SHRQ $51,DX - ADDQ R13,DX - ANDQ SI,R9 - MOVQ DX,AX - SHRQ $51,DX - ADDQ R15,DX - ANDQ SI,AX - MOVQ DX,R10 - SHRQ $51,DX - IMUL3Q $19,DX,DX - ADDQ DX,CX - ANDQ SI,R10 - MOVQ CX,0(DI) - MOVQ R8,8(DI) - MOVQ R9,16(DI) - MOVQ AX,24(DI) - MOVQ R10,32(DI) - MOVQ 0(SP),R11 - MOVQ 8(SP),R12 - MOVQ 16(SP),R13 - MOVQ 24(SP),R14 - MOVQ 32(SP),R15 - MOVQ 40(SP),BX - MOVQ 48(SP),BP - MOVQ R11,SP - MOVQ DI,AX - MOVQ SI,DX - RET diff --git a/vendor/golang.org/x/crypto/ed25519/ed25519.go b/vendor/golang.org/x/crypto/ed25519/ed25519.go deleted file mode 100644 index f1d9567..0000000 --- a/vendor/golang.org/x/crypto/ed25519/ed25519.go +++ /dev/null @@ -1,181 +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 ed25519 implements the Ed25519 signature algorithm. See -// http://ed25519.cr.yp.to/. -// -// These functions are also compatible with the “Ed25519” function defined in -// https://tools.ietf.org/html/draft-irtf-cfrg-eddsa-05. -package ed25519 - -// This code is a port of the public domain, “ref10” implementation of ed25519 -// from SUPERCOP. - -import ( - "crypto" - cryptorand "crypto/rand" - "crypto/sha512" - "crypto/subtle" - "errors" - "io" - "strconv" - - "golang.org/x/crypto/ed25519/internal/edwards25519" -) - -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 -) - -// PublicKey is the type of Ed25519 public keys. -type PublicKey []byte - -// 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) -} - -// 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 -} - -// 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 PublicKey, privateKey PrivateKey, err error) { - if rand == nil { - rand = cryptorand.Reader - } - - privateKey = make([]byte, PrivateKeySize) - publicKey = make([]byte, PublicKeySize) - _, err = io.ReadFull(rand, privateKey[:32]) - if err != nil { - return nil, nil, err - } - - digest := sha512.Sum512(privateKey[:32]) - 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) - - copy(privateKey[32:], publicKeyBytes[:]) - copy(publicKey, publicKeyBytes[:]) - - return publicKey, privateKey, nil -} - -// 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 -} - -// 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 b [32]byte - copy(b[:], sig[32:]) - edwards25519.GeDoubleScalarMultVartime(&R, &hReduced, &A, &b) - - var checkR [32]byte - R.ToBytes(&checkR) - return subtle.ConstantTimeCompare(sig[:32], checkR[:]) == 1 -} diff --git a/vendor/golang.org/x/crypto/ed25519/ed25519_test.go b/vendor/golang.org/x/crypto/ed25519/ed25519_test.go deleted file mode 100644 index 638e525..0000000 --- a/vendor/golang.org/x/crypto/ed25519/ed25519_test.go +++ /dev/null @@ -1,183 +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 ed25519 - -import ( - "bufio" - "bytes" - "compress/gzip" - "crypto" - "crypto/rand" - "encoding/hex" - "os" - "strings" - "testing" - - "golang.org/x/crypto/ed25519/internal/edwards25519" -) - -type zeroReader struct{} - -func (zeroReader) Read(buf []byte) (int, error) { - for i := range buf { - buf[i] = 0 - } - return len(buf), nil -} - -func TestUnmarshalMarshal(t *testing.T) { - pub, _, _ := GenerateKey(rand.Reader) - - var A edwards25519.ExtendedGroupElement - var pubBytes [32]byte - copy(pubBytes[:], pub) - if !A.FromBytes(&pubBytes) { - t.Fatalf("ExtendedGroupElement.FromBytes failed") - } - - var pub2 [32]byte - A.ToBytes(&pub2) - - if pubBytes != pub2 { - t.Errorf("FromBytes(%v)->ToBytes does not round-trip, got %x\n", pubBytes, pub2) - } -} - -func TestSignVerify(t *testing.T) { - var zero zeroReader - public, private, _ := GenerateKey(zero) - - message := []byte("test message") - sig := Sign(private, message) - if !Verify(public, message, sig) { - t.Errorf("valid signature rejected") - } - - wrongMessage := []byte("wrong message") - if Verify(public, wrongMessage, sig) { - t.Errorf("signature of different message accepted") - } -} - -func TestCryptoSigner(t *testing.T) { - var zero zeroReader - public, private, _ := GenerateKey(zero) - - signer := crypto.Signer(private) - - publicInterface := signer.Public() - public2, ok := publicInterface.(PublicKey) - if !ok { - t.Fatalf("expected PublicKey from Public() but got %T", publicInterface) - } - - if !bytes.Equal(public, public2) { - t.Errorf("public keys do not match: original:%x vs Public():%x", public, public2) - } - - message := []byte("message") - var noHash crypto.Hash - signature, err := signer.Sign(zero, message, noHash) - if err != nil { - t.Fatalf("error from Sign(): %s", err) - } - - if !Verify(public, message, signature) { - t.Errorf("Verify failed on signature from Sign()") - } -} - -func TestGolden(t *testing.T) { - // sign.input.gz is a selection of test cases from - // http://ed25519.cr.yp.to/python/sign.input - testDataZ, err := os.Open("testdata/sign.input.gz") - if err != nil { - t.Fatal(err) - } - defer testDataZ.Close() - testData, err := gzip.NewReader(testDataZ) - if err != nil { - t.Fatal(err) - } - defer testData.Close() - - scanner := bufio.NewScanner(testData) - lineNo := 0 - - for scanner.Scan() { - lineNo++ - - line := scanner.Text() - parts := strings.Split(line, ":") - if len(parts) != 5 { - t.Fatalf("bad number of parts on line %d", lineNo) - } - - privBytes, _ := hex.DecodeString(parts[0]) - pubKey, _ := hex.DecodeString(parts[1]) - msg, _ := hex.DecodeString(parts[2]) - sig, _ := hex.DecodeString(parts[3]) - // The signatures in the test vectors also include the message - // at the end, but we just want R and S. - sig = sig[:SignatureSize] - - if l := len(pubKey); l != PublicKeySize { - t.Fatalf("bad public key length on line %d: got %d bytes", lineNo, l) - } - - var priv [PrivateKeySize]byte - copy(priv[:], privBytes) - copy(priv[32:], pubKey) - - sig2 := Sign(priv[:], msg) - if !bytes.Equal(sig, sig2[:]) { - t.Errorf("different signature result on line %d: %x vs %x", lineNo, sig, sig2) - } - - if !Verify(pubKey, msg, sig2) { - t.Errorf("signature failed to verify on line %d", lineNo) - } - } - - if err := scanner.Err(); err != nil { - t.Fatalf("error reading test data: %s", err) - } -} - -func BenchmarkKeyGeneration(b *testing.B) { - var zero zeroReader - for i := 0; i < b.N; i++ { - if _, _, err := GenerateKey(zero); err != nil { - b.Fatal(err) - } - } -} - -func BenchmarkSigning(b *testing.B) { - var zero zeroReader - _, priv, err := GenerateKey(zero) - if err != nil { - b.Fatal(err) - } - message := []byte("Hello, world!") - b.ResetTimer() - for i := 0; i < b.N; i++ { - Sign(priv, message) - } -} - -func BenchmarkVerification(b *testing.B) { - var zero zeroReader - pub, priv, err := GenerateKey(zero) - if err != nil { - b.Fatal(err) - } - message := []byte("Hello, world!") - signature := Sign(priv, message) - b.ResetTimer() - for i := 0; i < b.N; i++ { - Verify(pub, message, signature) - } -} 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 e39f086..0000000 --- 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 5f8b994..0000000 --- a/vendor/golang.org/x/crypto/ed25519/internal/edwards25519/edwards25519.go +++ /dev/null @@ -1,1771 +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 - -// 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> 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]<= -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) -} diff --git a/vendor/golang.org/x/crypto/ed25519/testdata/sign.input.gz b/vendor/golang.org/x/crypto/ed25519/testdata/sign.input.gz deleted file mode 100644 index 41030690c0db39a0279304a46f002a625caa9080..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 50330 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¤ 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 T!|y*De*gRjX1oxufGGk1?cM`* diff --git a/vendor/golang.org/x/crypto/hkdf/example_test.go b/vendor/golang.org/x/crypto/hkdf/example_test.go deleted file mode 100644 index df84395..0000000 --- a/vendor/golang.org/x/crypto/hkdf/example_test.go +++ /dev/null @@ -1,61 +0,0 @@ -// 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_test - -import ( - "bytes" - "crypto/rand" - "crypto/sha256" - "fmt" - "golang.org/x/crypto/hkdf" - "io" -) - -// Usage example that expands one master key into three other cryptographically -// secure keys. -func Example_usage() { - // Underlying hash function to use - hash := sha256.New - - // Cryptographically secure master key. - master := []byte{0x00, 0x01, 0x02, 0x03} // i.e. NOT this. - - // Non secret salt, optional (can be nil) - // Recommended: hash-length sized random - salt := make([]byte, hash().Size()) - n, err := io.ReadFull(rand.Reader, salt) - if n != len(salt) || err != nil { - fmt.Println("error:", err) - return - } - - // Non secret context specific info, optional (can be nil). - // Note, independent from the master key. - info := []byte{0x03, 0x14, 0x15, 0x92, 0x65} - - // Create the key derivation function - hkdf := hkdf.New(hash, master, salt, info) - - // Generate the required keys - keys := make([][]byte, 3) - for i := 0; i < len(keys); i++ { - keys[i] = make([]byte, 24) - n, err := io.ReadFull(hkdf, keys[i]) - if n != len(keys[i]) || err != nil { - fmt.Println("error:", err) - return - } - } - - // Keys should contain 192 bit random keys - for i := 1; i <= len(keys); i++ { - fmt.Printf("Key #%d: %v\n", i, !bytes.Equal(keys[i-1], make([]byte, 24))) - } - - // Output: - // Key #1: true - // Key #2: true - // Key #3: true -} diff --git a/vendor/golang.org/x/crypto/hkdf/hkdf.go b/vendor/golang.org/x/crypto/hkdf/hkdf.go deleted file mode 100644 index 5bc2463..0000000 --- a/vendor/golang.org/x/crypto/hkdf/hkdf.go +++ /dev/null @@ -1,75 +0,0 @@ -// 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. -// -// RFC 5869: https://tools.ietf.org/html/rfc5869 -package hkdf // import "golang.org/x/crypto/hkdf" - -import ( - "crypto/hmac" - "errors" - "hash" - "io" -) - -type hkdf struct { - expander hash.Hash - size int - - info []byte - counter byte - - prev []byte - cache []byte -} - -func (f *hkdf) Read(p []byte) (int, error) { - // Check whether enough data can be generated - need := len(p) - remains := len(f.cache) + int(255-f.counter+1)*f.size - if remains < need { - return 0, errors.New("hkdf: entropy limit reached") - } - // Read from the cache, if enough data is present - n := copy(p, f.cache) - p = p[n:] - - // Fill 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.cache = f.prev - n = copy(p, f.cache) - p = p[n:] - } - // Save leftovers for next run - f.cache = f.cache[n:] - - return need, nil -} - -// New returns a new HKDF using the given hash, the secret keying material to expand -// and optional salt and info fields. -func New(hash func() hash.Hash, secret, salt, info []byte) io.Reader { - if salt == nil { - salt = make([]byte, hash().Size()) - } - extractor := hmac.New(hash, salt) - extractor.Write(secret) - prk := extractor.Sum(nil) - - return &hkdf{hmac.New(hash, prk), extractor.Size(), info, 1, nil, nil} -} diff --git a/vendor/golang.org/x/crypto/hkdf/hkdf_test.go b/vendor/golang.org/x/crypto/hkdf/hkdf_test.go deleted file mode 100644 index cee659b..0000000 --- a/vendor/golang.org/x/crypto/hkdf/hkdf_test.go +++ /dev/null @@ -1,370 +0,0 @@ -// 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 - -import ( - "bytes" - "crypto/md5" - "crypto/sha1" - "crypto/sha256" - "crypto/sha512" - "hash" - "io" - "testing" -) - -type hkdfTest struct { - hash func() hash.Hash - master []byte - salt []byte - info []byte - out []byte -} - -var hkdfTests = []hkdfTest{ - // Tests from RFC 5869 - { - sha256.New, - []byte{ - 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, - 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, - 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, - }, - []byte{ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, - }, - []byte{ - 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, - 0xf8, 0xf9, - }, - []byte{ - 0x3c, 0xb2, 0x5f, 0x25, 0xfa, 0xac, 0xd5, 0x7a, - 0x90, 0x43, 0x4f, 0x64, 0xd0, 0x36, 0x2f, 0x2a, - 0x2d, 0x2d, 0x0a, 0x90, 0xcf, 0x1a, 0x5a, 0x4c, - 0x5d, 0xb0, 0x2d, 0x56, 0xec, 0xc4, 0xc5, 0xbf, - 0x34, 0x00, 0x72, 0x08, 0xd5, 0xb8, 0x87, 0x18, - 0x58, 0x65, - }, - }, - { - sha256.New, - []byte{ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, - 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, - 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, - 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, - 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, - 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, - }, - []byte{ - 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, - 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, - 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, - 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, - 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, - 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, - 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, - 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, - 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, - 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, - }, - []byte{ - 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, - 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, - 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, - 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, - 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, - 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, - 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, - 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, - 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, - 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, - }, - []byte{ - 0xb1, 0x1e, 0x39, 0x8d, 0xc8, 0x03, 0x27, 0xa1, - 0xc8, 0xe7, 0xf7, 0x8c, 0x59, 0x6a, 0x49, 0x34, - 0x4f, 0x01, 0x2e, 0xda, 0x2d, 0x4e, 0xfa, 0xd8, - 0xa0, 0x50, 0xcc, 0x4c, 0x19, 0xaf, 0xa9, 0x7c, - 0x59, 0x04, 0x5a, 0x99, 0xca, 0xc7, 0x82, 0x72, - 0x71, 0xcb, 0x41, 0xc6, 0x5e, 0x59, 0x0e, 0x09, - 0xda, 0x32, 0x75, 0x60, 0x0c, 0x2f, 0x09, 0xb8, - 0x36, 0x77, 0x93, 0xa9, 0xac, 0xa3, 0xdb, 0x71, - 0xcc, 0x30, 0xc5, 0x81, 0x79, 0xec, 0x3e, 0x87, - 0xc1, 0x4c, 0x01, 0xd5, 0xc1, 0xf3, 0x43, 0x4f, - 0x1d, 0x87, - }, - }, - { - sha256.New, - []byte{ - 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, - 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, - 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, - }, - []byte{}, - []byte{}, - []byte{ - 0x8d, 0xa4, 0xe7, 0x75, 0xa5, 0x63, 0xc1, 0x8f, - 0x71, 0x5f, 0x80, 0x2a, 0x06, 0x3c, 0x5a, 0x31, - 0xb8, 0xa1, 0x1f, 0x5c, 0x5e, 0xe1, 0x87, 0x9e, - 0xc3, 0x45, 0x4e, 0x5f, 0x3c, 0x73, 0x8d, 0x2d, - 0x9d, 0x20, 0x13, 0x95, 0xfa, 0xa4, 0xb6, 0x1a, - 0x96, 0xc8, - }, - }, - { - sha1.New, - []byte{ - 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, - 0x0b, 0x0b, 0x0b, - }, - []byte{ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, - }, - []byte{ - 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, - 0xf8, 0xf9, - }, - []byte{ - 0x08, 0x5a, 0x01, 0xea, 0x1b, 0x10, 0xf3, 0x69, - 0x33, 0x06, 0x8b, 0x56, 0xef, 0xa5, 0xad, 0x81, - 0xa4, 0xf1, 0x4b, 0x82, 0x2f, 0x5b, 0x09, 0x15, - 0x68, 0xa9, 0xcd, 0xd4, 0xf1, 0x55, 0xfd, 0xa2, - 0xc2, 0x2e, 0x42, 0x24, 0x78, 0xd3, 0x05, 0xf3, - 0xf8, 0x96, - }, - }, - { - sha1.New, - []byte{ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, - 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, - 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, - 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, - 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, - 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, - }, - []byte{ - 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, - 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, - 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, - 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, - 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, - 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, - 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, - 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, - 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, - 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, - }, - []byte{ - 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, - 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, - 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, - 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, - 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, - 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, - 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, - 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, - 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, - 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, - }, - []byte{ - 0x0b, 0xd7, 0x70, 0xa7, 0x4d, 0x11, 0x60, 0xf7, - 0xc9, 0xf1, 0x2c, 0xd5, 0x91, 0x2a, 0x06, 0xeb, - 0xff, 0x6a, 0xdc, 0xae, 0x89, 0x9d, 0x92, 0x19, - 0x1f, 0xe4, 0x30, 0x56, 0x73, 0xba, 0x2f, 0xfe, - 0x8f, 0xa3, 0xf1, 0xa4, 0xe5, 0xad, 0x79, 0xf3, - 0xf3, 0x34, 0xb3, 0xb2, 0x02, 0xb2, 0x17, 0x3c, - 0x48, 0x6e, 0xa3, 0x7c, 0xe3, 0xd3, 0x97, 0xed, - 0x03, 0x4c, 0x7f, 0x9d, 0xfe, 0xb1, 0x5c, 0x5e, - 0x92, 0x73, 0x36, 0xd0, 0x44, 0x1f, 0x4c, 0x43, - 0x00, 0xe2, 0xcf, 0xf0, 0xd0, 0x90, 0x0b, 0x52, - 0xd3, 0xb4, - }, - }, - { - sha1.New, - []byte{ - 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, - 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, - 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, - }, - []byte{}, - []byte{}, - []byte{ - 0x0a, 0xc1, 0xaf, 0x70, 0x02, 0xb3, 0xd7, 0x61, - 0xd1, 0xe5, 0x52, 0x98, 0xda, 0x9d, 0x05, 0x06, - 0xb9, 0xae, 0x52, 0x05, 0x72, 0x20, 0xa3, 0x06, - 0xe0, 0x7b, 0x6b, 0x87, 0xe8, 0xdf, 0x21, 0xd0, - 0xea, 0x00, 0x03, 0x3d, 0xe0, 0x39, 0x84, 0xd3, - 0x49, 0x18, - }, - }, - { - sha1.New, - []byte{ - 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, - 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, - 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, - }, - nil, - []byte{}, - []byte{ - 0x2c, 0x91, 0x11, 0x72, 0x04, 0xd7, 0x45, 0xf3, - 0x50, 0x0d, 0x63, 0x6a, 0x62, 0xf6, 0x4f, 0x0a, - 0xb3, 0xba, 0xe5, 0x48, 0xaa, 0x53, 0xd4, 0x23, - 0xb0, 0xd1, 0xf2, 0x7e, 0xbb, 0xa6, 0xf5, 0xe5, - 0x67, 0x3a, 0x08, 0x1d, 0x70, 0xcc, 0xe7, 0xac, - 0xfc, 0x48, - }, - }, -} - -func TestHKDF(t *testing.T) { - for i, tt := range hkdfTests { - hkdf := New(tt.hash, tt.master, tt.salt, tt.info) - out := make([]byte, len(tt.out)) - - n, err := io.ReadFull(hkdf, out) - if n != len(tt.out) || err != nil { - t.Errorf("test %d: not enough output bytes: %d.", i, n) - } - - if !bytes.Equal(out, tt.out) { - t.Errorf("test %d: incorrect output: have %v, need %v.", i, out, tt.out) - } - } -} - -func TestHKDFMultiRead(t *testing.T) { - for i, tt := range hkdfTests { - hkdf := New(tt.hash, tt.master, tt.salt, tt.info) - out := make([]byte, len(tt.out)) - - for b := 0; b < len(tt.out); b++ { - n, err := io.ReadFull(hkdf, out[b:b+1]) - if n != 1 || err != nil { - t.Errorf("test %d.%d: not enough output bytes: have %d, need %d .", i, b, n, len(tt.out)) - } - } - - if !bytes.Equal(out, tt.out) { - t.Errorf("test %d: incorrect output: have %v, need %v.", i, out, tt.out) - } - } -} - -func TestHKDFLimit(t *testing.T) { - hash := sha1.New - master := []byte{0x00, 0x01, 0x02, 0x03} - info := []byte{} - - hkdf := New(hash, master, nil, info) - limit := hash().Size() * 255 - out := make([]byte, limit) - - // The maximum output bytes should be extractable - n, err := io.ReadFull(hkdf, out) - if n != limit || err != nil { - t.Errorf("not enough output bytes: %d, %v.", n, err) - } - - // Reading one more should fail - n, err = io.ReadFull(hkdf, make([]byte, 1)) - if n > 0 || err == nil { - t.Errorf("key expansion overflowed: n = %d, err = %v", n, err) - } -} - -func Benchmark16ByteMD5Single(b *testing.B) { - benchmarkHKDFSingle(md5.New, 16, b) -} - -func Benchmark20ByteSHA1Single(b *testing.B) { - benchmarkHKDFSingle(sha1.New, 20, b) -} - -func Benchmark32ByteSHA256Single(b *testing.B) { - benchmarkHKDFSingle(sha256.New, 32, b) -} - -func Benchmark64ByteSHA512Single(b *testing.B) { - benchmarkHKDFSingle(sha512.New, 64, b) -} - -func Benchmark8ByteMD5Stream(b *testing.B) { - benchmarkHKDFStream(md5.New, 8, b) -} - -func Benchmark16ByteMD5Stream(b *testing.B) { - benchmarkHKDFStream(md5.New, 16, b) -} - -func Benchmark8ByteSHA1Stream(b *testing.B) { - benchmarkHKDFStream(sha1.New, 8, b) -} - -func Benchmark20ByteSHA1Stream(b *testing.B) { - benchmarkHKDFStream(sha1.New, 20, b) -} - -func Benchmark8ByteSHA256Stream(b *testing.B) { - benchmarkHKDFStream(sha256.New, 8, b) -} - -func Benchmark32ByteSHA256Stream(b *testing.B) { - benchmarkHKDFStream(sha256.New, 32, b) -} - -func Benchmark8ByteSHA512Stream(b *testing.B) { - benchmarkHKDFStream(sha512.New, 8, b) -} - -func Benchmark64ByteSHA512Stream(b *testing.B) { - benchmarkHKDFStream(sha512.New, 64, b) -} - -func benchmarkHKDFSingle(hasher func() hash.Hash, block int, b *testing.B) { - master := []byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07} - salt := []byte{0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17} - info := []byte{0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27} - out := make([]byte, block) - - b.SetBytes(int64(block)) - b.ResetTimer() - - for i := 0; i < b.N; i++ { - hkdf := New(hasher, master, salt, info) - io.ReadFull(hkdf, out) - } -} - -func benchmarkHKDFStream(hasher func() hash.Hash, block int, b *testing.B) { - master := []byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07} - salt := []byte{0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17} - info := []byte{0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27} - out := make([]byte, block) - - b.SetBytes(int64(block)) - b.ResetTimer() - - hkdf := New(hasher, master, salt, info) - for i := 0; i < b.N; i++ { - _, err := io.ReadFull(hkdf, out) - if err != nil { - hkdf = New(hasher, master, salt, info) - i-- - } - } -} diff --git a/vendor/golang.org/x/crypto/md4/md4.go b/vendor/golang.org/x/crypto/md4/md4.go deleted file mode 100644 index 6d9ba9e..0000000 --- a/vendor/golang.org/x/crypto/md4/md4.go +++ /dev/null @@ -1,118 +0,0 @@ -// 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. -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/md4_test.go b/vendor/golang.org/x/crypto/md4/md4_test.go deleted file mode 100644 index b56edd7..0000000 --- a/vendor/golang.org/x/crypto/md4/md4_test.go +++ /dev/null @@ -1,71 +0,0 @@ -// 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 - -import ( - "fmt" - "io" - "testing" -) - -type md4Test struct { - out string - in string -} - -var golden = []md4Test{ - {"31d6cfe0d16ae931b73c59d7e0c089c0", ""}, - {"bde52cb31de33e46245e05fbdbd6fb24", "a"}, - {"ec388dd78999dfc7cf4632465693b6bf", "ab"}, - {"a448017aaf21d8525fc10ae87aa6729d", "abc"}, - {"41decd8f579255c5200f86a4bb3ba740", "abcd"}, - {"9803f4a34e8eb14f96adba49064a0c41", "abcde"}, - {"804e7f1c2586e50b49ac65db5b645131", "abcdef"}, - {"752f4adfe53d1da0241b5bc216d098fc", "abcdefg"}, - {"ad9daf8d49d81988590a6f0e745d15dd", "abcdefgh"}, - {"1e4e28b05464316b56402b3815ed2dfd", "abcdefghi"}, - {"dc959c6f5d6f9e04e4380777cc964b3d", "abcdefghij"}, - {"1b5701e265778898ef7de5623bbe7cc0", "Discard medicine more than two years old."}, - {"d7f087e090fe7ad4a01cb59dacc9a572", "He who has a shady past knows that nice guys finish last."}, - {"a6f8fd6df617c72837592fc3570595c9", "I wouldn't marry him with a ten foot pole."}, - {"c92a84a9526da8abc240c05d6b1a1ce0", "Free! Free!/A trip/to Mars/for 900/empty jars/Burma Shave"}, - {"f6013160c4dcb00847069fee3bb09803", "The days of the digital watch are numbered. -Tom Stoppard"}, - {"2c3bb64f50b9107ed57640fe94bec09f", "Nepal premier won't resign."}, - {"45b7d8a32c7806f2f7f897332774d6e4", "For every action there is an equal and opposite government program."}, - {"b5b4f9026b175c62d7654bdc3a1cd438", "His money is twice tainted: 'taint yours and 'taint mine."}, - {"caf44e80f2c20ce19b5ba1cab766e7bd", "There is no reason for any individual to have a computer in their home. -Ken Olsen, 1977"}, - {"191fae6707f496aa54a6bce9f2ecf74d", "It's a tiny change to the code and not completely disgusting. - Bob Manchek"}, - {"9ddc753e7a4ccee6081cd1b45b23a834", "size: a.out: bad magic"}, - {"8d050f55b1cadb9323474564be08a521", "The major problem is with sendmail. -Mark Horton"}, - {"ad6e2587f74c3e3cc19146f6127fa2e3", "Give me a rock, paper and scissors and I will move the world. CCFestoon"}, - {"1d616d60a5fabe85589c3f1566ca7fca", "If the enemy is within range, then so are you."}, - {"aec3326a4f496a2ced65a1963f84577f", "It's well we cannot hear the screams/That we create in others' dreams."}, - {"77b4fd762d6b9245e61c50bf6ebf118b", "You remind me of a TV show, but that's all right: I watch it anyway."}, - {"e8f48c726bae5e516f6ddb1a4fe62438", "C is as portable as Stonehedge!!"}, - {"a3a84366e7219e887423b01f9be7166e", "Even if I could be Shakespeare, I think I should still choose to be Faraday. - A. Huxley"}, - {"a6b7aa35157e984ef5d9b7f32e5fbb52", "The fugacity of a constituent in a mixture of gases at a given temperature is proportional to its mole fraction. Lewis-Randall Rule"}, - {"75661f0545955f8f9abeeb17845f3fd6", "How can you write a big system without C++? -Paul Glick"}, -} - -func TestGolden(t *testing.T) { - for i := 0; i < len(golden); i++ { - g := golden[i] - c := New() - for j := 0; j < 3; j++ { - if j < 2 { - io.WriteString(c, g.in) - } else { - io.WriteString(c, g.in[0:len(g.in)/2]) - c.Sum(nil) - io.WriteString(c, g.in[len(g.in)/2:]) - } - s := fmt.Sprintf("%x", c.Sum(nil)) - if s != g.out { - t.Fatalf("md4[%d](%s) = %s want %s", j, g.in, s, g.out) - } - c.Reset() - } - } -} diff --git a/vendor/golang.org/x/crypto/md4/md4block.go b/vendor/golang.org/x/crypto/md4/md4block.go deleted file mode 100644 index 3fed475..0000000 --- a/vendor/golang.org/x/crypto/md4/md4block.go +++ /dev/null @@ -1,89 +0,0 @@ -// 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<>(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<>(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<>(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/box/box.go b/vendor/golang.org/x/crypto/nacl/box/box.go deleted file mode 100644 index ca48a6d..0000000 --- a/vendor/golang.org/x/crypto/nacl/box/box.go +++ /dev/null @@ -1,85 +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. - -/* -Package box authenticates and encrypts 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. - -This package is interoperable with NaCl: http://nacl.cr.yp.to/box.html. -*/ -package box // import "golang.org/x/crypto/nacl/box" - -import ( - "golang.org/x/crypto/curve25519" - "golang.org/x/crypto/nacl/secretbox" - "golang.org/x/crypto/salsa20/salsa" - "io" -) - -// Overhead is the number of bytes of overhead when boxing a message. -const Overhead = secretbox.Overhead - -// 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. 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) -} diff --git a/vendor/golang.org/x/crypto/nacl/box/box_test.go b/vendor/golang.org/x/crypto/nacl/box/box_test.go deleted file mode 100644 index 481ade2..0000000 --- a/vendor/golang.org/x/crypto/nacl/box/box_test.go +++ /dev/null @@ -1,78 +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. - -package box - -import ( - "bytes" - "crypto/rand" - "encoding/hex" - "testing" - - "golang.org/x/crypto/curve25519" -) - -func TestSealOpen(t *testing.T) { - publicKey1, privateKey1, _ := GenerateKey(rand.Reader) - publicKey2, privateKey2, _ := GenerateKey(rand.Reader) - - if *privateKey1 == *privateKey2 { - t.Fatalf("private keys are equal!") - } - if *publicKey1 == *publicKey2 { - t.Fatalf("public keys are equal!") - } - message := []byte("test message") - var nonce [24]byte - - box := Seal(nil, message, &nonce, publicKey1, privateKey2) - opened, ok := Open(nil, box, &nonce, publicKey2, privateKey1) - if !ok { - t.Fatalf("failed to open box") - } - - if !bytes.Equal(opened, message) { - t.Fatalf("got %x, want %x", opened, message) - } - - for i := range box { - box[i] ^= 0x40 - _, ok := Open(nil, box, &nonce, publicKey2, privateKey1) - if ok { - t.Fatalf("opened box with byte %d corrupted", i) - } - box[i] ^= 0x40 - } -} - -func TestBox(t *testing.T) { - var privateKey1, privateKey2 [32]byte - for i := range privateKey1[:] { - privateKey1[i] = 1 - } - for i := range privateKey2[:] { - privateKey2[i] = 2 - } - - var publicKey1 [32]byte - curve25519.ScalarBaseMult(&publicKey1, &privateKey1) - var message [64]byte - for i := range message[:] { - message[i] = 3 - } - - var nonce [24]byte - for i := range nonce[:] { - nonce[i] = 4 - } - - box := Seal(nil, message[:], &nonce, &publicKey1, &privateKey2) - - // expected was generated using the C implementation of NaCl. - expected, _ := hex.DecodeString("78ea30b19d2341ebbdba54180f821eec265cf86312549bea8a37652a8bb94f07b78a73ed1708085e6ddd0e943bbdeb8755079a37eb31d86163ce241164a47629c0539f330b4914cd135b3855bc2a2dfc") - - if !bytes.Equal(box, expected) { - t.Fatalf("box didn't match, got\n%x\n, expected\n%x", box, expected) - } -} diff --git a/vendor/golang.org/x/crypto/nacl/secretbox/secretbox.go b/vendor/golang.org/x/crypto/nacl/secretbox/secretbox.go deleted file mode 100644 index dbf31bb..0000000 --- a/vendor/golang.org/x/crypto/nacl/secretbox/secretbox.go +++ /dev/null @@ -1,149 +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. - -/* -Package secretbox encrypts and authenticates small messages. - -Secretbox uses XSalsa20 and Poly1305 to encrypt and authenticate messages with -secret-key cryptography. 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. - -This package is interoperable with NaCl: http://nacl.cr.yp.to/secretbox.html. -*/ -package secretbox // import "golang.org/x/crypto/nacl/secretbox" - -import ( - "golang.org/x/crypto/poly1305" - "golang.org/x/crypto/salsa20/salsa" -) - -// Overhead is the number of bytes of overhead when boxing a message. -const Overhead = poly1305.TagSize - -// setup produces a sub-key and Salsa20 counter given a nonce and key. -func setup(subKey *[32]byte, counter *[16]byte, nonce *[24]byte, key *[32]byte) { - // We use XSalsa20 for encryption so first we need to generate a - // key and nonce with HSalsa20. - var hNonce [16]byte - copy(hNonce[:], nonce[:]) - salsa.HSalsa20(subKey, &hNonce, key, &salsa.Sigma) - - // The final 8 bytes of the original nonce form the new nonce. - copy(counter[:], nonce[16:]) -} - -// 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 -} - -// Seal appends an encrypted and authenticated copy of message to out, which -// must not overlap message. The key and nonce pair must be unique for each -// distinct message and the output will be Overhead bytes longer than message. -func Seal(out, message []byte, nonce *[24]byte, key *[32]byte) []byte { - var subKey [32]byte - var counter [16]byte - setup(&subKey, &counter, nonce, key) - - // The Poly1305 key is generated by encrypting 32 bytes of zeros. Since - // Salsa20 works with 64-byte blocks, we also generate 32 bytes of - // keystream as a side effect. - var firstBlock [64]byte - salsa.XORKeyStream(firstBlock[:], firstBlock[:], &counter, &subKey) - - var poly1305Key [32]byte - copy(poly1305Key[:], firstBlock[:]) - - ret, out := sliceForAppend(out, len(message)+poly1305.TagSize) - - // We XOR up to 32 bytes of message with the keystream generated from - // the first block. - firstMessageBlock := message - if len(firstMessageBlock) > 32 { - firstMessageBlock = firstMessageBlock[:32] - } - - tagOut := out - out = out[poly1305.TagSize:] - for i, x := range firstMessageBlock { - out[i] = firstBlock[32+i] ^ x - } - message = message[len(firstMessageBlock):] - ciphertext := out - out = out[len(firstMessageBlock):] - - // Now encrypt the rest. - counter[8] = 1 - salsa.XORKeyStream(out, message, &counter, &subKey) - - var tag [poly1305.TagSize]byte - poly1305.Sum(&tag, ciphertext, &poly1305Key) - copy(tagOut, tag[:]) - - return ret -} - -// 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 []byte, box []byte, nonce *[24]byte, key *[32]byte) ([]byte, bool) { - if len(box) < Overhead { - return nil, false - } - - var subKey [32]byte - var counter [16]byte - setup(&subKey, &counter, nonce, key) - - // The Poly1305 key is generated by encrypting 32 bytes of zeros. Since - // Salsa20 works with 64-byte blocks, we also generate 32 bytes of - // keystream as a side effect. - var firstBlock [64]byte - salsa.XORKeyStream(firstBlock[:], firstBlock[:], &counter, &subKey) - - var poly1305Key [32]byte - copy(poly1305Key[:], firstBlock[:]) - var tag [poly1305.TagSize]byte - copy(tag[:], box) - - if !poly1305.Verify(&tag, box[poly1305.TagSize:], &poly1305Key) { - return nil, false - } - - ret, out := sliceForAppend(out, len(box)-Overhead) - - // We XOR up to 32 bytes of box with the keystream generated from - // the first block. - box = box[Overhead:] - firstMessageBlock := box - if len(firstMessageBlock) > 32 { - firstMessageBlock = firstMessageBlock[:32] - } - for i, x := range firstMessageBlock { - out[i] = firstBlock[32+i] ^ x - } - - box = box[len(firstMessageBlock):] - out = out[len(firstMessageBlock):] - - // Now decrypt the rest. - counter[8] = 1 - salsa.XORKeyStream(out, box, &counter, &subKey) - - return ret, true -} diff --git a/vendor/golang.org/x/crypto/nacl/secretbox/secretbox_test.go b/vendor/golang.org/x/crypto/nacl/secretbox/secretbox_test.go deleted file mode 100644 index 664dc15..0000000 --- a/vendor/golang.org/x/crypto/nacl/secretbox/secretbox_test.go +++ /dev/null @@ -1,91 +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. - -package secretbox - -import ( - "bytes" - "crypto/rand" - "encoding/hex" - "testing" -) - -func TestSealOpen(t *testing.T) { - var key [32]byte - var nonce [24]byte - - rand.Reader.Read(key[:]) - rand.Reader.Read(nonce[:]) - - var box, opened []byte - - for msgLen := 0; msgLen < 128; msgLen += 17 { - message := make([]byte, msgLen) - rand.Reader.Read(message) - - box = Seal(box[:0], message, &nonce, &key) - var ok bool - opened, ok = Open(opened[:0], box, &nonce, &key) - if !ok { - t.Errorf("%d: failed to open box", msgLen) - continue - } - - if !bytes.Equal(opened, message) { - t.Errorf("%d: got %x, expected %x", msgLen, opened, message) - continue - } - } - - for i := range box { - box[i] ^= 0x20 - _, ok := Open(opened[:0], box, &nonce, &key) - if ok { - t.Errorf("box was opened after corrupting byte %d", i) - } - box[i] ^= 0x20 - } -} - -func TestSecretBox(t *testing.T) { - var key [32]byte - var nonce [24]byte - var message [64]byte - - for i := range key[:] { - key[i] = 1 - } - for i := range nonce[:] { - nonce[i] = 2 - } - for i := range message[:] { - message[i] = 3 - } - - box := Seal(nil, message[:], &nonce, &key) - // expected was generated using the C implementation of NaCl. - expected, _ := hex.DecodeString("8442bc313f4626f1359e3b50122b6ce6fe66ddfe7d39d14e637eb4fd5b45beadab55198df6ab5368439792a23c87db70acb6156dc5ef957ac04f6276cf6093b84be77ff0849cc33e34b7254d5a8f65ad") - - if !bytes.Equal(box, expected) { - t.Fatalf("box didn't match, got\n%x\n, expected\n%x", box, expected) - } -} - -func TestAppend(t *testing.T) { - var key [32]byte - var nonce [24]byte - var message [8]byte - - out := make([]byte, 4) - box := Seal(out, message[:], &nonce, &key) - if !bytes.Equal(box[:4], out[:4]) { - t.Fatalf("Seal didn't correctly append") - } - - out = make([]byte, 4, 100) - box = Seal(out, message[:], &nonce, &key) - if !bytes.Equal(box[:4], out[:4]) { - t.Fatalf("Seal didn't correctly append with sufficient capacity.") - } -} diff --git a/vendor/golang.org/x/crypto/ocsp/ocsp.go b/vendor/golang.org/x/crypto/ocsp/ocsp.go deleted file mode 100644 index 6bfbd5d..0000000 --- a/vendor/golang.org/x/crypto/ocsp/ocsp.go +++ /dev/null @@ -1,673 +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 ocsp parses OCSP responses as specified in RFC 2560. OCSP responses -// are signed messages attesting to the validity of a certificate for a small -// period of time. This is used to manage revocation for X.509 certificates. -package ocsp // import "golang.org/x/crypto/ocsp" - -import ( - "crypto" - "crypto/ecdsa" - "crypto/elliptic" - "crypto/rand" - "crypto/rsa" - "crypto/sha1" - "crypto/x509" - "crypto/x509/pkix" - "encoding/asn1" - "errors" - "math/big" - "strconv" - "time" -) - -var idPKIXOCSPBasic = asn1.ObjectIdentifier([]int{1, 3, 6, 1, 5, 5, 7, 48, 1, 1}) - -// ResponseStatus contains the result of an OCSP request. See -// https://tools.ietf.org/html/rfc6960#section-2.3 -type ResponseStatus int - -const ( - Success ResponseStatus = 0 - Malformed ResponseStatus = 1 - InternalError ResponseStatus = 2 - TryLater ResponseStatus = 3 - // Status code four is ununsed in OCSP. See - // https://tools.ietf.org/html/rfc6960#section-4.2.1 - SignatureRequired ResponseStatus = 5 - Unauthorized ResponseStatus = 6 -) - -func (r ResponseStatus) String() string { - switch r { - case Success: - return "success" - case Malformed: - return "malformed" - case InternalError: - return "internal error" - case TryLater: - return "try later" - case SignatureRequired: - return "signature required" - case Unauthorized: - return "unauthorized" - default: - return "unknown OCSP status: " + strconv.Itoa(int(r)) - } -} - -// ResponseError is an error that may be returned by ParseResponse to indicate -// that the response itself is an error, not just that its indicating that a -// certificate is revoked, unknown, etc. -type ResponseError struct { - Status ResponseStatus -} - -func (r ResponseError) Error() string { - return "ocsp: error from server: " + r.Status.String() -} - -// These are internal structures that reflect the ASN.1 structure of an OCSP -// response. See RFC 2560, section 4.2. - -type certID struct { - HashAlgorithm pkix.AlgorithmIdentifier - NameHash []byte - IssuerKeyHash []byte - SerialNumber *big.Int -} - -// https://tools.ietf.org/html/rfc2560#section-4.1.1 -type ocspRequest struct { - TBSRequest tbsRequest -} - -type tbsRequest struct { - Version int `asn1:"explicit,tag:0,default:0,optional"` - RequestorName pkix.RDNSequence `asn1:"explicit,tag:1,optional"` - RequestList []request -} - -type request struct { - Cert certID -} - -type responseASN1 struct { - Status asn1.Enumerated - Response responseBytes `asn1:"explicit,tag:0,optional"` -} - -type responseBytes struct { - ResponseType asn1.ObjectIdentifier - Response []byte -} - -type basicResponse struct { - TBSResponseData responseData - SignatureAlgorithm pkix.AlgorithmIdentifier - Signature asn1.BitString - Certificates []asn1.RawValue `asn1:"explicit,tag:0,optional"` -} - -type responseData struct { - Raw asn1.RawContent - Version int `asn1:"optional,default:1,explicit,tag:0"` - RawResponderName asn1.RawValue `asn1:"optional,explicit,tag:1"` - KeyHash []byte `asn1:"optional,explicit,tag:2"` - ProducedAt time.Time `asn1:"generalized"` - Responses []singleResponse -} - -type singleResponse struct { - CertID certID - Good asn1.Flag `asn1:"tag:0,optional"` - Revoked revokedInfo `asn1:"tag:1,optional"` - Unknown asn1.Flag `asn1:"tag:2,optional"` - ThisUpdate time.Time `asn1:"generalized"` - NextUpdate time.Time `asn1:"generalized,explicit,tag:0,optional"` - SingleExtensions []pkix.Extension `asn1:"explicit,tag:1,optional"` -} - -type revokedInfo struct { - RevocationTime time.Time `asn1:"generalized"` - Reason asn1.Enumerated `asn1:"explicit,tag:0,optional"` -} - -var ( - oidSignatureMD2WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 2} - oidSignatureMD5WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 4} - oidSignatureSHA1WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 5} - oidSignatureSHA256WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 11} - oidSignatureSHA384WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 12} - oidSignatureSHA512WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 13} - oidSignatureDSAWithSHA1 = asn1.ObjectIdentifier{1, 2, 840, 10040, 4, 3} - oidSignatureDSAWithSHA256 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 3, 2} - oidSignatureECDSAWithSHA1 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 1} - oidSignatureECDSAWithSHA256 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 2} - oidSignatureECDSAWithSHA384 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 3} - oidSignatureECDSAWithSHA512 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 4} -) - -var hashOIDs = map[crypto.Hash]asn1.ObjectIdentifier{ - crypto.SHA1: asn1.ObjectIdentifier([]int{1, 3, 14, 3, 2, 26}), - crypto.SHA256: asn1.ObjectIdentifier([]int{2, 16, 840, 1, 101, 3, 4, 2, 1}), - crypto.SHA384: asn1.ObjectIdentifier([]int{2, 16, 840, 1, 101, 3, 4, 2, 2}), - crypto.SHA512: asn1.ObjectIdentifier([]int{2, 16, 840, 1, 101, 3, 4, 2, 3}), -} - -// TODO(rlb): This is also from crypto/x509, so same comment as AGL's below -var signatureAlgorithmDetails = []struct { - algo x509.SignatureAlgorithm - oid asn1.ObjectIdentifier - pubKeyAlgo x509.PublicKeyAlgorithm - hash crypto.Hash -}{ - {x509.MD2WithRSA, oidSignatureMD2WithRSA, x509.RSA, crypto.Hash(0) /* no value for MD2 */}, - {x509.MD5WithRSA, oidSignatureMD5WithRSA, x509.RSA, crypto.MD5}, - {x509.SHA1WithRSA, oidSignatureSHA1WithRSA, x509.RSA, crypto.SHA1}, - {x509.SHA256WithRSA, oidSignatureSHA256WithRSA, x509.RSA, crypto.SHA256}, - {x509.SHA384WithRSA, oidSignatureSHA384WithRSA, x509.RSA, crypto.SHA384}, - {x509.SHA512WithRSA, oidSignatureSHA512WithRSA, x509.RSA, crypto.SHA512}, - {x509.DSAWithSHA1, oidSignatureDSAWithSHA1, x509.DSA, crypto.SHA1}, - {x509.DSAWithSHA256, oidSignatureDSAWithSHA256, x509.DSA, crypto.SHA256}, - {x509.ECDSAWithSHA1, oidSignatureECDSAWithSHA1, x509.ECDSA, crypto.SHA1}, - {x509.ECDSAWithSHA256, oidSignatureECDSAWithSHA256, x509.ECDSA, crypto.SHA256}, - {x509.ECDSAWithSHA384, oidSignatureECDSAWithSHA384, x509.ECDSA, crypto.SHA384}, - {x509.ECDSAWithSHA512, oidSignatureECDSAWithSHA512, x509.ECDSA, crypto.SHA512}, -} - -// TODO(rlb): This is also from crypto/x509, so same comment as AGL's below -func signingParamsForPublicKey(pub interface{}, requestedSigAlgo x509.SignatureAlgorithm) (hashFunc crypto.Hash, sigAlgo pkix.AlgorithmIdentifier, err error) { - var pubType x509.PublicKeyAlgorithm - - switch pub := pub.(type) { - case *rsa.PublicKey: - pubType = x509.RSA - hashFunc = crypto.SHA256 - sigAlgo.Algorithm = oidSignatureSHA256WithRSA - sigAlgo.Parameters = asn1.RawValue{ - Tag: 5, - } - - case *ecdsa.PublicKey: - pubType = x509.ECDSA - - switch pub.Curve { - case elliptic.P224(), elliptic.P256(): - hashFunc = crypto.SHA256 - sigAlgo.Algorithm = oidSignatureECDSAWithSHA256 - case elliptic.P384(): - hashFunc = crypto.SHA384 - sigAlgo.Algorithm = oidSignatureECDSAWithSHA384 - case elliptic.P521(): - hashFunc = crypto.SHA512 - sigAlgo.Algorithm = oidSignatureECDSAWithSHA512 - default: - err = errors.New("x509: unknown elliptic curve") - } - - default: - err = errors.New("x509: only RSA and ECDSA keys supported") - } - - if err != nil { - return - } - - if requestedSigAlgo == 0 { - return - } - - found := false - for _, details := range signatureAlgorithmDetails { - if details.algo == requestedSigAlgo { - if details.pubKeyAlgo != pubType { - err = errors.New("x509: requested SignatureAlgorithm does not match private key type") - return - } - sigAlgo.Algorithm, hashFunc = details.oid, details.hash - if hashFunc == 0 { - err = errors.New("x509: cannot sign with hash function requested") - return - } - found = true - break - } - } - - if !found { - err = errors.New("x509: unknown SignatureAlgorithm") - } - - return -} - -// TODO(agl): this is taken from crypto/x509 and so should probably be exported -// from crypto/x509 or crypto/x509/pkix. -func getSignatureAlgorithmFromOID(oid asn1.ObjectIdentifier) x509.SignatureAlgorithm { - for _, details := range signatureAlgorithmDetails { - if oid.Equal(details.oid) { - return details.algo - } - } - return x509.UnknownSignatureAlgorithm -} - -// TODO(rlb): This is not taken from crypto/x509, but it's of the same general form. -func getHashAlgorithmFromOID(target asn1.ObjectIdentifier) crypto.Hash { - for hash, oid := range hashOIDs { - if oid.Equal(target) { - return hash - } - } - return crypto.Hash(0) -} - -// This is the exposed reflection of the internal OCSP structures. - -// The status values that can be expressed in OCSP. See RFC 6960. -const ( - // Good means that the certificate is valid. - Good = iota - // Revoked means that the certificate has been deliberately revoked. - Revoked - // Unknown means that the OCSP responder doesn't know about the certificate. - Unknown - // ServerFailed is unused and was never used (see - // https://go-review.googlesource.com/#/c/18944). ParseResponse will - // return a ResponseError when an error response is parsed. - ServerFailed -) - -// The enumerated reasons for revoking a certificate. See RFC 5280. -const ( - Unspecified = iota - KeyCompromise = iota - CACompromise = iota - AffiliationChanged = iota - Superseded = iota - CessationOfOperation = iota - CertificateHold = iota - _ = iota - RemoveFromCRL = iota - PrivilegeWithdrawn = iota - AACompromise = iota -) - -// Request represents an OCSP request. See RFC 6960. -type Request struct { - HashAlgorithm crypto.Hash - IssuerNameHash []byte - IssuerKeyHash []byte - SerialNumber *big.Int -} - -// Response represents an OCSP response containing a single SingleResponse. See -// RFC 6960. -type Response struct { - // Status is one of {Good, Revoked, Unknown} - Status int - SerialNumber *big.Int - ProducedAt, ThisUpdate, NextUpdate, RevokedAt time.Time - RevocationReason int - Certificate *x509.Certificate - // TBSResponseData contains the raw bytes of the signed response. If - // Certificate is nil then this can be used to verify Signature. - TBSResponseData []byte - Signature []byte - SignatureAlgorithm x509.SignatureAlgorithm - - // Extensions contains raw X.509 extensions from the singleExtensions field - // of the OCSP response. When parsing certificates, this can be used to - // extract non-critical extensions that are not parsed by this package. When - // marshaling OCSP responses, the Extensions field is ignored, see - // ExtraExtensions. - Extensions []pkix.Extension - - // ExtraExtensions contains extensions to be copied, raw, into any marshaled - // OCSP response (in the singleExtensions field). Values override any - // extensions that would otherwise be produced based on the other fields. The - // ExtraExtensions field is not populated when parsing certificates, see - // Extensions. - ExtraExtensions []pkix.Extension -} - -// These are pre-serialized error responses for the various non-success codes -// defined by OCSP. The Unauthorized code in particular can be used by an OCSP -// responder that supports only pre-signed responses as a response to requests -// for certificates with unknown status. See RFC 5019. -var ( - MalformedRequestErrorResponse = []byte{0x30, 0x03, 0x0A, 0x01, 0x01} - InternalErrorErrorResponse = []byte{0x30, 0x03, 0x0A, 0x01, 0x02} - TryLaterErrorResponse = []byte{0x30, 0x03, 0x0A, 0x01, 0x03} - SigRequredErrorResponse = []byte{0x30, 0x03, 0x0A, 0x01, 0x05} - UnauthorizedErrorResponse = []byte{0x30, 0x03, 0x0A, 0x01, 0x06} -) - -// CheckSignatureFrom checks that the signature in resp is a valid signature -// from issuer. This should only be used if resp.Certificate is nil. Otherwise, -// the OCSP response contained an intermediate certificate that created the -// signature. That signature is checked by ParseResponse and only -// resp.Certificate remains to be validated. -func (resp *Response) CheckSignatureFrom(issuer *x509.Certificate) error { - return issuer.CheckSignature(resp.SignatureAlgorithm, resp.TBSResponseData, resp.Signature) -} - -// ParseError results from an invalid OCSP response. -type ParseError string - -func (p ParseError) Error() string { - return string(p) -} - -// ParseRequest parses an OCSP request in DER form. It only supports -// requests for a single certificate. Signed requests are not supported. -// If a request includes a signature, it will result in a ParseError. -func ParseRequest(bytes []byte) (*Request, error) { - var req ocspRequest - rest, err := asn1.Unmarshal(bytes, &req) - if err != nil { - return nil, err - } - if len(rest) > 0 { - return nil, ParseError("trailing data in OCSP request") - } - - if len(req.TBSRequest.RequestList) == 0 { - return nil, ParseError("OCSP request contains no request body") - } - innerRequest := req.TBSRequest.RequestList[0] - - hashFunc := getHashAlgorithmFromOID(innerRequest.Cert.HashAlgorithm.Algorithm) - if hashFunc == crypto.Hash(0) { - return nil, ParseError("OCSP request uses unknown hash function") - } - - return &Request{ - HashAlgorithm: hashFunc, - IssuerNameHash: innerRequest.Cert.NameHash, - IssuerKeyHash: innerRequest.Cert.IssuerKeyHash, - SerialNumber: innerRequest.Cert.SerialNumber, - }, nil -} - -// ParseResponse parses an OCSP response in DER form. It only supports -// responses for a single certificate. If the response contains a certificate -// then the signature over the response is checked. If issuer is not nil then -// it will be used to validate the signature or embedded certificate. -// -// Invalid signatures or parse failures will result in a ParseError. Error -// responses will result in a ResponseError. -func ParseResponse(bytes []byte, issuer *x509.Certificate) (*Response, error) { - var resp responseASN1 - rest, err := asn1.Unmarshal(bytes, &resp) - if err != nil { - return nil, err - } - if len(rest) > 0 { - return nil, ParseError("trailing data in OCSP response") - } - - if status := ResponseStatus(resp.Status); status != Success { - return nil, ResponseError{status} - } - - if !resp.Response.ResponseType.Equal(idPKIXOCSPBasic) { - return nil, ParseError("bad OCSP response type") - } - - var basicResp basicResponse - rest, err = asn1.Unmarshal(resp.Response.Response, &basicResp) - if err != nil { - return nil, err - } - - if len(basicResp.Certificates) > 1 { - return nil, ParseError("OCSP response contains bad number of certificates") - } - - if len(basicResp.TBSResponseData.Responses) != 1 { - return nil, ParseError("OCSP response contains bad number of responses") - } - - ret := &Response{ - TBSResponseData: basicResp.TBSResponseData.Raw, - Signature: basicResp.Signature.RightAlign(), - SignatureAlgorithm: getSignatureAlgorithmFromOID(basicResp.SignatureAlgorithm.Algorithm), - } - - if len(basicResp.Certificates) > 0 { - ret.Certificate, err = x509.ParseCertificate(basicResp.Certificates[0].FullBytes) - if err != nil { - return nil, err - } - - if err := ret.CheckSignatureFrom(ret.Certificate); err != nil { - return nil, ParseError("bad OCSP signature") - } - - if issuer != nil { - if err := issuer.CheckSignature(ret.Certificate.SignatureAlgorithm, ret.Certificate.RawTBSCertificate, ret.Certificate.Signature); err != nil { - return nil, ParseError("bad signature on embedded certificate") - } - } - } else if issuer != nil { - if err := ret.CheckSignatureFrom(issuer); err != nil { - return nil, ParseError("bad OCSP signature") - } - } - - r := basicResp.TBSResponseData.Responses[0] - - for _, ext := range r.SingleExtensions { - if ext.Critical { - return nil, ParseError("unsupported critical extension") - } - } - ret.Extensions = r.SingleExtensions - - ret.SerialNumber = r.CertID.SerialNumber - - switch { - case bool(r.Good): - ret.Status = Good - case bool(r.Unknown): - ret.Status = Unknown - default: - ret.Status = Revoked - ret.RevokedAt = r.Revoked.RevocationTime - ret.RevocationReason = int(r.Revoked.Reason) - } - - ret.ProducedAt = basicResp.TBSResponseData.ProducedAt - ret.ThisUpdate = r.ThisUpdate - ret.NextUpdate = r.NextUpdate - - return ret, nil -} - -// RequestOptions contains options for constructing OCSP requests. -type RequestOptions struct { - // Hash contains the hash function that should be used when - // constructing the OCSP request. If zero, SHA-1 will be used. - Hash crypto.Hash -} - -func (opts *RequestOptions) hash() crypto.Hash { - if opts == nil || opts.Hash == 0 { - // SHA-1 is nearly universally used in OCSP. - return crypto.SHA1 - } - return opts.Hash -} - -// CreateRequest returns a DER-encoded, OCSP request for the status of cert. If -// opts is nil then sensible defaults are used. -func CreateRequest(cert, issuer *x509.Certificate, opts *RequestOptions) ([]byte, error) { - hashFunc := opts.hash() - - // OCSP seems to be the only place where these raw hash identifiers are - // used. I took the following from - // http://msdn.microsoft.com/en-us/library/ff635603.aspx - var hashOID asn1.ObjectIdentifier - hashOID, ok := hashOIDs[hashFunc] - if !ok { - return nil, x509.ErrUnsupportedAlgorithm - } - - if !hashFunc.Available() { - return nil, x509.ErrUnsupportedAlgorithm - } - h := opts.hash().New() - - var publicKeyInfo struct { - Algorithm pkix.AlgorithmIdentifier - PublicKey asn1.BitString - } - if _, err := asn1.Unmarshal(issuer.RawSubjectPublicKeyInfo, &publicKeyInfo); err != nil { - return nil, err - } - - h.Write(publicKeyInfo.PublicKey.RightAlign()) - issuerKeyHash := h.Sum(nil) - - h.Reset() - h.Write(issuer.RawSubject) - issuerNameHash := h.Sum(nil) - - return asn1.Marshal(ocspRequest{ - tbsRequest{ - Version: 0, - RequestList: []request{ - { - Cert: certID{ - pkix.AlgorithmIdentifier{ - Algorithm: hashOID, - Parameters: asn1.RawValue{Tag: 5 /* ASN.1 NULL */}, - }, - issuerNameHash, - issuerKeyHash, - cert.SerialNumber, - }, - }, - }, - }, - }) -} - -// CreateResponse returns a DER-encoded OCSP response with the specified contents. -// The fields in the response are populated as follows: -// -// The responder cert is used to populate the ResponderName field, and the certificate -// itself is provided alongside the OCSP response signature. -// -// The issuer cert is used to puplate the IssuerNameHash and IssuerKeyHash fields. -// (SHA-1 is used for the hash function; this is not configurable.) -// -// The template is used to populate the SerialNumber, RevocationStatus, RevokedAt, -// RevocationReason, ThisUpdate, and NextUpdate fields. -// -// The ProducedAt date is automatically set to the current date, to the nearest minute. -func CreateResponse(issuer, responderCert *x509.Certificate, template Response, priv crypto.Signer) ([]byte, error) { - var publicKeyInfo struct { - Algorithm pkix.AlgorithmIdentifier - PublicKey asn1.BitString - } - if _, err := asn1.Unmarshal(issuer.RawSubjectPublicKeyInfo, &publicKeyInfo); err != nil { - return nil, err - } - - h := sha1.New() - h.Write(publicKeyInfo.PublicKey.RightAlign()) - issuerKeyHash := h.Sum(nil) - - h.Reset() - h.Write(issuer.RawSubject) - issuerNameHash := h.Sum(nil) - - innerResponse := singleResponse{ - CertID: certID{ - HashAlgorithm: pkix.AlgorithmIdentifier{ - Algorithm: hashOIDs[crypto.SHA1], - Parameters: asn1.RawValue{Tag: 5 /* ASN.1 NULL */}, - }, - NameHash: issuerNameHash, - IssuerKeyHash: issuerKeyHash, - SerialNumber: template.SerialNumber, - }, - ThisUpdate: template.ThisUpdate.UTC(), - NextUpdate: template.NextUpdate.UTC(), - SingleExtensions: template.ExtraExtensions, - } - - switch template.Status { - case Good: - innerResponse.Good = true - case Unknown: - innerResponse.Unknown = true - case Revoked: - innerResponse.Revoked = revokedInfo{ - RevocationTime: template.RevokedAt.UTC(), - Reason: asn1.Enumerated(template.RevocationReason), - } - } - - responderName := asn1.RawValue{ - Class: 2, // context-specific - Tag: 1, // explicit tag - IsCompound: true, - Bytes: responderCert.RawSubject, - } - tbsResponseData := responseData{ - Version: 0, - RawResponderName: responderName, - ProducedAt: time.Now().Truncate(time.Minute).UTC(), - Responses: []singleResponse{innerResponse}, - } - - tbsResponseDataDER, err := asn1.Marshal(tbsResponseData) - if err != nil { - return nil, err - } - - hashFunc, signatureAlgorithm, err := signingParamsForPublicKey(priv.Public(), template.SignatureAlgorithm) - if err != nil { - return nil, err - } - - responseHash := hashFunc.New() - responseHash.Write(tbsResponseDataDER) - signature, err := priv.Sign(rand.Reader, responseHash.Sum(nil), hashFunc) - if err != nil { - return nil, err - } - - response := basicResponse{ - TBSResponseData: tbsResponseData, - SignatureAlgorithm: signatureAlgorithm, - Signature: asn1.BitString{ - Bytes: signature, - BitLength: 8 * len(signature), - }, - } - if template.Certificate != nil { - response.Certificates = []asn1.RawValue{ - asn1.RawValue{FullBytes: template.Certificate.Raw}, - } - } - responseDER, err := asn1.Marshal(response) - if err != nil { - return nil, err - } - - return asn1.Marshal(responseASN1{ - Status: asn1.Enumerated(Success), - Response: responseBytes{ - ResponseType: idPKIXOCSPBasic, - Response: responseDER, - }, - }) -} diff --git a/vendor/golang.org/x/crypto/ocsp/ocsp_test.go b/vendor/golang.org/x/crypto/ocsp/ocsp_test.go deleted file mode 100644 index 3386849..0000000 --- a/vendor/golang.org/x/crypto/ocsp/ocsp_test.go +++ /dev/null @@ -1,584 +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 ocsp - -import ( - "bytes" - "crypto" - "crypto/sha1" - "crypto/x509" - "crypto/x509/pkix" - "encoding/asn1" - "encoding/hex" - "math/big" - "reflect" - "testing" - "time" -) - -func TestOCSPDecode(t *testing.T) { - responseBytes, _ := hex.DecodeString(ocspResponseHex) - resp, err := ParseResponse(responseBytes, nil) - if err != nil { - t.Error(err) - } - - expected := Response{ - Status: Good, - SerialNumber: big.NewInt(0x1d0fa), - RevocationReason: Unspecified, - ThisUpdate: time.Date(2010, 7, 7, 15, 1, 5, 0, time.UTC), - NextUpdate: time.Date(2010, 7, 7, 18, 35, 17, 0, time.UTC), - } - - if !reflect.DeepEqual(resp.ThisUpdate, expected.ThisUpdate) { - t.Errorf("resp.ThisUpdate: got %d, want %d", resp.ThisUpdate, expected.ThisUpdate) - } - - if !reflect.DeepEqual(resp.NextUpdate, expected.NextUpdate) { - t.Errorf("resp.NextUpdate: got %d, want %d", resp.NextUpdate, expected.NextUpdate) - } - - if resp.Status != expected.Status { - t.Errorf("resp.Status: got %d, want %d", resp.Status, expected.Status) - } - - if resp.SerialNumber.Cmp(expected.SerialNumber) != 0 { - t.Errorf("resp.SerialNumber: got %x, want %x", resp.SerialNumber, expected.SerialNumber) - } - - if resp.RevocationReason != expected.RevocationReason { - t.Errorf("resp.RevocationReason: got %d, want %d", resp.RevocationReason, expected.RevocationReason) - } -} - -func TestOCSPDecodeWithoutCert(t *testing.T) { - responseBytes, _ := hex.DecodeString(ocspResponseWithoutCertHex) - _, err := ParseResponse(responseBytes, nil) - if err != nil { - t.Error(err) - } -} - -func TestOCSPDecodeWithExtensions(t *testing.T) { - responseBytes, _ := hex.DecodeString(ocspResponseWithCriticalExtensionHex) - _, err := ParseResponse(responseBytes, nil) - if err == nil { - t.Error(err) - } - - responseBytes, _ = hex.DecodeString(ocspResponseWithExtensionHex) - response, err := ParseResponse(responseBytes, nil) - if err != nil { - t.Fatal(err) - } - - if len(response.Extensions) != 1 { - t.Errorf("len(response.Extensions): got %v, want %v", len(response.Extensions), 1) - } - - extensionBytes := response.Extensions[0].Value - expectedBytes, _ := hex.DecodeString(ocspExtensionValueHex) - if !bytes.Equal(extensionBytes, expectedBytes) { - t.Errorf("response.Extensions[0]: got %x, want %x", extensionBytes, expectedBytes) - } -} - -func TestOCSPSignature(t *testing.T) { - issuerCert, _ := hex.DecodeString(startComHex) - issuer, err := x509.ParseCertificate(issuerCert) - if err != nil { - t.Fatal(err) - } - - response, _ := hex.DecodeString(ocspResponseHex) - if _, err := ParseResponse(response, issuer); err != nil { - t.Error(err) - } -} - -func TestOCSPRequest(t *testing.T) { - leafCert, _ := hex.DecodeString(leafCertHex) - cert, err := x509.ParseCertificate(leafCert) - if err != nil { - t.Fatal(err) - } - - issuerCert, _ := hex.DecodeString(issuerCertHex) - issuer, err := x509.ParseCertificate(issuerCert) - if err != nil { - t.Fatal(err) - } - - request, err := CreateRequest(cert, issuer, nil) - if err != nil { - t.Fatal(err) - } - - expectedBytes, _ := hex.DecodeString(ocspRequestHex) - if !bytes.Equal(request, expectedBytes) { - t.Errorf("request: got %x, wanted %x", request, expectedBytes) - } - - decodedRequest, err := ParseRequest(expectedBytes) - if err != nil { - t.Fatal(err) - } - - if decodedRequest.HashAlgorithm != crypto.SHA1 { - t.Errorf("request.HashAlgorithm: got %v, want %v", decodedRequest.HashAlgorithm, crypto.SHA1) - } - - var publicKeyInfo struct { - Algorithm pkix.AlgorithmIdentifier - PublicKey asn1.BitString - } - _, err = asn1.Unmarshal(issuer.RawSubjectPublicKeyInfo, &publicKeyInfo) - if err != nil { - t.Fatal(err) - } - - h := sha1.New() - h.Write(publicKeyInfo.PublicKey.RightAlign()) - issuerKeyHash := h.Sum(nil) - - h.Reset() - h.Write(issuer.RawSubject) - issuerNameHash := h.Sum(nil) - - if got := decodedRequest.IssuerKeyHash; !bytes.Equal(got, issuerKeyHash) { - t.Errorf("request.IssuerKeyHash: got %x, want %x", got, issuerKeyHash) - } - - if got := decodedRequest.IssuerNameHash; !bytes.Equal(got, issuerNameHash) { - t.Errorf("request.IssuerKeyHash: got %x, want %x", got, issuerNameHash) - } - - if got := decodedRequest.SerialNumber; got.Cmp(cert.SerialNumber) != 0 { - t.Errorf("request.SerialNumber: got %x, want %x", got, cert.SerialNumber) - } -} - -func TestOCSPResponse(t *testing.T) { - leafCert, _ := hex.DecodeString(leafCertHex) - leaf, err := x509.ParseCertificate(leafCert) - if err != nil { - t.Fatal(err) - } - - issuerCert, _ := hex.DecodeString(issuerCertHex) - issuer, err := x509.ParseCertificate(issuerCert) - if err != nil { - t.Fatal(err) - } - - responderCert, _ := hex.DecodeString(responderCertHex) - responder, err := x509.ParseCertificate(responderCert) - if err != nil { - t.Fatal(err) - } - - responderPrivateKeyDER, _ := hex.DecodeString(responderPrivateKeyHex) - responderPrivateKey, err := x509.ParsePKCS1PrivateKey(responderPrivateKeyDER) - if err != nil { - t.Fatal(err) - } - - extensionBytes, _ := hex.DecodeString(ocspExtensionValueHex) - extensions := []pkix.Extension{ - pkix.Extension{ - Id: ocspExtensionOID, - Critical: false, - Value: extensionBytes, - }, - } - - producedAt := time.Now().Truncate(time.Minute) - thisUpdate := time.Date(2010, 7, 7, 15, 1, 5, 0, time.UTC) - nextUpdate := time.Date(2010, 7, 7, 18, 35, 17, 0, time.UTC) - template := Response{ - Status: Revoked, - SerialNumber: leaf.SerialNumber, - ThisUpdate: thisUpdate, - NextUpdate: nextUpdate, - RevokedAt: thisUpdate, - RevocationReason: KeyCompromise, - Certificate: responder, - ExtraExtensions: extensions, - } - - responseBytes, err := CreateResponse(issuer, responder, template, responderPrivateKey) - if err != nil { - t.Fatal(err) - } - - resp, err := ParseResponse(responseBytes, nil) - if err != nil { - t.Fatal(err) - } - - if !reflect.DeepEqual(resp.ThisUpdate, template.ThisUpdate) { - t.Errorf("resp.ThisUpdate: got %d, want %d", resp.ThisUpdate, template.ThisUpdate) - } - - if !reflect.DeepEqual(resp.NextUpdate, template.NextUpdate) { - t.Errorf("resp.NextUpdate: got %d, want %d", resp.NextUpdate, template.NextUpdate) - } - - if !reflect.DeepEqual(resp.RevokedAt, template.RevokedAt) { - t.Errorf("resp.RevokedAt: got %d, want %d", resp.RevokedAt, template.RevokedAt) - } - - if !reflect.DeepEqual(resp.Extensions, template.ExtraExtensions) { - t.Errorf("resp.Extensions: got %v, want %v", resp.Extensions, template.ExtraExtensions) - } - - if !resp.ProducedAt.Equal(producedAt) { - t.Errorf("resp.ProducedAt: got %d, want %d", resp.ProducedAt, producedAt) - } - - if resp.Status != template.Status { - t.Errorf("resp.Status: got %d, want %d", resp.Status, template.Status) - } - - if resp.SerialNumber.Cmp(template.SerialNumber) != 0 { - t.Errorf("resp.SerialNumber: got %x, want %x", resp.SerialNumber, template.SerialNumber) - } - - if resp.RevocationReason != template.RevocationReason { - t.Errorf("resp.RevocationReason: got %d, want %d", resp.RevocationReason, template.RevocationReason) - } -} - -func TestErrorResponse(t *testing.T) { - responseBytes, _ := hex.DecodeString(errorResponseHex) - _, err := ParseResponse(responseBytes, nil) - - respErr, ok := err.(ResponseError) - if !ok { - t.Fatalf("expected ResponseError from ParseResponse but got %#v", err) - } - if respErr.Status != Malformed { - t.Fatalf("expected Malformed status from ParseResponse but got %d", respErr.Status) - } -} - -// This OCSP response was taken from Thawte's public OCSP responder. -// To recreate: -// $ openssl s_client -tls1 -showcerts -servername www.google.com -connect www.google.com:443 -// Copy and paste the first certificate into /tmp/cert.crt and the second into -// /tmp/intermediate.crt -// $ openssl ocsp -issuer /tmp/intermediate.crt -cert /tmp/cert.crt -url http://ocsp.thawte.com -resp_text -respout /tmp/ocsp.der -// Then hex encode the result: -// $ python -c 'print file("/tmp/ocsp.der", "r").read().encode("hex")' - -const ocspResponseHex = "308206bc0a0100a08206b5308206b106092b0601050507300101048206a23082069e3081" + - "c9a14e304c310b300906035504061302494c31163014060355040a130d5374617274436f" + - "6d204c74642e312530230603550403131c5374617274436f6d20436c6173732031204f43" + - "5350205369676e6572180f32303130303730373137333531375a30663064303c30090605" + - "2b0e03021a050004146568874f40750f016a3475625e1f5c93e5a26d580414eb4234d098" + - "b0ab9ff41b6b08f7cc642eef0e2c45020301d0fa8000180f323031303037303731353031" + - "30355aa011180f32303130303730373138333531375a300d06092a864886f70d01010505" + - "000382010100ab557ff070d1d7cebbb5f0ec91a15c3fed22eb2e1b8244f1b84545f013a4" + - "fb46214c5e3fbfbebb8a56acc2b9db19f68fd3c3201046b3824d5ba689f99864328710cb" + - "467195eb37d84f539e49f859316b32964dc3e47e36814ce94d6c56dd02733b1d0802f7ff" + - "4eebdbbd2927dcf580f16cbc290f91e81b53cb365e7223f1d6e20a88ea064104875e0145" + - "672b20fc14829d51ca122f5f5d77d3ad6c83889c55c7dc43680ba2fe3cef8b05dbcabdc0" + - "d3e09aaf9725597f8c858c2fa38c0d6aed2e6318194420dd1a1137445d13e1c97ab47896" + - "17a4e08925f46f867b72e3a4dc1f08cb870b2b0717f7207faa0ac512e628a029aba7457a" + - "e63dcf3281e2162d9349a08204ba308204b6308204b23082039aa003020102020101300d" + - "06092a864886f70d010105050030818c310b300906035504061302494c31163014060355" + - "040a130d5374617274436f6d204c74642e312b3029060355040b13225365637572652044" + - "69676974616c204365727469666963617465205369676e696e6731383036060355040313" + - "2f5374617274436f6d20436c6173732031205072696d61727920496e7465726d65646961" + - "746520536572766572204341301e170d3037313032353030323330365a170d3132313032" + - "333030323330365a304c310b300906035504061302494c31163014060355040a130d5374" + - "617274436f6d204c74642e312530230603550403131c5374617274436f6d20436c617373" + - "2031204f435350205369676e657230820122300d06092a864886f70d0101010500038201" + - "0f003082010a0282010100b9561b4c45318717178084e96e178df2255e18ed8d8ecc7c2b" + - "7b51a6c1c2e6bf0aa3603066f132fe10ae97b50e99fa24b83fc53dd2777496387d14e1c3" + - "a9b6a4933e2ac12413d085570a95b8147414a0bc007c7bcf222446ef7f1a156d7ea1c577" + - "fc5f0facdfd42eb0f5974990cb2f5cefebceef4d1bdc7ae5c1075c5a99a93171f2b0845b" + - "4ff0864e973fcfe32f9d7511ff87a3e943410c90a4493a306b6944359340a9ca96f02b66" + - "ce67f028df2980a6aaee8d5d5d452b8b0eb93f923cc1e23fcccbdbe7ffcb114d08fa7a6a" + - "3c404f825d1a0e715935cf623a8c7b59670014ed0622f6089a9447a7a19010f7fe58f841" + - "29a2765ea367824d1c3bb2fda308530203010001a382015c30820158300c0603551d1301" + - "01ff04023000300b0603551d0f0404030203a8301e0603551d250417301506082b060105" + - "0507030906092b0601050507300105301d0603551d0e0416041445e0a36695414c5dd449" + - "bc00e33cdcdbd2343e173081a80603551d230481a030819d8014eb4234d098b0ab9ff41b" + - "6b08f7cc642eef0e2c45a18181a47f307d310b300906035504061302494c311630140603" + - "55040a130d5374617274436f6d204c74642e312b3029060355040b132253656375726520" + - "4469676974616c204365727469666963617465205369676e696e67312930270603550403" + - "13205374617274436f6d2043657274696669636174696f6e20417574686f726974798201" + - "0a30230603551d12041c301a8618687474703a2f2f7777772e737461727473736c2e636f" + - "6d2f302c06096086480186f842010d041f161d5374617274436f6d205265766f63617469" + - "6f6e20417574686f72697479300d06092a864886f70d01010505000382010100182d2215" + - "8f0fc0291324fa8574c49bb8ff2835085adcbf7b7fc4191c397ab6951328253fffe1e5ec" + - "2a7da0d50fca1a404e6968481366939e666c0a6209073eca57973e2fefa9ed1718e8176f" + - "1d85527ff522c08db702e3b2b180f1cbff05d98128252cf0f450f7dd2772f4188047f19d" + - "c85317366f94bc52d60f453a550af58e308aaab00ced33040b62bf37f5b1ab2a4f7f0f80" + - "f763bf4d707bc8841d7ad9385ee2a4244469260b6f2bf085977af9074796048ecc2f9d48" + - "a1d24ce16e41a9941568fec5b42771e118f16c106a54ccc339a4b02166445a167902e75e" + - "6d8620b0825dcd18a069b90fd851d10fa8effd409deec02860d26d8d833f304b10669b42" - -const startComHex = "308206343082041ca003020102020118300d06092a864886f70d0101050500307d310b30" + - "0906035504061302494c31163014060355040a130d5374617274436f6d204c74642e312b" + - "3029060355040b1322536563757265204469676974616c20436572746966696361746520" + - "5369676e696e6731293027060355040313205374617274436f6d20436572746966696361" + - "74696f6e20417574686f72697479301e170d3037313032343230353431375a170d313731" + - "3032343230353431375a30818c310b300906035504061302494c31163014060355040a13" + - "0d5374617274436f6d204c74642e312b3029060355040b13225365637572652044696769" + - "74616c204365727469666963617465205369676e696e67313830360603550403132f5374" + - "617274436f6d20436c6173732031205072696d61727920496e7465726d65646961746520" + - "53657276657220434130820122300d06092a864886f70d01010105000382010f00308201" + - "0a0282010100b689c6acef09527807ac9263d0f44418188480561f91aee187fa3250b4d3" + - "4706f0e6075f700e10f71dc0ce103634855a0f92ac83c6ac58523fba38e8fce7a724e240" + - "a60876c0926e9e2a6d4d3f6e61200adb59ded27d63b33e46fefa215118d7cd30a6ed076e" + - "3b7087b4f9faebee823c056f92f7a4dc0a301e9373fe07cad75f809d225852ae06da8b87" + - "2369b0e42ad8ea83d2bdf371db705a280faf5a387045123f304dcd3baf17e50fcba0a95d" + - "48aab16150cb34cd3c5cc30be810c08c9bf0030362feb26c3e720eee1c432ac9480e5739" + - "c43121c810c12c87fe5495521f523c31129b7fe7c0a0a559d5e28f3ef0d5a8e1d77031a9" + - "c4b3cfaf6d532f06f4a70203010001a38201ad308201a9300f0603551d130101ff040530" + - "030101ff300e0603551d0f0101ff040403020106301d0603551d0e04160414eb4234d098" + - "b0ab9ff41b6b08f7cc642eef0e2c45301f0603551d230418301680144e0bef1aa4405ba5" + - "17698730ca346843d041aef2306606082b06010505070101045a3058302706082b060105" + - "05073001861b687474703a2f2f6f6373702e737461727473736c2e636f6d2f6361302d06" + - "082b060105050730028621687474703a2f2f7777772e737461727473736c2e636f6d2f73" + - "667363612e637274305b0603551d1f045430523027a025a0238621687474703a2f2f7777" + - "772e737461727473736c2e636f6d2f73667363612e63726c3027a025a023862168747470" + - "3a2f2f63726c2e737461727473736c2e636f6d2f73667363612e63726c3081800603551d" + - "20047930773075060b2b0601040181b5370102013066302e06082b060105050702011622" + - "687474703a2f2f7777772e737461727473736c2e636f6d2f706f6c6963792e7064663034" + - "06082b060105050702011628687474703a2f2f7777772e737461727473736c2e636f6d2f" + - "696e7465726d6564696174652e706466300d06092a864886f70d01010505000382020100" + - "2109493ea5886ee00b8b48da314d8ff75657a2e1d36257e9b556f38545753be5501f048b" + - "e6a05a3ee700ae85d0fbff200364cbad02e1c69172f8a34dd6dee8cc3fa18aa2e37c37a7" + - "c64f8f35d6f4d66e067bdd21d9cf56ffcb302249fe8904f385e5aaf1e71fe875904dddf9" + - "46f74234f745580c110d84b0c6da5d3ef9019ee7e1da5595be741c7bfc4d144fac7e5547" + - "7d7bf4a50d491e95e8f712c1ccff76a62547d0f37535be97b75816ebaa5c786fec5330af" + - "ea044dcca902e3f0b60412f630b1113d904e5664d7dc3c435f7339ef4baf87ebf6fe6888" + - "4472ead207c669b0c1a18bef1749d761b145485f3b2021e95bb2ccf4d7e931f50b15613b" + - "7a94e3ebd9bc7f94ae6ae3626296a8647cb887f399327e92a252bebbf865cfc9f230fc8b" + - "c1c2a696d75f89e15c3480f58f47072fb491bfb1a27e5f4b5ad05b9f248605515a690365" + - "434971c5e06f94346bf61bd8a9b04c7e53eb8f48dfca33b548fa364a1a53a6330cd089cd" + - "4915cd89313c90c072d7654b52358a461144b93d8e2865a63e799e5c084429adb035112e" + - "214eb8d2e7103e5d8483b3c3c2e4d2c6fd094b7409ddf1b3d3193e800da20b19f038e7c5" + - "c2afe223db61e29d5c6e2089492e236ab262c145b49faf8ba7f1223bf87de290d07a19fb" + - "4a4ce3d27d5f4a8303ed27d6239e6b8db459a2d9ef6c8229dd75193c3f4c108defbb7527" + - "d2ae83a7a8ce5ba7" - -const ocspResponseWithoutCertHex = "308201d40a0100a08201cd308201c906092b0601050507300101048201ba3082" + - "01b630819fa2160414884451ff502a695e2d88f421bad90cf2cecbea7c180f3230313330" + - "3631383037323434335a30743072304a300906052b0e03021a0500041448b60d38238df8" + - "456e4ee5843ea394111802979f0414884451ff502a695e2d88f421bad90cf2cecbea7c02" + - "1100f78b13b946fc9635d8ab49de9d2148218000180f3230313330363138303732343433" + - "5aa011180f32303133303632323037323434335a300d06092a864886f70d010105050003" + - "82010100103e18b3d297a5e7a6c07a4fc52ac46a15c0eba96f3be17f0ffe84de5b8c8e05" + - "5a8f577586a849dc4abd6440eb6fedde4622451e2823c1cbf3558b4e8184959c9fe96eff" + - "8bc5f95866c58c6d087519faabfdae37e11d9874f1bc0db292208f645dd848185e4dd38b" + - "6a8547dfa7b74d514a8470015719064d35476b95bebb03d4d2845c5ca15202d2784878f2" + - "0f904c24f09736f044609e9c271381713400e563023d212db422236440c6f377bbf24b2b" + - "9e7dec8698e36a8df68b7592ad3489fb2937afb90eb85d2aa96b81c94c25057dbd4759d9" + - "20a1a65c7f0b6427a224b3c98edd96b9b61f706099951188b0289555ad30a216fb774651" + - "5a35fca2e054dfa8" - -// PKIX nonce extension -var ocspExtensionOID = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 48, 1, 2} -var ocspExtensionValueHex = "0403000000" - -const ocspResponseWithCriticalExtensionHex = "308204fe0a0100a08204f7308204f306092b0601050507300101048204e4308204e03081" + - "dba003020100a11b3019311730150603550403130e4f43535020526573706f6e64657218" + - "0f32303136303130343137303130305a3081a53081a23049300906052b0e03021a050004" + - "14c0fe0278fc99188891b3f212e9c7e1b21ab7bfc004140dfc1df0a9e0f01ce7f2b21317" + - "7e6f8d157cd4f60210017f77deb3bcbb235d44ccc7dba62e72a116180f32303130303730" + - "373135303130355aa0030a0101180f32303130303730373135303130355aa011180f3230" + - "3130303730373138333531375aa1193017301506092b06010505073001020101ff040504" + - "03000000300d06092a864886f70d01010b0500038201010031c730ca60a7a0d92d8e4010" + - "911b469de95b4d27e89de6537552436237967694f76f701cf6b45c932bd308bca4a8d092" + - "5c604ba94796903091d9e6c000178e72c1f0a24a277dd262835af5d17d3f9d7869606c9f" + - "e7c8e708a41645699895beee38bfa63bb46296683761c5d1d65439b8ab868dc3017c9eeb" + - "b70b82dbf3a31c55b457d48bb9e82b335ed49f445042eaf606b06a3e0639824924c89c63" + - "eccddfe85e6694314138b2536f5e15e07085d0f6e26d4b2f8244bab0d70de07283ac6384" + - "a0501fc3dea7cf0adfd4c7f34871080900e252ddc403e3f0265f2a704af905d3727504ed" + - "28f3214a219d898a022463c78439799ca81c8cbafdbcec34ea937cd6a08202ea308202e6" + - "308202e2308201caa003020102020101300d06092a864886f70d01010b05003019311730" + - "150603550403130e4f43535020526573706f6e646572301e170d31353031333031353530" + - "33335a170d3136303133303135353033335a3019311730150603550403130e4f43535020" + - "526573706f6e64657230820122300d06092a864886f70d01010105000382010f00308201" + - "0a0282010100e8155f2d3e6f2e8d14c62a788bd462f9f844e7a6977c83ef1099f0f6616e" + - "c5265b56f356e62c5400f0b06a2e7945a82752c636df32a895152d6074df1701dc6ccfbc" + - "bec75a70bd2b55ae2be7e6cad3b5fd4cd5b7790ab401a436d3f5f346074ffde8a99d5b72" + - "3350f0a112076614b12ef79c78991b119453445acf2416ab0046b540db14c9fc0f27b898" + - "9ad0f63aa4b8aefc91aa8a72160c36307c60fec78a93d3fddf4259902aa77e7332971c7d" + - "285b6a04f648993c6922a3e9da9adf5f81508c3228791843e5d49f24db2f1290bafd97e6" + - "55b1049a199f652cd603c4fafa330c390b0da78fbbc67e8fa021cbd74eb96222b12ace31" + - "a77dcf920334dc94581b0203010001a3353033300e0603551d0f0101ff04040302078030" + - "130603551d25040c300a06082b06010505070309300c0603551d130101ff04023000300d" + - "06092a864886f70d01010b05000382010100718012761b5063e18f0dc44644d8e6ab8612" + - "31c15fd5357805425d82aec1de85bf6d3e30fce205e3e3b8b795bbe52e40a439286d2288" + - "9064f4aeeb150359b9425f1da51b3a5c939018555d13ac42c565a0603786a919328f3267" + - "09dce52c22ad958ecb7873b9771d1148b1c4be2efe80ba868919fc9f68b6090c2f33c156" + - "d67156e42766a50b5d51e79637b7e58af74c2a951b1e642fa7741fec982cc937de37eff5" + - "9e2005d5939bfc031589ca143e6e8ab83f40ee08cc20a6b4a95a318352c28d18528dcaf9" + - "66705de17afa19d6e8ae91ddf33179d16ebb6ac2c69cae8373d408ebf8c55308be6c04d9" + - "3a25439a94299a65a709756c7a3e568be049d5c38839" - -const ocspResponseWithExtensionHex = "308204fb0a0100a08204f4308204f006092b0601050507300101048204e1308204dd3081" + - "d8a003020100a11b3019311730150603550403130e4f43535020526573706f6e64657218" + - "0f32303136303130343136353930305a3081a230819f3049300906052b0e03021a050004" + - "14c0fe0278fc99188891b3f212e9c7e1b21ab7bfc004140dfc1df0a9e0f01ce7f2b21317" + - "7e6f8d157cd4f60210017f77deb3bcbb235d44ccc7dba62e72a116180f32303130303730" + - "373135303130355aa0030a0101180f32303130303730373135303130355aa011180f3230" + - "3130303730373138333531375aa1163014301206092b0601050507300102040504030000" + - "00300d06092a864886f70d01010b05000382010100c09a33e0b2324c852421bb83f85ac9" + - "9113f5426012bd2d2279a8166e9241d18a33c870894250622ffc7ed0c4601b16d624f90b" + - "779265442cdb6868cf40ab304ab4b66e7315ed02cf663b1601d1d4751772b31bc299db23" + - "9aebac78ed6797c06ed815a7a8d18d63cfbb609cafb47ec2e89e37db255216eb09307848" + - "d01be0a3e943653c78212b96ff524b74c9ec456b17cdfb950cc97645c577b2e09ff41dde" + - "b03afb3adaa381cc0f7c1d95663ef22a0f72f2c45613ae8e2b2d1efc96e8463c7d1d8a1d" + - "7e3b35df8fe73a301fc3f804b942b2b3afa337ff105fc1462b7b1c1d75eb4566c8665e59" + - "f80393b0adbf8004ff6c3327ed34f007cb4a3348a7d55e06e3a08202ea308202e6308202" + - "e2308201caa003020102020101300d06092a864886f70d01010b05003019311730150603" + - "550403130e4f43535020526573706f6e646572301e170d3135303133303135353033335a" + - "170d3136303133303135353033335a3019311730150603550403130e4f43535020526573" + - "706f6e64657230820122300d06092a864886f70d01010105000382010f003082010a0282" + - "010100e8155f2d3e6f2e8d14c62a788bd462f9f844e7a6977c83ef1099f0f6616ec5265b" + - "56f356e62c5400f0b06a2e7945a82752c636df32a895152d6074df1701dc6ccfbcbec75a" + - "70bd2b55ae2be7e6cad3b5fd4cd5b7790ab401a436d3f5f346074ffde8a99d5b723350f0" + - "a112076614b12ef79c78991b119453445acf2416ab0046b540db14c9fc0f27b8989ad0f6" + - "3aa4b8aefc91aa8a72160c36307c60fec78a93d3fddf4259902aa77e7332971c7d285b6a" + - "04f648993c6922a3e9da9adf5f81508c3228791843e5d49f24db2f1290bafd97e655b104" + - "9a199f652cd603c4fafa330c390b0da78fbbc67e8fa021cbd74eb96222b12ace31a77dcf" + - "920334dc94581b0203010001a3353033300e0603551d0f0101ff04040302078030130603" + - "551d25040c300a06082b06010505070309300c0603551d130101ff04023000300d06092a" + - "864886f70d01010b05000382010100718012761b5063e18f0dc44644d8e6ab861231c15f" + - "d5357805425d82aec1de85bf6d3e30fce205e3e3b8b795bbe52e40a439286d22889064f4" + - "aeeb150359b9425f1da51b3a5c939018555d13ac42c565a0603786a919328f326709dce5" + - "2c22ad958ecb7873b9771d1148b1c4be2efe80ba868919fc9f68b6090c2f33c156d67156" + - "e42766a50b5d51e79637b7e58af74c2a951b1e642fa7741fec982cc937de37eff59e2005" + - "d5939bfc031589ca143e6e8ab83f40ee08cc20a6b4a95a318352c28d18528dcaf966705d" + - "e17afa19d6e8ae91ddf33179d16ebb6ac2c69cae8373d408ebf8c55308be6c04d93a2543" + - "9a94299a65a709756c7a3e568be049d5c38839" - -const ocspRequestHex = "3051304f304d304b3049300906052b0e03021a05000414c0fe0278fc99188891b3f212e9" + - "c7e1b21ab7bfc004140dfc1df0a9e0f01ce7f2b213177e6f8d157cd4f60210017f77deb3" + - "bcbb235d44ccc7dba62e72" - -const leafCertHex = "308203c830820331a0030201020210017f77deb3bcbb235d44ccc7dba62e72300d06092a" + - "864886f70d01010505003081ba311f301d060355040a1316566572695369676e20547275" + - "7374204e6574776f726b31173015060355040b130e566572695369676e2c20496e632e31" + - "333031060355040b132a566572695369676e20496e7465726e6174696f6e616c20536572" + - "766572204341202d20436c617373203331493047060355040b13407777772e7665726973" + - "69676e2e636f6d2f43505320496e636f72702e6279205265662e204c494142494c495459" + - "204c54442e286329393720566572695369676e301e170d3132303632313030303030305a" + - "170d3133313233313233353935395a3068310b3009060355040613025553311330110603" + - "550408130a43616c69666f726e6961311230100603550407130950616c6f20416c746f31" + - "173015060355040a130e46616365626f6f6b2c20496e632e311730150603550403140e2a" + - "2e66616365626f6f6b2e636f6d30819f300d06092a864886f70d010101050003818d0030" + - "818902818100ae94b171e2deccc1693e051063240102e0689ae83c39b6b3e74b97d48d7b" + - "23689100b0b496ee62f0e6d356bcf4aa0f50643402f5d1766aa972835a7564723f39bbef" + - "5290ded9bcdbf9d3d55dfad23aa03dc604c54d29cf1d4b3bdbd1a809cfae47b44c7eae17" + - "c5109bee24a9cf4a8d911bb0fd0415ae4c3f430aa12a557e2ae10203010001a382011e30" + - "82011a30090603551d130402300030440603551d20043d303b3039060b6086480186f845" + - "01071703302a302806082b06010505070201161c68747470733a2f2f7777772e76657269" + - "7369676e2e636f6d2f727061303c0603551d1f043530333031a02fa02d862b687474703a" + - "2f2f535652496e746c2d63726c2e766572697369676e2e636f6d2f535652496e746c2e63" + - "726c301d0603551d250416301406082b0601050507030106082b06010505070302300b06" + - "03551d0f0404030205a0303406082b0601050507010104283026302406082b0601050507" + - "30018618687474703a2f2f6f6373702e766572697369676e2e636f6d30270603551d1104" + - "20301e820e2a2e66616365626f6f6b2e636f6d820c66616365626f6f6b2e636f6d300d06" + - "092a864886f70d0101050500038181005b6c2b75f8ed30aa51aad36aba595e555141951f" + - "81a53b447910ac1f76ff78fc2781616b58f3122afc1c87010425e9ed43df1a7ba6498060" + - "67e2688af03db58c7df4ee03309a6afc247ccb134dc33e54c6bc1d5133a532a73273b1d7" + - "9cadc08e7e1a83116d34523340b0305427a21742827c98916698ee7eaf8c3bdd71700817" - -const issuerCertHex = "30820383308202eca003020102021046fcebbab4d02f0f926098233f93078f300d06092a" + - "864886f70d0101050500305f310b300906035504061302555331173015060355040a130e" + - "566572695369676e2c20496e632e31373035060355040b132e436c617373203320507562" + - "6c6963205072696d6172792043657274696669636174696f6e20417574686f7269747930" + - "1e170d3937303431373030303030305a170d3136313032343233353935395a3081ba311f" + - "301d060355040a1316566572695369676e205472757374204e6574776f726b3117301506" + - "0355040b130e566572695369676e2c20496e632e31333031060355040b132a5665726953" + - "69676e20496e7465726e6174696f6e616c20536572766572204341202d20436c61737320" + - "3331493047060355040b13407777772e766572697369676e2e636f6d2f43505320496e63" + - "6f72702e6279205265662e204c494142494c495459204c54442e28632939372056657269" + - "5369676e30819f300d06092a864886f70d010101050003818d0030818902818100d88280" + - "e8d619027d1f85183925a2652be1bfd405d3bce6363baaf04c6c5bb6e7aa3c734555b2f1" + - "bdea9742ed9a340a15d4a95cf54025ddd907c132b2756cc4cabba3fe56277143aa63f530" + - "3e9328e5faf1093bf3b74d4e39f75c495ab8c11dd3b28afe70309542cbfe2b518b5a3c3a" + - "f9224f90b202a7539c4f34e7ab04b27b6f0203010001a381e33081e0300f0603551d1304" + - "0830060101ff02010030440603551d20043d303b3039060b6086480186f8450107010130" + - "2a302806082b06010505070201161c68747470733a2f2f7777772e766572697369676e2e" + - "636f6d2f43505330340603551d25042d302b06082b0601050507030106082b0601050507" + - "030206096086480186f8420401060a6086480186f845010801300b0603551d0f04040302" + - "0106301106096086480186f842010104040302010630310603551d1f042a30283026a024" + - "a0228620687474703a2f2f63726c2e766572697369676e2e636f6d2f706361332e63726c" + - "300d06092a864886f70d010105050003818100408e4997968a73dd8e4def3e61b7caa062" + - "adf40e0abb753de26ed82cc7bff4b98c369bcaa2d09c724639f6a682036511c4bcbf2da6" + - "f5d93b0ab598fab378b91ef22b4c62d5fdb27a1ddf33fd73f9a5d82d8c2aead1fcb028b6" + - "e94948134b838a1b487b24f738de6f4154b8ab576b06dfc7a2d4a9f6f136628088f28b75" + - "d68071" - -// Key and certificate for the OCSP responder were not taken from the Thawte -// responder, since CreateResponse requires that we have the private key. -// Instead, they were generated randomly. -const responderPrivateKeyHex = "308204a40201000282010100e8155f2d3e6f2e8d14c62a788bd462f9f844e7a6977c83ef" + - "1099f0f6616ec5265b56f356e62c5400f0b06a2e7945a82752c636df32a895152d6074df" + - "1701dc6ccfbcbec75a70bd2b55ae2be7e6cad3b5fd4cd5b7790ab401a436d3f5f346074f" + - "fde8a99d5b723350f0a112076614b12ef79c78991b119453445acf2416ab0046b540db14" + - "c9fc0f27b8989ad0f63aa4b8aefc91aa8a72160c36307c60fec78a93d3fddf4259902aa7" + - "7e7332971c7d285b6a04f648993c6922a3e9da9adf5f81508c3228791843e5d49f24db2f" + - "1290bafd97e655b1049a199f652cd603c4fafa330c390b0da78fbbc67e8fa021cbd74eb9" + - "6222b12ace31a77dcf920334dc94581b02030100010282010100bcf0b93d7238bda329a8" + - "72e7149f61bcb37c154330ccb3f42a85c9002c2e2bdea039d77d8581cd19bed94078794e" + - "56293d601547fc4bf6a2f9002fe5772b92b21b254403b403585e3130cc99ccf08f0ef81a" + - "575b38f597ba4660448b54f44bfbb97072b5a2bf043bfeca828cf7741d13698e3f38162b" + - "679faa646b82abd9a72c5c7d722c5fc577a76d2c2daac588accad18516d1bbad10b0dfa2" + - "05cfe246b59e28608a43942e1b71b0c80498075121de5b900d727c31c42c78cf1db5c0aa" + - "5b491e10ea4ed5c0962aaf2ae025dd81fa4ce490d9d6b4a4465411d8e542fc88617e5695" + - "1aa4fc8ea166f2b4d0eb89ef17f2b206bd5f1014bf8fe0e71fe62f2cccf102818100f2dc" + - "ddf878d553286daad68bac4070a82ffec3dc4666a2750f47879eec913f91836f1d976b60" + - "daf9356e078446dafab5bd2e489e5d64f8572ba24a4ba4f3729b5e106c4dd831cc2497a7" + - "e6c7507df05cb64aeb1bbc81c1e340d58b5964cf39cff84ea30c29ec5d3f005ee1362698" + - "07395037955955655292c3e85f6187fa1f9502818100f4a33c102630840705f8c778a47b" + - "87e8da31e68809af981ac5e5999cf1551685d761cdf0d6520361b99aebd5777a940fa64d" + - "327c09fa63746fbb3247ec73a86edf115f1fe5c83598db803881ade71c33c6e956118345" + - "497b98b5e07bb5be75971465ec78f2f9467e1b74956ca9d4c7c3e314e742a72d8b33889c" + - "6c093a466cef0281801d3df0d02124766dd0be98349b19eb36a508c4e679e793ba0a8bef" + - "4d786888c1e9947078b1ea28938716677b4ad8c5052af12eb73ac194915264a913709a0b" + - "7b9f98d4a18edd781a13d49899f91c20dbd8eb2e61d991ba19b5cdc08893f5cb9d39e5a6" + - "0629ea16d426244673b1b3ee72bd30e41fac8395acac40077403de5efd028180050731dd" + - "d71b1a2b96c8d538ba90bb6b62c8b1c74c03aae9a9f59d21a7a82b0d572ef06fa9c807bf" + - "c373d6b30d809c7871df96510c577421d9860c7383fda0919ece19996b3ca13562159193" + - "c0c246471e287f975e8e57034e5136aaf44254e2650def3d51292474c515b1588969112e" + - "0a85cc77073e9d64d2c2fc497844284b02818100d71d63eabf416cf677401ebf965f8314" + - "120b568a57dd3bd9116c629c40dc0c6948bab3a13cc544c31c7da40e76132ef5dd3f7534" + - "45a635930c74326ae3df0edd1bfb1523e3aa259873ac7cf1ac31151ec8f37b528c275622" + - "48f99b8bed59fd4da2576aa6ee20d93a684900bf907e80c66d6e2261ae15e55284b4ed9d" + - "6bdaa059" - -const responderCertHex = "308202e2308201caa003020102020101300d06092a864886f70d01010b05003019311730" + - "150603550403130e4f43535020526573706f6e646572301e170d31353031333031353530" + - "33335a170d3136303133303135353033335a3019311730150603550403130e4f43535020" + - "526573706f6e64657230820122300d06092a864886f70d01010105000382010f00308201" + - "0a0282010100e8155f2d3e6f2e8d14c62a788bd462f9f844e7a6977c83ef1099f0f6616e" + - "c5265b56f356e62c5400f0b06a2e7945a82752c636df32a895152d6074df1701dc6ccfbc" + - "bec75a70bd2b55ae2be7e6cad3b5fd4cd5b7790ab401a436d3f5f346074ffde8a99d5b72" + - "3350f0a112076614b12ef79c78991b119453445acf2416ab0046b540db14c9fc0f27b898" + - "9ad0f63aa4b8aefc91aa8a72160c36307c60fec78a93d3fddf4259902aa77e7332971c7d" + - "285b6a04f648993c6922a3e9da9adf5f81508c3228791843e5d49f24db2f1290bafd97e6" + - "55b1049a199f652cd603c4fafa330c390b0da78fbbc67e8fa021cbd74eb96222b12ace31" + - "a77dcf920334dc94581b0203010001a3353033300e0603551d0f0101ff04040302078030" + - "130603551d25040c300a06082b06010505070309300c0603551d130101ff04023000300d" + - "06092a864886f70d01010b05000382010100718012761b5063e18f0dc44644d8e6ab8612" + - "31c15fd5357805425d82aec1de85bf6d3e30fce205e3e3b8b795bbe52e40a439286d2288" + - "9064f4aeeb150359b9425f1da51b3a5c939018555d13ac42c565a0603786a919328f3267" + - "09dce52c22ad958ecb7873b9771d1148b1c4be2efe80ba868919fc9f68b6090c2f33c156" + - "d67156e42766a50b5d51e79637b7e58af74c2a951b1e642fa7741fec982cc937de37eff5" + - "9e2005d5939bfc031589ca143e6e8ab83f40ee08cc20a6b4a95a318352c28d18528dcaf9" + - "66705de17afa19d6e8ae91ddf33179d16ebb6ac2c69cae8373d408ebf8c55308be6c04d9" + - "3a25439a94299a65a709756c7a3e568be049d5c38839" - -const errorResponseHex = "30030a0101" diff --git a/vendor/golang.org/x/crypto/openpgp/armor/armor.go b/vendor/golang.org/x/crypto/openpgp/armor/armor.go deleted file mode 100644 index 592d186..0000000 --- a/vendor/golang.org/x/crypto/openpgp/armor/armor.go +++ /dev/null @@ -1,219 +0,0 @@ -// 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. -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 -} - -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 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 - 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 { - if 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/armor_test.go b/vendor/golang.org/x/crypto/openpgp/armor/armor_test.go deleted file mode 100644 index 9334e94..0000000 --- a/vendor/golang.org/x/crypto/openpgp/armor/armor_test.go +++ /dev/null @@ -1,95 +0,0 @@ -// 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 ( - "bytes" - "hash/adler32" - "io/ioutil" - "testing" -) - -func TestDecodeEncode(t *testing.T) { - buf := bytes.NewBuffer([]byte(armorExample1)) - result, err := Decode(buf) - if err != nil { - t.Error(err) - } - expectedType := "PGP SIGNATURE" - if result.Type != expectedType { - t.Errorf("result.Type: got:%s want:%s", result.Type, expectedType) - } - if len(result.Header) != 1 { - t.Errorf("len(result.Header): got:%d want:1", len(result.Header)) - } - v, ok := result.Header["Version"] - if !ok || v != "GnuPG v1.4.10 (GNU/Linux)" { - t.Errorf("result.Header: got:%#v", result.Header) - } - - contents, err := ioutil.ReadAll(result.Body) - if err != nil { - t.Error(err) - } - - if adler32.Checksum(contents) != 0x27b144be { - t.Errorf("contents: got: %x", contents) - } - - buf = bytes.NewBuffer(nil) - w, err := Encode(buf, result.Type, result.Header) - if err != nil { - t.Error(err) - } - _, err = w.Write(contents) - if err != nil { - t.Error(err) - } - w.Close() - - if !bytes.Equal(buf.Bytes(), []byte(armorExample1)) { - t.Errorf("got: %s\nwant: %s", string(buf.Bytes()), armorExample1) - } -} - -func TestLongHeader(t *testing.T) { - buf := bytes.NewBuffer([]byte(armorLongLine)) - result, err := Decode(buf) - if err != nil { - t.Error(err) - return - } - value, ok := result.Header["Version"] - if !ok { - t.Errorf("missing Version header") - } - if value != longValueExpected { - t.Errorf("got: %s want: %s", value, longValueExpected) - } -} - -const armorExample1 = `-----BEGIN PGP SIGNATURE----- -Version: GnuPG v1.4.10 (GNU/Linux) - -iJwEAAECAAYFAk1Fv/0ACgkQo01+GMIMMbsYTwQAiAw+QAaNfY6WBdplZ/uMAccm -4g+81QPmTSGHnetSb6WBiY13kVzK4HQiZH8JSkmmroMLuGeJwsRTEL4wbjRyUKEt -p1xwUZDECs234F1xiG5enc5SGlRtP7foLBz9lOsjx+LEcA4sTl5/2eZR9zyFZqWW -TxRjs+fJCIFuo71xb1g= -=/teI ------END PGP SIGNATURE-----` - -const armorLongLine = `-----BEGIN PGP SIGNATURE----- -Version: 0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz - -iQEcBAABAgAGBQJMtFESAAoJEKsQXJGvOPsVj40H/1WW6jaMXv4BW+1ueDSMDwM8 -kx1fLOXbVM5/Kn5LStZNt1jWWnpxdz7eq3uiqeCQjmqUoRde3YbB2EMnnwRbAhpp -cacnAvy9ZQ78OTxUdNW1mhX5bS6q1MTEJnl+DcyigD70HG/yNNQD7sOPMdYQw0TA -byQBwmLwmTsuZsrYqB68QyLHI+DUugn+kX6Hd2WDB62DKa2suoIUIHQQCd/ofwB3 -WfCYInXQKKOSxu2YOg2Eb4kLNhSMc1i9uKUWAH+sdgJh7NBgdoE4MaNtBFkHXRvv -okWuf3+xA9ksp1npSY/mDvgHijmjvtpRDe6iUeqfCn8N9u9CBg8geANgaG8+QA4= -=wfQG ------END PGP SIGNATURE-----` - -const longValueExpected = "0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz" diff --git a/vendor/golang.org/x/crypto/openpgp/armor/encode.go b/vendor/golang.org/x/crypto/openpgp/armor/encode.go deleted file mode 100644 index 6f07582..0000000 --- a/vendor/golang.org/x/crypto/openpgp/armor/encode.go +++ /dev/null @@ -1,160 +0,0 @@ -// 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 deleted file mode 100644 index e601e38..0000000 --- a/vendor/golang.org/x/crypto/openpgp/canonical_text.go +++ /dev/null @@ -1,59 +0,0 @@ -// 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/canonical_text_test.go b/vendor/golang.org/x/crypto/openpgp/canonical_text_test.go deleted file mode 100644 index 8f3ba2a..0000000 --- a/vendor/golang.org/x/crypto/openpgp/canonical_text_test.go +++ /dev/null @@ -1,52 +0,0 @@ -// 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 ( - "bytes" - "testing" -) - -type recordingHash struct { - buf *bytes.Buffer -} - -func (r recordingHash) Write(b []byte) (n int, err error) { - return r.buf.Write(b) -} - -func (r recordingHash) Sum(in []byte) []byte { - return append(in, r.buf.Bytes()...) -} - -func (r recordingHash) Reset() { - panic("shouldn't be called") -} - -func (r recordingHash) Size() int { - panic("shouldn't be called") -} - -func (r recordingHash) BlockSize() int { - panic("shouldn't be called") -} - -func testCanonicalText(t *testing.T, input, expected string) { - r := recordingHash{bytes.NewBuffer(nil)} - c := NewCanonicalTextHash(r) - c.Write([]byte(input)) - result := c.Sum(nil) - if expected != string(result) { - t.Errorf("input: %x got: %x want: %x", input, result, expected) - } -} - -func TestCanonicalText(t *testing.T) { - testCanonicalText(t, "foo\n", "foo\r\n") - testCanonicalText(t, "foo", "foo") - testCanonicalText(t, "foo\r\n", "foo\r\n") - testCanonicalText(t, "foo\r\nbar", "foo\r\nbar") - testCanonicalText(t, "foo\r\nbar\n\n", "foo\r\nbar\r\n\r\n") -} diff --git a/vendor/golang.org/x/crypto/openpgp/clearsign/clearsign.go b/vendor/golang.org/x/crypto/openpgp/clearsign/clearsign.go deleted file mode 100644 index def4cab..0000000 --- a/vendor/golang.org/x/crypto/openpgp/clearsign/clearsign.go +++ /dev/null @@ -1,376 +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. - -// 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. -package clearsign // import "golang.org/x/crypto/openpgp/clearsign" - -import ( - "bufio" - "bytes" - "crypto" - "hash" - "io" - "net/textproto" - "strconv" - - "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 message 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. -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. - _, rest = getLine(rest) - - 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 - } - - i := bytes.Index(line, []byte{':'}) - if i == -1 { - return nil, data - } - - key, val := line[0:i], line[i+1:] - key = bytes.TrimSpace(key) - val = bytes.TrimSpace(val) - b.Headers.Add(string(key), string(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 - h hash.Hash - hashType crypto.Hash - - atBeginningOfLine bool - isFirstLine bool - - whitespace []byte - byteBuf []byte // a one byte buffer to save allocations - - privateKey *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.h.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.h.Write(d.byteBuf) - d.atBeginningOfLine = false - } else if b == '\n' { - // Nothing to do because we delay writing CRLF to the hash. - } else { - d.h.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.h.Write(d.whitespace) - if _, err = d.buffered.Write(d.whitespace); err != nil { - return - } - d.whitespace = d.whitespace[:0] - } - d.h.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 - } - } - sig := new(packet.Signature) - sig.SigType = packet.SigTypeText - sig.PubKeyAlgo = d.privateKey.PubKeyAlgo - sig.Hash = d.hashType - sig.CreationTime = d.config.Now() - sig.IssuerKeyId = &d.privateKey.KeyId - - if err = sig.Sign(d.h, d.privateKey, d.config); err != nil { - return - } - - out, err := armor.Encode(d.buffered, "PGP SIGNATURE", nil) - if 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) { - if privateKey.Encrypted { - return nil, errors.InvalidArgumentError("signing key is encrypted") - } - - 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))) - } - h := hashType.New() - - 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, - h: h, - hashType: hashType, - - atBeginningOfLine: true, - isFirstLine: true, - - byteBuf: make([]byte, 1), - - privateKey: privateKey, - 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/clearsign/clearsign_test.go b/vendor/golang.org/x/crypto/openpgp/clearsign/clearsign_test.go deleted file mode 100644 index 2c09480..0000000 --- a/vendor/golang.org/x/crypto/openpgp/clearsign/clearsign_test.go +++ /dev/null @@ -1,210 +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. - -package clearsign - -import ( - "bytes" - "golang.org/x/crypto/openpgp" - "testing" -) - -func testParse(t *testing.T, input []byte, expected, expectedPlaintext string) { - b, rest := Decode(input) - if b == nil { - t.Fatal("failed to decode clearsign message") - } - if !bytes.Equal(rest, []byte("trailing")) { - t.Errorf("unexpected remaining bytes returned: %s", string(rest)) - } - if b.ArmoredSignature.Type != "PGP SIGNATURE" { - t.Errorf("bad armor type, got:%s, want:PGP SIGNATURE", b.ArmoredSignature.Type) - } - if !bytes.Equal(b.Bytes, []byte(expected)) { - t.Errorf("bad body, got:%x want:%x", b.Bytes, expected) - } - - if !bytes.Equal(b.Plaintext, []byte(expectedPlaintext)) { - t.Errorf("bad plaintext, got:%x want:%x", b.Plaintext, expectedPlaintext) - } - - keyring, err := openpgp.ReadArmoredKeyRing(bytes.NewBufferString(signingKey)) - if err != nil { - t.Errorf("failed to parse public key: %s", err) - } - - if _, err := openpgp.CheckDetachedSignature(keyring, bytes.NewBuffer(b.Bytes), b.ArmoredSignature.Body); err != nil { - t.Errorf("failed to check signature: %s", err) - } -} - -func TestParse(t *testing.T) { - testParse(t, clearsignInput, "Hello world\r\nline 2", "Hello world\nline 2\n") - testParse(t, clearsignInput2, "\r\n\r\n(This message has a couple of blank lines at the start and end.)\r\n\r\n", "\n\n(This message has a couple of blank lines at the start and end.)\n\n\n") -} - -func TestParseInvalid(t *testing.T) { - if b, _ := Decode(clearsignInput3); b != nil { - t.Fatal("decoded a bad clearsigned message without any error") - } -} - -func TestParseWithNoNewlineAtEnd(t *testing.T) { - input := clearsignInput - input = input[:len(input)-len("trailing")-1] - b, rest := Decode(input) - if b == nil { - t.Fatal("failed to decode clearsign message") - } - if len(rest) > 0 { - t.Errorf("unexpected remaining bytes returned: %s", string(rest)) - } -} - -var signingTests = []struct { - in, signed, plaintext string -}{ - {"", "", ""}, - {"a", "a", "a\n"}, - {"a\n", "a", "a\n"}, - {"-a\n", "-a", "-a\n"}, - {"--a\nb", "--a\r\nb", "--a\nb\n"}, - // leading whitespace - {" a\n", " a", " a\n"}, - {" a\n", " a", " a\n"}, - // trailing whitespace (should be stripped) - {"a \n", "a", "a\n"}, - {"a ", "a", "a\n"}, - // whitespace-only lines (should be stripped) - {" \n", "", "\n"}, - {" ", "", "\n"}, - {"a\n \n \nb\n", "a\r\n\r\n\r\nb", "a\n\n\nb\n"}, -} - -func TestSigning(t *testing.T) { - keyring, err := openpgp.ReadArmoredKeyRing(bytes.NewBufferString(signingKey)) - if err != nil { - t.Errorf("failed to parse public key: %s", err) - } - - for i, test := range signingTests { - var buf bytes.Buffer - - plaintext, err := Encode(&buf, keyring[0].PrivateKey, nil) - if err != nil { - t.Errorf("#%d: error from Encode: %s", i, err) - continue - } - if _, err := plaintext.Write([]byte(test.in)); err != nil { - t.Errorf("#%d: error from Write: %s", i, err) - continue - } - if err := plaintext.Close(); err != nil { - t.Fatalf("#%d: error from Close: %s", i, err) - continue - } - - b, _ := Decode(buf.Bytes()) - if b == nil { - t.Errorf("#%d: failed to decode clearsign message", i) - continue - } - if !bytes.Equal(b.Bytes, []byte(test.signed)) { - t.Errorf("#%d: bad result, got:%x, want:%x", i, b.Bytes, test.signed) - continue - } - if !bytes.Equal(b.Plaintext, []byte(test.plaintext)) { - t.Errorf("#%d: bad result, got:%x, want:%x", i, b.Plaintext, test.plaintext) - continue - } - - if _, err := openpgp.CheckDetachedSignature(keyring, bytes.NewBuffer(b.Bytes), b.ArmoredSignature.Body); err != nil { - t.Errorf("#%d: failed to check signature: %s", i, err) - } - } -} - -var clearsignInput = []byte(` -;lasjlkfdsa - ------BEGIN PGP SIGNED MESSAGE----- -Hash: SHA1 - -Hello world -line 2 ------BEGIN PGP SIGNATURE----- -Version: GnuPG v1.4.10 (GNU/Linux) - -iJwEAQECAAYFAk8kMuEACgkQO9o98PRieSpMsAQAhmY/vwmNpflrPgmfWsYhk5O8 -pjnBUzZwqTDoDeINjZEoPDSpQAHGhjFjgaDx/Gj4fAl0dM4D0wuUEBb6QOrwflog -2A2k9kfSOMOtk0IH/H5VuFN1Mie9L/erYXjTQIptv9t9J7NoRBMU0QOOaFU0JaO9 -MyTpno24AjIAGb+mH1U= -=hIJ6 ------END PGP SIGNATURE----- -trailing`) - -var clearsignInput2 = []byte(` -asdlfkjasdlkfjsadf - ------BEGIN PGP SIGNED MESSAGE----- -Hash: SHA256 - - - -(This message has a couple of blank lines at the start and end.) - - ------BEGIN PGP SIGNATURE----- -Version: GnuPG v1.4.11 (GNU/Linux) - -iJwEAQEIAAYFAlPpSREACgkQO9o98PRieSpZTAP+M8QUoCt/7Rf3YbXPcdzIL32v -pt1I+cMNeopzfLy0u4ioEFi8s5VkwpL1AFmirvgViCwlf82inoRxzZRiW05JQ5LI -ESEzeCoy2LIdRCQ2hcrG8pIUPzUO4TqO5D/dMbdHwNH4h5nNmGJUAEG6FpURlPm+ -qZg6BaTvOxepqOxnhVU= -=e+C6 ------END PGP SIGNATURE----- - -trailing`) - -var clearsignInput3 = []byte(` ------BEGIN PGP SIGNED MESSAGE----- -Hash: SHA256 - -(This message was truncated.) -`) - -var signingKey = `-----BEGIN PGP PRIVATE KEY BLOCK----- -Version: GnuPG v1.4.10 (GNU/Linux) - -lQHYBE2rFNoBBADFwqWQIW/DSqcB4yCQqnAFTJ27qS5AnB46ccAdw3u4Greeu3Bp -idpoHdjULy7zSKlwR1EA873dO/k/e11Ml3dlAFUinWeejWaK2ugFP6JjiieSsrKn -vWNicdCS4HTWn0X4sjl0ZiAygw6GNhqEQ3cpLeL0g8E9hnYzJKQ0LWJa0QARAQAB -AAP/TB81EIo2VYNmTq0pK1ZXwUpxCrvAAIG3hwKjEzHcbQznsjNvPUihZ+NZQ6+X -0HCfPAdPkGDCLCb6NavcSW+iNnLTrdDnSI6+3BbIONqWWdRDYJhqZCkqmG6zqSfL -IdkJgCw94taUg5BWP/AAeQrhzjChvpMQTVKQL5mnuZbUCeMCAN5qrYMP2S9iKdnk -VANIFj7656ARKt/nf4CBzxcpHTyB8+d2CtPDKCmlJP6vL8t58Jmih+kHJMvC0dzn -gr5f5+sCAOOe5gt9e0am7AvQWhdbHVfJU0TQJx+m2OiCJAqGTB1nvtBLHdJnfdC9 -TnXXQ6ZXibqLyBies/xeY2sCKL5qtTMCAKnX9+9d/5yQxRyrQUHt1NYhaXZnJbHx -q4ytu0eWz+5i68IYUSK69jJ1NWPM0T6SkqpB3KCAIv68VFm9PxqG1KmhSrQIVGVz -dCBLZXmIuAQTAQIAIgUCTasU2gIbAwYLCQgHAwIGFQgCCQoLBBYCAwECHgECF4AA -CgkQO9o98PRieSoLhgQAkLEZex02Qt7vGhZzMwuN0R22w3VwyYyjBx+fM3JFETy1 -ut4xcLJoJfIaF5ZS38UplgakHG0FQ+b49i8dMij0aZmDqGxrew1m4kBfjXw9B/v+ -eIqpODryb6cOSwyQFH0lQkXC040pjq9YqDsO5w0WYNXYKDnzRV0p4H1pweo2VDid -AdgETasU2gEEAN46UPeWRqKHvA99arOxee38fBt2CI08iiWyI8T3J6ivtFGixSqV -bRcPxYO/qLpVe5l84Nb3X71GfVXlc9hyv7CD6tcowL59hg1E/DC5ydI8K8iEpUmK -/UnHdIY5h8/kqgGxkY/T/hgp5fRQgW1ZoZxLajVlMRZ8W4tFtT0DeA+JABEBAAEA -A/0bE1jaaZKj6ndqcw86jd+QtD1SF+Cf21CWRNeLKnUds4FRRvclzTyUMuWPkUeX -TaNNsUOFqBsf6QQ2oHUBBK4VCHffHCW4ZEX2cd6umz7mpHW6XzN4DECEzOVksXtc -lUC1j4UB91DC/RNQqwX1IV2QLSwssVotPMPqhOi0ZLNY7wIA3n7DWKInxYZZ4K+6 -rQ+POsz6brEoRHwr8x6XlHenq1Oki855pSa1yXIARoTrSJkBtn5oI+f8AzrnN0BN -oyeQAwIA/7E++3HDi5aweWrViiul9cd3rcsS0dEnksPhvS0ozCJiHsq/6GFmy7J8 -QSHZPteedBnZyNp5jR+H7cIfVN3KgwH/Skq4PsuPhDq5TKK6i8Pc1WW8MA6DXTdU -nLkX7RGmMwjC0DBf7KWAlPjFaONAX3a8ndnz//fy1q7u2l9AZwrj1qa1iJ8EGAEC -AAkFAk2rFNoCGwwACgkQO9o98PRieSo2/QP/WTzr4ioINVsvN1akKuekmEMI3LAp -BfHwatufxxP1U+3Si/6YIk7kuPB9Hs+pRqCXzbvPRrI8NHZBmc8qIGthishdCYad -AHcVnXjtxrULkQFGbGvhKURLvS9WnzD/m1K2zzwxzkPTzT9/Yf06O6Mal5AdugPL -VrM0m72/jnpKo04= -=zNCn ------END PGP PRIVATE KEY BLOCK----- -` diff --git a/vendor/golang.org/x/crypto/openpgp/elgamal/elgamal.go b/vendor/golang.org/x/crypto/openpgp/elgamal/elgamal.go deleted file mode 100644 index 73f4fe3..0000000 --- a/vendor/golang.org/x/crypto/openpgp/elgamal/elgamal.go +++ /dev/null @@ -1,122 +0,0 @@ -// 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. -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) - s.ModInverse(s, priv.P) - 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/elgamal/elgamal_test.go b/vendor/golang.org/x/crypto/openpgp/elgamal/elgamal_test.go deleted file mode 100644 index c4f99f5..0000000 --- a/vendor/golang.org/x/crypto/openpgp/elgamal/elgamal_test.go +++ /dev/null @@ -1,49 +0,0 @@ -// 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 - -import ( - "bytes" - "crypto/rand" - "math/big" - "testing" -) - -// This is the 1024-bit MODP group from RFC 5114, section 2.1: -const primeHex = "B10B8F96A080E01DDE92DE5EAE5D54EC52C99FBCFB06A3C69A6A9DCA52D23B616073E28675A23D189838EF1E2EE652C013ECB4AEA906112324975C3CD49B83BFACCBDD7D90C4BD7098488E9C219A73724EFFD6FAE5644738FAA31A4FF55BCCC0A151AF5F0DC8B4BD45BF37DF365C1A65E68CFDA76D4DA708DF1FB2BC2E4A4371" - -const generatorHex = "A4D1CBD5C3FD34126765A442EFB99905F8104DD258AC507FD6406CFF14266D31266FEA1E5C41564B777E690F5504F213160217B4B01B886A5E91547F9E2749F4D7FBD7D3B9A92EE1909D0D2263F80A76A6A24C087A091F531DBF0A0169B6A28AD662A4D18E73AFA32D779D5918D08BC8858F4DCEF97C2A24855E6EEB22B3B2E5" - -func fromHex(hex string) *big.Int { - n, ok := new(big.Int).SetString(hex, 16) - if !ok { - panic("failed to parse hex number") - } - return n -} - -func TestEncryptDecrypt(t *testing.T) { - priv := &PrivateKey{ - PublicKey: PublicKey{ - G: fromHex(generatorHex), - P: fromHex(primeHex), - }, - X: fromHex("42"), - } - priv.Y = new(big.Int).Exp(priv.G, priv.X, priv.P) - - message := []byte("hello world") - c1, c2, err := Encrypt(rand.Reader, &priv.PublicKey, message) - if err != nil { - t.Errorf("error encrypting: %s", err) - } - message2, err := Decrypt(priv, c1, c2) - if err != nil { - t.Errorf("error decrypting: %s", err) - } - if !bytes.Equal(message2, message) { - t.Errorf("decryption failed, got: %x, want: %x", message2, message) - } -} diff --git a/vendor/golang.org/x/crypto/openpgp/errors/errors.go b/vendor/golang.org/x/crypto/openpgp/errors/errors.go deleted file mode 100644 index eb0550b..0000000 --- a/vendor/golang.org/x/crypto/openpgp/errors/errors.go +++ /dev/null @@ -1,72 +0,0 @@ -// 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. -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 deleted file mode 100644 index bfe3260..0000000 --- a/vendor/golang.org/x/crypto/openpgp/keys.go +++ /dev/null @@ -1,633 +0,0 @@ -// 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) " - 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 - } - } - - panic("unreachable") -} - -// 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") - } else { - e.PrimaryKey = &e.PrivateKey.PublicKey - } - } - - if !e.PrimaryKey.PubKeyAlgo.CanSign() { - return nil, errors.StructuralError("primary key cannot be used for signatures") - } - - var current *Identity - 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: - current = new(Identity) - current.Name = pkt.Id - current.UserId = pkt - e.Identities[pkt.Id] = current - - for { - p, err = packets.Next() - if err == io.EOF { - return nil, io.ErrUnexpectedEOF - } else if err != nil { - return nil, err - } - - sig, ok := p.(*packet.Signature) - if !ok { - return nil, errors.StructuralError("user ID packet not followed by self-signature") - } - - 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 nil, errors.StructuralError("user ID self-signature invalid: " + err.Error()) - } - current.SelfSignature = sig - break - } - current.Signatures = append(current.Signatures, sig) - } - 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 if current == nil { - return nil, errors.StructuralError("signature packet found before user id packet") - } else { - current.Signatures = append(current.Signatures, pkt) - } - 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 addSubkey(e *Entity, packets *packet.Reader, pub *packet.PublicKey, priv *packet.PrivateKey) error { - var subKey Subkey - subKey.PublicKey = pub - subKey.PrivateKey = priv - p, err := packets.Next() - if err == io.EOF { - return io.ErrUnexpectedEOF - } - if err != nil { - return errors.StructuralError("subkey signature invalid: " + err.Error()) - } - var ok bool - subKey.Sig, ok = p.(*packet.Signature) - if !ok { - return errors.StructuralError("subkey packet not followed by signature") - } - if subKey.Sig.SigType != packet.SigTypeSubkeyBinding && subKey.Sig.SigType != packet.SigTypeSubkeyRevocation { - return errors.StructuralError("subkey signature with wrong type") - } - err = e.PrimaryKey.VerifyKeySignature(subKey.PublicKey, subKey.Sig) - if err != nil { - return errors.StructuralError("subkey signature invalid: " + err.Error()) - } - e.Subkeys = append(e.Subkeys, subKey) - return nil -} - -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) { - currentTime := 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(currentTime, &signingPriv.PublicKey), - PrivateKey: packet.NewRSAPrivateKey(currentTime, signingPriv), - Identities: make(map[string]*Identity), - } - isPrimaryId := true - e.Identities[uid.Id] = &Identity{ - Name: uid.Name, - UserId: uid, - SelfSignature: &packet.Signature{ - CreationTime: currentTime, - SigType: packet.SigTypePositiveCert, - PubKeyAlgo: packet.PubKeyAlgoRSA, - Hash: config.Hash(), - IsPrimaryId: &isPrimaryId, - FlagsValid: true, - FlagSign: true, - FlagCertify: true, - IssuerKeyId: &e.PrimaryKey.KeyId, - }, - } - - e.Subkeys = make([]Subkey, 1) - e.Subkeys[0] = Subkey{ - PublicKey: packet.NewRSAPublicKey(currentTime, &encryptingPriv.PublicKey), - PrivateKey: packet.NewRSAPrivateKey(currentTime, encryptingPriv), - Sig: &packet.Signature{ - CreationTime: currentTime, - 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 - - return e, nil -} - -// SerializePrivate serializes an Entity, including private key material, to -// the given Writer. For now, it must only be used on an Entity returned from -// NewEntity. -// 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. (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/keys_test.go b/vendor/golang.org/x/crypto/openpgp/keys_test.go deleted file mode 100644 index d5e2056..0000000 --- a/vendor/golang.org/x/crypto/openpgp/keys_test.go +++ /dev/null @@ -1,370 +0,0 @@ -package openpgp - -import ( - "bytes" - "strings" - "testing" - "time" - - "golang.org/x/crypto/openpgp/errors" - "golang.org/x/crypto/openpgp/packet" -) - -func TestKeyExpiry(t *testing.T) { - kring, _ := ReadKeyRing(readerFromHex(expiringKeyHex)) - entity := kring[0] - - const timeFormat = "2006-01-02" - time1, _ := time.Parse(timeFormat, "2013-07-01") - - // The expiringKeyHex key is structured as: - // - // pub 1024R/5E237D8C created: 2013-07-01 expires: 2013-07-31 usage: SC - // sub 1024R/1ABB25A0 created: 2013-07-01 23:11:07 +0200 CEST expires: 2013-07-08 usage: E - // sub 1024R/96A672F5 created: 2013-07-01 23:11:23 +0200 CEST expires: 2013-07-31 usage: E - // - // So this should select the newest, non-expired encryption key. - key, _ := entity.encryptionKey(time1) - if id := key.PublicKey.KeyIdShortString(); id != "96A672F5" { - t.Errorf("Expected key 1ABB25A0 at time %s, but got key %s", time1.Format(timeFormat), id) - } - - // Once the first encryption subkey has expired, the second should be - // selected. - time2, _ := time.Parse(timeFormat, "2013-07-09") - key, _ = entity.encryptionKey(time2) - if id := key.PublicKey.KeyIdShortString(); id != "96A672F5" { - t.Errorf("Expected key 96A672F5 at time %s, but got key %s", time2.Format(timeFormat), id) - } - - // Once all the keys have expired, nothing should be returned. - time3, _ := time.Parse(timeFormat, "2013-08-01") - if key, ok := entity.encryptionKey(time3); ok { - t.Errorf("Expected no key at time %s, but got key %s", time3.Format(timeFormat), key.PublicKey.KeyIdShortString()) - } -} - -func TestMissingCrossSignature(t *testing.T) { - // This public key has a signing subkey, but the subkey does not - // contain a cross-signature. - keys, err := ReadArmoredKeyRing(bytes.NewBufferString(missingCrossSignatureKey)) - if len(keys) != 0 { - t.Errorf("Accepted key with missing cross signature") - } - if err == nil { - t.Fatal("Failed to detect error in keyring with missing cross signature") - } - structural, ok := err.(errors.StructuralError) - if !ok { - t.Fatalf("Unexpected class of error: %T. Wanted StructuralError", err) - } - const expectedMsg = "signing subkey is missing cross-signature" - if !strings.Contains(string(structural), expectedMsg) { - t.Fatalf("Unexpected error: %q. Expected it to contain %q", err, expectedMsg) - } -} - -func TestInvalidCrossSignature(t *testing.T) { - // This public key has a signing subkey, and the subkey has an - // embedded cross-signature. However, the cross-signature does - // not correctly validate over the primary and subkey. - keys, err := ReadArmoredKeyRing(bytes.NewBufferString(invalidCrossSignatureKey)) - if len(keys) != 0 { - t.Errorf("Accepted key with invalid cross signature") - } - if err == nil { - t.Fatal("Failed to detect error in keyring with an invalid cross signature") - } - structural, ok := err.(errors.StructuralError) - if !ok { - t.Fatalf("Unexpected class of error: %T. Wanted StructuralError", err) - } - const expectedMsg = "subkey signature invalid" - if !strings.Contains(string(structural), expectedMsg) { - t.Fatalf("Unexpected error: %q. Expected it to contain %q", err, expectedMsg) - } -} - -func TestGoodCrossSignature(t *testing.T) { - // This public key has a signing subkey, and the subkey has an - // embedded cross-signature which correctly validates over the - // primary and subkey. - keys, err := ReadArmoredKeyRing(bytes.NewBufferString(goodCrossSignatureKey)) - if err != nil { - t.Fatal(err) - } - if len(keys) != 1 { - t.Errorf("Failed to accept key with good cross signature, %d", len(keys)) - } - if len(keys[0].Subkeys) != 1 { - t.Errorf("Failed to accept good subkey, %d", len(keys[0].Subkeys)) - } -} - -// TestExternallyRevokableKey attempts to load and parse a key with a third party revocation permission. -func TestExternallyRevocableKey(t *testing.T) { - kring, _ := ReadKeyRing(readerFromHex(subkeyUsageHex)) - - // The 0xA42704B92866382A key can be revoked by 0xBE3893CB843D0FE70C - // according to this signature that appears within the key: - // :signature packet: algo 1, keyid A42704B92866382A - // version 4, created 1396409682, md5len 0, sigclass 0x1f - // digest algo 2, begin of digest a9 84 - // hashed subpkt 2 len 4 (sig created 2014-04-02) - // hashed subpkt 12 len 22 (revocation key: c=80 a=1 f=CE094AA433F7040BB2DDF0BE3893CB843D0FE70C) - // hashed subpkt 7 len 1 (not revocable) - // subpkt 16 len 8 (issuer key ID A42704B92866382A) - // data: [1024 bits] - - id := uint64(0xA42704B92866382A) - keys := kring.KeysById(id) - if len(keys) != 1 { - t.Errorf("Expected to find key id %X, but got %d matches", id, len(keys)) - } -} - -func TestKeyRevocation(t *testing.T) { - kring, _ := ReadKeyRing(readerFromHex(revokedKeyHex)) - - // revokedKeyHex contains these keys: - // pub 1024R/9A34F7C0 2014-03-25 [revoked: 2014-03-25] - // sub 1024R/1BA3CD60 2014-03-25 [revoked: 2014-03-25] - ids := []uint64{0xA401D9F09A34F7C0, 0x5CD3BE0A1BA3CD60} - - for _, id := range ids { - keys := kring.KeysById(id) - if len(keys) != 1 { - t.Errorf("Expected KeysById to find revoked key %X, but got %d matches", id, len(keys)) - } - keys = kring.KeysByIdUsage(id, 0) - if len(keys) != 0 { - t.Errorf("Expected KeysByIdUsage to filter out revoked key %X, but got %d matches", id, len(keys)) - } - } -} - -func TestSubkeyRevocation(t *testing.T) { - kring, _ := ReadKeyRing(readerFromHex(revokedSubkeyHex)) - - // revokedSubkeyHex contains these keys: - // pub 1024R/4EF7E4BECCDE97F0 2014-03-25 - // sub 1024R/D63636E2B96AE423 2014-03-25 - // sub 1024D/DBCE4EE19529437F 2014-03-25 - // sub 1024R/677815E371C2FD23 2014-03-25 [revoked: 2014-03-25] - validKeys := []uint64{0x4EF7E4BECCDE97F0, 0xD63636E2B96AE423, 0xDBCE4EE19529437F} - revokedKey := uint64(0x677815E371C2FD23) - - for _, id := range validKeys { - keys := kring.KeysById(id) - if len(keys) != 1 { - t.Errorf("Expected KeysById to find key %X, but got %d matches", id, len(keys)) - } - keys = kring.KeysByIdUsage(id, 0) - if len(keys) != 1 { - t.Errorf("Expected KeysByIdUsage to find key %X, but got %d matches", id, len(keys)) - } - } - - keys := kring.KeysById(revokedKey) - if len(keys) != 1 { - t.Errorf("Expected KeysById to find key %X, but got %d matches", revokedKey, len(keys)) - } - - keys = kring.KeysByIdUsage(revokedKey, 0) - if len(keys) != 0 { - t.Errorf("Expected KeysByIdUsage to filter out revoked key %X, but got %d matches", revokedKey, len(keys)) - } -} - -func TestKeyUsage(t *testing.T) { - kring, _ := ReadKeyRing(readerFromHex(subkeyUsageHex)) - - // subkeyUsageHex contains these keys: - // pub 1024R/2866382A created: 2014-04-01 expires: never usage: SC - // sub 1024R/936C9153 created: 2014-04-01 expires: never usage: E - // sub 1024R/64D5F5BB created: 2014-04-02 expires: never usage: E - // sub 1024D/BC0BA992 created: 2014-04-02 expires: never usage: S - certifiers := []uint64{0xA42704B92866382A} - signers := []uint64{0xA42704B92866382A, 0x42CE2C64BC0BA992} - encrypters := []uint64{0x09C0C7D9936C9153, 0xC104E98664D5F5BB} - - for _, id := range certifiers { - keys := kring.KeysByIdUsage(id, packet.KeyFlagCertify) - if len(keys) == 1 { - if keys[0].PublicKey.KeyId != id { - t.Errorf("Expected to find certifier key id %X, but got %X", id, keys[0].PublicKey.KeyId) - } - } else { - t.Errorf("Expected one match for certifier key id %X, but got %d matches", id, len(keys)) - } - } - - for _, id := range signers { - keys := kring.KeysByIdUsage(id, packet.KeyFlagSign) - if len(keys) == 1 { - if keys[0].PublicKey.KeyId != id { - t.Errorf("Expected to find signing key id %X, but got %X", id, keys[0].PublicKey.KeyId) - } - } else { - t.Errorf("Expected one match for signing key id %X, but got %d matches", id, len(keys)) - } - - // This keyring contains no encryption keys that are also good for signing. - keys = kring.KeysByIdUsage(id, packet.KeyFlagEncryptStorage|packet.KeyFlagEncryptCommunications) - if len(keys) != 0 { - t.Errorf("Unexpected match for encryption key id %X", id) - } - } - - for _, id := range encrypters { - keys := kring.KeysByIdUsage(id, packet.KeyFlagEncryptStorage|packet.KeyFlagEncryptCommunications) - if len(keys) == 1 { - if keys[0].PublicKey.KeyId != id { - t.Errorf("Expected to find encryption key id %X, but got %X", id, keys[0].PublicKey.KeyId) - } - } else { - t.Errorf("Expected one match for encryption key id %X, but got %d matches", id, len(keys)) - } - - // This keyring contains no encryption keys that are also good for signing. - keys = kring.KeysByIdUsage(id, packet.KeyFlagSign) - if len(keys) != 0 { - t.Errorf("Unexpected match for signing key id %X", id) - } - } -} - -func TestIdVerification(t *testing.T) { - kring, err := ReadKeyRing(readerFromHex(testKeys1And2PrivateHex)) - if err != nil { - t.Fatal(err) - } - if err := kring[1].PrivateKey.Decrypt([]byte("passphrase")); err != nil { - t.Fatal(err) - } - - const identity = "Test Key 1 (RSA)" - if err := kring[0].SignIdentity(identity, kring[1], nil); err != nil { - t.Fatal(err) - } - - ident, ok := kring[0].Identities[identity] - if !ok { - t.Fatal("identity missing from key after signing") - } - - checked := false - for _, sig := range ident.Signatures { - if sig.IssuerKeyId == nil || *sig.IssuerKeyId != kring[1].PrimaryKey.KeyId { - continue - } - - if err := kring[1].PrimaryKey.VerifyUserIdSignature(identity, kring[0].PrimaryKey, sig); err != nil { - t.Fatalf("error verifying new identity signature: %s", err) - } - checked = true - break - } - - if !checked { - t.Fatal("didn't find identity signature in Entity") - } -} - -const expiringKeyHex = "988d0451d1ec5d010400ba3385721f2dc3f4ab096b2ee867ab77213f0a27a8538441c35d2fa225b08798a1439a66a5150e6bdc3f40f5d28d588c712394c632b6299f77db8c0d48d37903fb72ebd794d61be6aa774688839e5fdecfe06b2684cc115d240c98c66cb1ef22ae84e3aa0c2b0c28665c1e7d4d044e7f270706193f5223c8d44e0d70b7b8da830011010001b40f4578706972792074657374206b657988be041301020028050251d1ec5d021b03050900278d00060b090807030206150802090a0b0416020301021e01021780000a091072589ad75e237d8c033503fd10506d72837834eb7f994117740723adc39227104b0d326a1161871c0b415d25b4aedef946ca77ea4c05af9c22b32cf98be86ab890111fced1ee3f75e87b7cc3c00dc63bbc85dfab91c0dc2ad9de2c4d13a34659333a85c6acc1a669c5e1d6cecb0cf1e56c10e72d855ae177ddc9e766f9b2dda57ccbb75f57156438bbdb4e42b88d0451d1ec5d0104009c64906559866c5cb61578f5846a94fcee142a489c9b41e67b12bb54cfe86eb9bc8566460f9a720cb00d6526fbccfd4f552071a8e3f7744b1882d01036d811ee5a3fb91a1c568055758f43ba5d2c6a9676b012f3a1a89e47bbf624f1ad571b208f3cc6224eb378f1645dd3d47584463f9eadeacfd1ce6f813064fbfdcc4b5a53001101000188a504180102000f021b0c050251d1f06b050900093e89000a091072589ad75e237d8c20e00400ab8310a41461425b37889c4da28129b5fae6084fafbc0a47dd1adc74a264c6e9c9cc125f40462ee1433072a58384daef88c961c390ed06426a81b464a53194c4e291ddd7e2e2ba3efced01537d713bd111f48437bde2363446200995e8e0d4e528dda377fd1e8f8ede9c8e2198b393bd86852ce7457a7e3daf74d510461a5b77b88d0451d1ece8010400b3a519f83ab0010307e83bca895170acce8964a044190a2b368892f7a244758d9fc193482648acb1fb9780d28cc22d171931f38bb40279389fc9bf2110876d4f3db4fcfb13f22f7083877fe56592b3b65251312c36f83ffcb6d313c6a17f197dd471f0712aad15a8537b435a92471ba2e5b0c72a6c72536c3b567c558d7b6051001101000188a504180102000f021b0c050251d1f07b050900279091000a091072589ad75e237d8ce69e03fe286026afacf7c97ee20673864d4459a2240b5655219950643c7dba0ac384b1d4359c67805b21d98211f7b09c2a0ccf6410c8c04d4ff4a51293725d8d6570d9d8bb0e10c07d22357caeb49626df99c180be02d77d1fe8ed25e7a54481237646083a9f89a11566cd20b9e995b1487c5f9e02aeb434f3a1897cd416dd0a87861838da3e9e" -const subkeyUsageHex = "988d04533a52bc010400d26af43085558f65b9e7dbc90cb9238015259aed5e954637adcfa2181548b2d0b60c65f1f42ec5081cbf1bc0a8aa4900acfb77070837c58f26012fbce297d70afe96e759ad63531f0037538e70dbf8e384569b9720d99d8eb39d8d0a2947233ed242436cb6ac7dfe74123354b3d0119b5c235d3dd9c9d6c004f8ffaf67ad8583001101000188b7041f010200210502533b8552170c8001ce094aa433f7040bb2ddf0be3893cb843d0fe70c020700000a0910a42704b92866382aa98404009d63d916a27543da4221c60087c33f1c44bec9998c5438018ed370cca4962876c748e94b73eb39c58eb698063f3fd6346d58dd2a11c0247934c4a9d71f24754f7468f96fb24c3e791dd2392b62f626148ad724189498cbf993db2df7c0cdc2d677c35da0f16cb16c9ce7c33b4de65a4a91b1d21a130ae9cc26067718910ef8e2b417556d627261203c756d627261407379642e65642e61753e88b80413010200220502533a52bc021b03060b090807030206150802090a0b0416020301021e01021780000a0910a42704b92866382a47840400c0c2bd04f5fca586de408b395b3c280a278259c93eaaa8b79a53b97003f8ed502a8a00446dd9947fb462677e4fcac0dac2f0701847d15130aadb6cd9e0705ea0cf5f92f129136c7be21a718d46c8e641eb7f044f2adae573e11ae423a0a9ca51324f03a8a2f34b91fa40c3cc764bee4dccadedb54c768ba0469b683ea53f1c29b88d04533a52bc01040099c92a5d6f8b744224da27bc2369127c35269b58bec179de6bbc038f749344222f85a31933224f26b70243c4e4b2d242f0c4777eaef7b5502f9dad6d8bf3aaeb471210674b74de2d7078af497d55f5cdad97c7bedfbc1b41e8065a97c9c3d344b21fc81d27723af8e374bc595da26ea242dccb6ae497be26eea57e563ed517e90011010001889f0418010200090502533a52bc021b0c000a0910a42704b92866382afa1403ff70284c2de8a043ff51d8d29772602fa98009b7861c540535f874f2c230af8caf5638151a636b21f8255003997ccd29747fdd06777bb24f9593bd7d98a3e887689bf902f999915fcc94625ae487e5d13e6616f89090ebc4fdc7eb5cad8943e4056995bb61c6af37f8043016876a958ec7ebf39c43d20d53b7f546cfa83e8d2604b88d04533b8283010400c0b529316dbdf58b4c54461e7e669dc11c09eb7f73819f178ccd4177b9182b91d138605fcf1e463262fabefa73f94a52b5e15d1904635541c7ea540f07050ce0fb51b73e6f88644cec86e91107c957a114f69554548a85295d2b70bd0b203992f76eb5d493d86d9eabcaa7ef3fc7db7e458438db3fcdb0ca1cc97c638439a9170011010001889f0418010200090502533b8283021b0c000a0910a42704b92866382adc6d0400cfff6258485a21675adb7a811c3e19ebca18851533f75a7ba317950b9997fda8d1a4c8c76505c08c04b6c2cc31dc704d33da36a21273f2b388a1a706f7c3378b66d887197a525936ed9a69acb57fe7f718133da85ec742001c5d1864e9c6c8ea1b94f1c3759cebfd93b18606066c063a63be86085b7e37bdbc65f9a915bf084bb901a204533b85cd110400aed3d2c52af2b38b5b67904b0ef73d6dd7aef86adb770e2b153cd22489654dcc91730892087bb9856ae2d9f7ed1eb48f214243fe86bfe87b349ebd7c30e630e49c07b21fdabf78b7a95c8b7f969e97e3d33f2e074c63552ba64a2ded7badc05ce0ea2be6d53485f6900c7860c7aa76560376ce963d7271b9b54638a4028b573f00a0d8854bfcdb04986141568046202192263b9b67350400aaa1049dbc7943141ef590a70dcb028d730371d92ea4863de715f7f0f16d168bd3dc266c2450457d46dcbbf0b071547e5fbee7700a820c3750b236335d8d5848adb3c0da010e998908dfd93d961480084f3aea20b247034f8988eccb5546efaa35a92d0451df3aaf1aee5aa36a4c4d462c760ecd9cebcabfbe1412b1f21450f203fd126687cd486496e971a87fd9e1a8a765fe654baa219a6871ab97768596ab05c26c1aeea8f1a2c72395a58dbc12ef9640d2b95784e974a4d2d5a9b17c25fedacfe551bda52602de8f6d2e48443f5dd1a2a2a8e6a5e70ecdb88cd6e766ad9745c7ee91d78cc55c3d06536b49c3fee6c3d0b6ff0fb2bf13a314f57c953b8f4d93bf88e70418010200090502533b85cd021b0200520910a42704b92866382a47200419110200060502533b85cd000a091042ce2c64bc0ba99214b2009e26b26852c8b13b10c35768e40e78fbbb48bd084100a0c79d9ea0844fa5853dd3c85ff3ecae6f2c9dd6c557aa04008bbbc964cd65b9b8299d4ebf31f41cc7264b8cf33a00e82c5af022331fac79efc9563a822497ba012953cefe2629f1242fcdcb911dbb2315985bab060bfd58261ace3c654bdbbe2e8ed27a46e836490145c86dc7bae15c011f7e1ffc33730109b9338cd9f483e7cef3d2f396aab5bd80efb6646d7e778270ee99d934d187dd98" -const revokedKeyHex = "988d045331ce82010400c4fdf7b40a5477f206e6ee278eaef888ca73bf9128a9eef9f2f1ddb8b7b71a4c07cfa241f028a04edb405e4d916c61d6beabc333813dc7b484d2b3c52ee233c6a79b1eea4e9cc51596ba9cd5ac5aeb9df62d86ea051055b79d03f8a4fa9f38386f5bd17529138f3325d46801514ea9047977e0829ed728e68636802796801be10011010001889f04200102000905025331d0e3021d03000a0910a401d9f09a34f7c042aa040086631196405b7e6af71026b88e98012eab44aa9849f6ef3fa930c7c9f23deaedba9db1538830f8652fb7648ec3fcade8dbcbf9eaf428e83c6cbcc272201bfe2fbb90d41963397a7c0637a1a9d9448ce695d9790db2dc95433ad7be19eb3de72dacf1d6db82c3644c13eae2a3d072b99bb341debba012c5ce4006a7d34a1f4b94b444526567205265766f6b657220283c52656727732022424d204261726973746122204b657920262530305c303e5c29203c72656740626d626172697374612e636f2e61753e88b704130102002205025331ce82021b03060b090807030206150802090a0b0416020301021e01021780000a0910a401d9f09a34f7c0019c03f75edfbeb6a73e7225ad3cc52724e2872e04260d7daf0d693c170d8c4b243b8767bc7785763533febc62ec2600c30603c433c095453ede59ff2fcabeb84ce32e0ed9d5cf15ffcbc816202b64370d4d77c1e9077d74e94a16fb4fa2e5bec23a56d7a73cf275f91691ae1801a976fcde09e981a2f6327ac27ea1fecf3185df0d56889c04100102000605025331cfb5000a0910fe9645554e8266b64b4303fc084075396674fb6f778d302ac07cef6bc0b5d07b66b2004c44aef711cbac79617ef06d836b4957522d8772dd94bf41a2f4ac8b1ee6d70c57503f837445a74765a076d07b829b8111fc2a918423ddb817ead7ca2a613ef0bfb9c6b3562aec6c3cf3c75ef3031d81d95f6563e4cdcc9960bcb386c5d757b104fcca5fe11fc709df884604101102000605025331cfe7000a09107b15a67f0b3ddc0317f6009e360beea58f29c1d963a22b962b80788c3fa6c84e009d148cfde6b351469b8eae91187eff07ad9d08fcaab88d045331ce820104009f25e20a42b904f3fa555530fe5c46737cf7bd076c35a2a0d22b11f7e0b61a69320b768f4a80fe13980ce380d1cfc4a0cd8fbe2d2e2ef85416668b77208baa65bf973fe8e500e78cc310d7c8705cdb34328bf80e24f0385fce5845c33bc7943cf6b11b02348a23da0bf6428e57c05135f2dc6bd7c1ce325d666d5a5fd2fd5e410011010001889f04180102000905025331ce82021b0c000a0910a401d9f09a34f7c0418003fe34feafcbeaef348a800a0d908a7a6809cc7304017d820f70f0474d5e23cb17e38b67dc6dca282c6ca00961f4ec9edf2738d0f087b1d81e4871ef08e1798010863afb4eac4c44a376cb343be929c5be66a78cfd4456ae9ec6a99d97f4e1c3ff3583351db2147a65c0acef5c003fb544ab3a2e2dc4d43646f58b811a6c3a369d1f" -const revokedSubkeyHex = "988d04533121f6010400aefc803a3e4bb1a61c86e8a86d2726c6a43e0079e9f2713f1fa017e9854c83877f4aced8e331d675c67ea83ddab80aacbfa0b9040bb12d96f5a3d6be09455e2a76546cbd21677537db941cab710216b6d24ec277ee0bd65b910f416737ed120f6b93a9d3b306245c8cfd8394606fdb462e5cf43c551438d2864506c63367fc890011010001b41d416c696365203c616c69636540626d626172697374612e636f2e61753e88bb041301020025021b03060b090807030206150802090a0b0416020301021e01021780050253312798021901000a09104ef7e4beccde97f015a803ff5448437780f63263b0df8442a995e7f76c221351a51edd06f2063d8166cf3157aada4923dfc44aa0f2a6a4da5cf83b7fe722ba8ab416c976e77c6b5682e7f1069026673bd0de56ba06fd5d7a9f177607f277d9b55ff940a638c3e68525c67517e2b3d976899b93ca267f705b3e5efad7d61220e96b618a4497eab8d04403d23f8846041011020006050253312910000a09107b15a67f0b3ddc03d96e009f50b6365d86c4be5d5e9d0ea42d5e56f5794c617700a0ab274e19c2827780016d23417ce89e0a2c0d987d889c04100102000605025331cf7a000a0910a401d9f09a34f7c0ee970400aca292f213041c9f3b3fc49148cbda9d84afee6183c8dd6c5ff2600b29482db5fecd4303797be1ee6d544a20a858080fec43412061c9a71fae4039fd58013b4ae341273e6c66ad4c7cdd9e68245bedb260562e7b166f2461a1032f2b38c0e0e5715fb3d1656979e052b55ca827a76f872b78a9fdae64bc298170bfcebedc1271b41a416c696365203c616c696365407379646973702e6f722e61753e88b804130102002205025331278b021b03060b090807030206150802090a0b0416020301021e01021780000a09104ef7e4beccde97f06a7003fa03c3af68d272ebc1fa08aa72a03b02189c26496a2833d90450801c4e42c5b5f51ad96ce2d2c9cef4b7c02a6a2fcf1412d6a2d486098eb762f5010a201819c17fd2888aec8eda20c65a3b75744de7ee5cc8ac7bfc470cbe3cb982720405a27a3c6a8c229cfe36905f881b02ed5680f6a8f05866efb9d6c5844897e631deb949ca8846041011020006050253312910000a09107b15a67f0b3ddc0347bc009f7fa35db59147469eb6f2c5aaf6428accb138b22800a0caa2f5f0874bacc5909c652a57a31beda65eddd5889c04100102000605025331cf7a000a0910a401d9f09a34f7c0316403ff46f2a5c101256627f16384d34a38fb47a6c88ba60506843e532d91614339fccae5f884a5741e7582ffaf292ba38ee10a270a05f139bde3814b6a077e8cd2db0f105ebea2a83af70d385f13b507fac2ad93ff79d84950328bb86f3074745a8b7f9b64990fb142e2a12976e27e8d09a28dc5621f957ac49091116da410ac3cbde1b88d04533121f6010400cbd785b56905e4192e2fb62a720727d43c4fa487821203cf72138b884b78b701093243e1d8c92a0248a6c0203a5a88693da34af357499abacaf4b3309c640797d03093870a323b4b6f37865f6eaa2838148a67df4735d43a90ca87942554cdf1c4a751b1e75f9fd4ce4e97e278d6c1c7ed59d33441df7d084f3f02beb68896c70011010001889f0418010200090502533121f6021b0c000a09104ef7e4beccde97f0b98b03fc0a5ccf6a372995835a2f5da33b282a7d612c0ab2a97f59cf9fff73e9110981aac2858c41399afa29624a7fd8a0add11654e3d882c0fd199e161bdad65e5e2548f7b68a437ea64293db1246e3011cbb94dc1bcdeaf0f2539bd88ff16d95547144d97cead6a8c5927660a91e6db0d16eb36b7b49a3525b54d1644e65599b032b7eb901a204533127a0110400bd3edaa09eff9809c4edc2c2a0ebe52e53c50a19c1e49ab78e6167bf61473bb08f2050d78a5cbbc6ed66aff7b42cd503f16b4a0b99fa1609681fca9b7ce2bbb1a5b3864d6cdda4d7ef7849d156d534dea30fb0efb9e4cf8959a2b2ce623905882d5430b995a15c3b9fe92906086788b891002924f94abe139b42cbbfaaabe42f00a0b65dc1a1ad27d798adbcb5b5ad02d2688c89477b03ff4eebb6f7b15a73b96a96bed201c0e5e4ea27e4c6e2dd1005b94d4b90137a5b1cf5e01c6226c070c4cc999938101578877ee76d296b9aab8246d57049caacf489e80a3f40589cade790a020b1ac146d6f7a6241184b8c7fcde680eae3188f5dcbe846d7f7bdad34f6fcfca08413e19c1d5df83fc7c7c627d493492e009c2f52a80400a2fe82de87136fd2e8845888c4431b032ba29d9a29a804277e31002a8201fb8591a3e55c7a0d0881496caf8b9fb07544a5a4879291d0dc026a0ea9e5bd88eb4aa4947bbd694b25012e208a250d65ddc6f1eea59d3aed3b4ec15fcab85e2afaa23a40ab1ef9ce3e11e1bc1c34a0e758e7aa64deb8739276df0af7d4121f834a9b88e70418010200090502533127a0021b02005209104ef7e4beccde97f047200419110200060502533127a0000a0910dbce4ee19529437fe045009c0b32f5ead48ee8a7e98fac0dea3d3e6c0e2c552500a0ad71fadc5007cfaf842d9b7db3335a8cdad15d3d1a6404009b08e2c68fe8f3b45c1bb72a4b3278cdf3012aa0f229883ad74aa1f6000bb90b18301b2f85372ca5d6b9bf478d235b733b1b197d19ccca48e9daf8e890cb64546b4ce1b178faccfff07003c172a2d4f5ebaba9f57153955f3f61a9b80a4f5cb959908f8b211b03b7026a8a82fc612bfedd3794969bcf458c4ce92be215a1176ab88d045331d144010400a5063000c5aaf34953c1aa3bfc95045b3aab9882b9a8027fecfe2142dc6b47ba8aca667399990244d513dd0504716908c17d92c65e74219e004f7b83fc125e575dd58efec3ab6dd22e3580106998523dea42ec75bf9aa111734c82df54630bebdff20fe981cfc36c76f865eb1c2fb62c9e85bc3a6e5015a361a2eb1c8431578d0011010001889f04280102000905025331d433021d03000a09104ef7e4beccde97f02e5503ff5e0630d1b65291f4882b6d40a29da4616bb5088717d469fbcc3648b8276de04a04988b1f1b9f3e18f52265c1f8b6c85861691c1a6b8a3a25a1809a0b32ad330aec5667cb4262f4450649184e8113849b05e5ad06a316ea80c001e8e71838190339a6e48bbde30647bcf245134b9a97fa875c1d83a9862cae87ffd7e2c4ce3a1b89013d04180102000905025331d144021b0200a809104ef7e4beccde97f09d2004190102000605025331d144000a0910677815e371c2fd23522203fe22ab62b8e7a151383cea3edd3a12995693911426f8ccf125e1f6426388c0010f88d9ca7da2224aee8d1c12135998640c5e1813d55a93df472faae75bef858457248db41b4505827590aeccf6f9eb646da7f980655dd3050c6897feddddaca90676dee856d66db8923477d251712bb9b3186b4d0114daf7d6b59272b53218dd1da94a03ff64006fcbe71211e5daecd9961fba66cdb6de3f914882c58ba5beddeba7dcb950c1156d7fba18c19ea880dccc800eae335deec34e3b84ac75ffa24864f782f87815cda1c0f634b3dd2fa67cea30811d21723d21d9551fa12ccbcfa62b6d3a15d01307b99925707992556d50065505b090aadb8579083a20fe65bd2a270da9b011" -const missingCrossSignatureKey = `-----BEGIN PGP PUBLIC KEY BLOCK----- -Charset: UTF-8 - -mQENBFMYynYBCACVOZ3/e8Bm2b9KH9QyIlHGo/i1bnkpqsgXj8tpJ2MIUOnXMMAY -ztW7kKFLCmgVdLIC0vSoLA4yhaLcMojznh/2CcUglZeb6Ao8Gtelr//Rd5DRfPpG -zqcfUo+m+eO1co2Orabw0tZDfGpg5p3AYl0hmxhUyYSc/xUq93xL1UJzBFgYXY54 -QsM8dgeQgFseSk/YvdP5SMx1ev+eraUyiiUtWzWrWC1TdyRa5p4UZg6Rkoppf+WJ -QrW6BWrhAtqATHc8ozV7uJjeONjUEq24roRc/OFZdmQQGK6yrzKnnbA6MdHhqpdo -9kWDcXYb7pSE63Lc+OBa5X2GUVvXJLS/3nrtABEBAAG0F2ludmFsaWQtc2lnbmlu -Zy1zdWJrZXlziQEoBBMBAgASBQJTnKB5AhsBAgsHAhUIAh4BAAoJEO3UDQUIHpI/ -dN4H/idX4FQ1LIZCnpHS/oxoWQWfpRgdKAEM0qCqjMgiipJeEwSQbqjTCynuh5/R -JlODDz85ABR06aoF4l5ebGLQWFCYifPnJZ/Yf5OYcMGtb7dIbqxWVFL9iLMO/oDL -ioI3dotjPui5e+2hI9pVH1UHB/bZ/GvMGo6Zg0XxLPolKQODMVjpjLAQ0YJ3spew -RAmOGre6tIvbDsMBnm8qREt7a07cBJ6XK7xjxYaZHQBiHVxyEWDa6gyANONx8duW -/fhQ/zDTnyVM/ik6VO0Ty9BhPpcEYLFwh5c1ilFari1ta3e6qKo6ZGa9YMk/REhu -yBHd9nTkI+0CiQUmbckUiVjDKKe5AQ0EUxjKdgEIAJcXQeP+NmuciE99YcJoffxv -2gVLU4ZXBNHEaP0mgaJ1+tmMD089vUQAcyGRvw8jfsNsVZQIOAuRxY94aHQhIRHR -bUzBN28ofo/AJJtfx62C15xt6fDKRV6HXYqAiygrHIpEoRLyiN69iScUsjIJeyFL -C8wa72e8pSL6dkHoaV1N9ZH/xmrJ+k0vsgkQaAh9CzYufncDxcwkoP+aOlGtX1gP -WwWoIbz0JwLEMPHBWvDDXQcQPQTYQyj+LGC9U6f9VZHN25E94subM1MjuT9OhN9Y -MLfWaaIc5WyhLFyQKW2Upofn9wSFi8ubyBnv640Dfd0rVmaWv7LNTZpoZ/GbJAMA -EQEAAYkBHwQYAQIACQUCU5ygeQIbAgAKCRDt1A0FCB6SP0zCB/sEzaVR38vpx+OQ -MMynCBJrakiqDmUZv9xtplY7zsHSQjpd6xGflbU2n+iX99Q+nav0ETQZifNUEd4N -1ljDGQejcTyKD6Pkg6wBL3x9/RJye7Zszazm4+toJXZ8xJ3800+BtaPoI39akYJm -+ijzbskvN0v/j5GOFJwQO0pPRAFtdHqRs9Kf4YanxhedB4dIUblzlIJuKsxFit6N -lgGRblagG3Vv2eBszbxzPbJjHCgVLR3RmrVezKOsZjr/2i7X+xLWIR0uD3IN1qOW -CXQxLBizEEmSNVNxsp7KPGTLnqO3bPtqFirxS9PJLIMPTPLNBY7ZYuPNTMqVIUWF -4artDmrG -=7FfJ ------END PGP PUBLIC KEY BLOCK-----` - -const invalidCrossSignatureKey = `-----BEGIN PGP PUBLIC KEY BLOCK----- - -mQENBFMYynYBCACVOZ3/e8Bm2b9KH9QyIlHGo/i1bnkpqsgXj8tpJ2MIUOnXMMAY -ztW7kKFLCmgVdLIC0vSoLA4yhaLcMojznh/2CcUglZeb6Ao8Gtelr//Rd5DRfPpG -zqcfUo+m+eO1co2Orabw0tZDfGpg5p3AYl0hmxhUyYSc/xUq93xL1UJzBFgYXY54 -QsM8dgeQgFseSk/YvdP5SMx1ev+eraUyiiUtWzWrWC1TdyRa5p4UZg6Rkoppf+WJ -QrW6BWrhAtqATHc8ozV7uJjeONjUEq24roRc/OFZdmQQGK6yrzKnnbA6MdHhqpdo -9kWDcXYb7pSE63Lc+OBa5X2GUVvXJLS/3nrtABEBAAG0F2ludmFsaWQtc2lnbmlu -Zy1zdWJrZXlziQEoBBMBAgASBQJTnKB5AhsBAgsHAhUIAh4BAAoJEO3UDQUIHpI/ -dN4H/idX4FQ1LIZCnpHS/oxoWQWfpRgdKAEM0qCqjMgiipJeEwSQbqjTCynuh5/R -JlODDz85ABR06aoF4l5ebGLQWFCYifPnJZ/Yf5OYcMGtb7dIbqxWVFL9iLMO/oDL -ioI3dotjPui5e+2hI9pVH1UHB/bZ/GvMGo6Zg0XxLPolKQODMVjpjLAQ0YJ3spew -RAmOGre6tIvbDsMBnm8qREt7a07cBJ6XK7xjxYaZHQBiHVxyEWDa6gyANONx8duW -/fhQ/zDTnyVM/ik6VO0Ty9BhPpcEYLFwh5c1ilFari1ta3e6qKo6ZGa9YMk/REhu -yBHd9nTkI+0CiQUmbckUiVjDKKe5AQ0EUxjKdgEIAIINDqlj7X6jYKc6DjwrOkjQ -UIRWbQQar0LwmNilehmt70g5DCL1SYm9q4LcgJJ2Nhxj0/5qqsYib50OSWMcKeEe -iRXpXzv1ObpcQtI5ithp0gR53YPXBib80t3bUzomQ5UyZqAAHzMp3BKC54/vUrSK -FeRaxDzNLrCeyI00+LHNUtwghAqHvdNcsIf8VRumK8oTm3RmDh0TyjASWYbrt9c8 -R1Um3zuoACOVy+mEIgIzsfHq0u7dwYwJB5+KeM7ZLx+HGIYdUYzHuUE1sLwVoELh -+SHIGHI1HDicOjzqgajShuIjj5hZTyQySVprrsLKiXS6NEwHAP20+XjayJ/R3tEA -EQEAAYkCPgQYAQIBKAUCU5ygeQIbAsBdIAQZAQIABgUCU5ygeQAKCRCpVlnFZmhO -52RJB/9uD1MSa0wjY6tHOIgquZcP3bHBvHmrHNMw9HR2wRCMO91ZkhrpdS3ZHtgb -u3/55etj0FdvDo1tb8P8FGSVtO5Vcwf5APM8sbbqoi8L951Q3i7qt847lfhu6sMl -w0LWFvPTOLHrliZHItPRjOltS1WAWfr2jUYhsU9ytaDAJmvf9DujxEOsN5G1YJep -54JCKVCkM/y585Zcnn+yxk/XwqoNQ0/iJUT9qRrZWvoeasxhl1PQcwihCwss44A+ -YXaAt3hbk+6LEQuZoYS73yR3WHj+42tfm7YxRGeubXfgCEz/brETEWXMh4pe0vCL -bfWrmfSPq2rDegYcAybxRQz0lF8PAAoJEO3UDQUIHpI/exkH/0vQfdHA8g/N4T6E -i6b1CUVBAkvtdJpCATZjWPhXmShOw62gkDw306vHPilL4SCvEEi4KzG72zkp6VsB -DSRcpxCwT4mHue+duiy53/aRMtSJ+vDfiV1Vhq+3sWAck/yUtfDU9/u4eFaiNok1 -8/Gd7reyuZt5CiJnpdPpjCwelK21l2w7sHAnJF55ITXdOxI8oG3BRKufz0z5lyDY -s2tXYmhhQIggdgelN8LbcMhWs/PBbtUr6uZlNJG2lW1yscD4aI529VjwJlCeo745 -U7pO4eF05VViUJ2mmfoivL3tkhoTUWhx8xs8xCUcCg8DoEoSIhxtOmoTPR22Z9BL -6LCg2mg= -=Dhm4 ------END PGP PUBLIC KEY BLOCK-----` - -const goodCrossSignatureKey = `-----BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1 - -mI0EVUqeVwEEAMufHRrMPWK3gyvi0O0tABCs/oON9zV9KDZlr1a1M91ShCSFwCPo -7r80PxdWVWcj0V5h50/CJYtpN3eE/mUIgW2z1uDYQF1OzrQ8ubrksfsJvpAhENom -lTQEppv9mV8qhcM278teb7TX0pgrUHLYF5CfPdp1L957JLLXoQR/lwLVABEBAAG0 -E2dvb2Qtc2lnbmluZy1zdWJrZXmIuAQTAQIAIgUCVUqeVwIbAwYLCQgHAwIGFQgC -CQoLBBYCAwECHgECF4AACgkQNRjL95IRWP69XQQAlH6+eyXJN4DZTLX78KGjHrsw -6FCvxxClEPtPUjcJy/1KCRQmtLAt9PbbA78dvgzjDeZMZqRAwdjyJhjyg/fkU2OH -7wq4ktjUu+dLcOBb+BFMEY+YjKZhf6EJuVfxoTVr5f82XNPbYHfTho9/OABKH6kv -X70PaKZhbwnwij8Nts65AaIEVUqftREEAJ3WxZfqAX0bTDbQPf2CMT2IVMGDfhK7 -GyubOZgDFFjwUJQvHNvsrbeGLZ0xOBumLINyPO1amIfTgJNm1iiWFWfmnHReGcDl -y5mpYG60Mb79Whdcer7CMm3AqYh/dW4g6IB02NwZMKoUHo3PXmFLxMKXnWyJ0clw -R0LI/Qn509yXAKDh1SO20rqrBM+EAP2c5bfI98kyNwQAi3buu94qo3RR1ZbvfxgW -CKXDVm6N99jdZGNK7FbRifXqzJJDLcXZKLnstnC4Sd3uyfyf1uFhmDLIQRryn5m+ -LBYHfDBPN3kdm7bsZDDq9GbTHiFZUfm/tChVKXWxkhpAmHhU/tH6GGzNSMXuIWSO -aOz3Rqq0ED4NXyNKjdF9MiwD/i83S0ZBc0LmJYt4Z10jtH2B6tYdqnAK29uQaadx -yZCX2scE09UIm32/w7pV77CKr1Cp/4OzAXS1tmFzQ+bX7DR+Gl8t4wxr57VeEMvl -BGw4Vjh3X8//m3xynxycQU18Q1zJ6PkiMyPw2owZ/nss3hpSRKFJsxMLhW3fKmKr -Ey2KiOcEGAECAAkFAlVKn7UCGwIAUgkQNRjL95IRWP5HIAQZEQIABgUCVUqftQAK -CRD98VjDN10SqkWrAKDTpEY8D8HC02E/KVC5YUI01B30wgCgurpILm20kXEDCeHp -C5pygfXw1DJrhAP+NyPJ4um/bU1I+rXaHHJYroYJs8YSweiNcwiHDQn0Engh/mVZ -SqLHvbKh2dL/RXymC3+rjPvQf5cup9bPxNMa6WagdYBNAfzWGtkVISeaQW+cTEp/ -MtgVijRGXR/lGLGETPg2X3Afwn9N9bLMBkBprKgbBqU7lpaoPupxT61bL70= -=vtbN ------END PGP PUBLIC KEY BLOCK-----` diff --git a/vendor/golang.org/x/crypto/openpgp/packet/compressed.go b/vendor/golang.org/x/crypto/openpgp/packet/compressed.go deleted file mode 100644 index e8f0b5c..0000000 --- a/vendor/golang.org/x/crypto/openpgp/packet/compressed.go +++ /dev/null @@ -1,123 +0,0 @@ -// 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/compressed_test.go b/vendor/golang.org/x/crypto/openpgp/packet/compressed_test.go deleted file mode 100644 index cb2d70b..0000000 --- a/vendor/golang.org/x/crypto/openpgp/packet/compressed_test.go +++ /dev/null @@ -1,41 +0,0 @@ -// 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" - "encoding/hex" - "io" - "io/ioutil" - "testing" -) - -func TestCompressed(t *testing.T) { - packet, err := Read(readerFromHex(compressedHex)) - if err != nil { - t.Errorf("failed to read Compressed: %s", err) - return - } - - c, ok := packet.(*Compressed) - if !ok { - t.Error("didn't find Compressed packet") - return - } - - contents, err := ioutil.ReadAll(c.Body) - if err != nil && err != io.EOF { - t.Error(err) - return - } - - expected, _ := hex.DecodeString(compressedExpectedHex) - if !bytes.Equal(expected, contents) { - t.Errorf("got:%x want:%x", contents, expected) - } -} - -const compressedHex = "a3013b2d90c4e02b72e25f727e5e496a5e49b11e1700" -const compressedExpectedHex = "cb1062004d14c8fe636f6e74656e74732e0a" diff --git a/vendor/golang.org/x/crypto/openpgp/packet/config.go b/vendor/golang.org/x/crypto/openpgp/packet/config.go deleted file mode 100644 index c76eecc..0000000 --- a/vendor/golang.org/x/crypto/openpgp/packet/config.go +++ /dev/null @@ -1,91 +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. - -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 deleted file mode 100644 index 266840d..0000000 --- a/vendor/golang.org/x/crypto/openpgp/packet/encrypted_key.go +++ /dev/null @@ -1,199 +0,0 @@ -// 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/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) - case PubKeyAlgoElGamal: - e.encryptedMPI1.bytes, e.encryptedMPI1.bitLength, err = readMPI(r) - if err != nil { - return - } - e.encryptedMPI2.bytes, e.encryptedMPI2.bitLength, err = readMPI(r) - } - _, 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: - b, err = rsa.DecryptPKCS1v15(config.Random(), priv.PrivateKey.(*rsa.PrivateKey), e.encryptedMPI1.bytes) - 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/encrypted_key_test.go b/vendor/golang.org/x/crypto/openpgp/packet/encrypted_key_test.go deleted file mode 100644 index fee14cf..0000000 --- a/vendor/golang.org/x/crypto/openpgp/packet/encrypted_key_test.go +++ /dev/null @@ -1,146 +0,0 @@ -// 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/rsa" - "encoding/hex" - "fmt" - "math/big" - "testing" -) - -func bigFromBase10(s string) *big.Int { - b, ok := new(big.Int).SetString(s, 10) - if !ok { - panic("bigFromBase10 failed") - } - return b -} - -var encryptedKeyPub = rsa.PublicKey{ - E: 65537, - N: bigFromBase10("115804063926007623305902631768113868327816898845124614648849934718568541074358183759250136204762053879858102352159854352727097033322663029387610959884180306668628526686121021235757016368038585212410610742029286439607686208110250133174279811431933746643015923132833417396844716207301518956640020862630546868823"), -} - -var encryptedKeyRSAPriv = &rsa.PrivateKey{ - PublicKey: encryptedKeyPub, - D: bigFromBase10("32355588668219869544751561565313228297765464314098552250409557267371233892496951383426602439009993875125222579159850054973310859166139474359774543943714622292329487391199285040721944491839695981199720170366763547754915493640685849961780092241140181198779299712578774460837139360803883139311171713302987058393"), -} - -var encryptedKeyPriv = &PrivateKey{ - PublicKey: PublicKey{ - PubKeyAlgo: PubKeyAlgoRSA, - }, - PrivateKey: encryptedKeyRSAPriv, -} - -func TestDecryptingEncryptedKey(t *testing.T) { - const encryptedKeyHex = "c18c032a67d68660df41c70104005789d0de26b6a50c985a02a13131ca829c413a35d0e6fa8d6842599252162808ac7439c72151c8c6183e76923fe3299301414d0c25a2f06a2257db3839e7df0ec964773f6e4c4ac7ff3b48c444237166dd46ba8ff443a5410dc670cb486672fdbe7c9dfafb75b4fea83af3a204fe2a7dfa86bd20122b4f3d2646cbeecb8f7be8" - const expectedKeyHex = "d930363f7e0308c333b9618617ea728963d8df993665ae7be1092d4926fd864b" - - p, err := Read(readerFromHex(encryptedKeyHex)) - if err != nil { - t.Errorf("error from Read: %s", err) - return - } - ek, ok := p.(*EncryptedKey) - if !ok { - t.Errorf("didn't parse an EncryptedKey, got %#v", p) - return - } - - if ek.KeyId != 0x2a67d68660df41c7 || ek.Algo != PubKeyAlgoRSA { - t.Errorf("unexpected EncryptedKey contents: %#v", ek) - return - } - - err = ek.Decrypt(encryptedKeyPriv, nil) - if err != nil { - t.Errorf("error from Decrypt: %s", err) - return - } - - if ek.CipherFunc != CipherAES256 { - t.Errorf("unexpected EncryptedKey contents: %#v", ek) - return - } - - keyHex := fmt.Sprintf("%x", ek.Key) - if keyHex != expectedKeyHex { - t.Errorf("bad key, got %s want %x", keyHex, expectedKeyHex) - } -} - -func TestEncryptingEncryptedKey(t *testing.T) { - key := []byte{1, 2, 3, 4} - const expectedKeyHex = "01020304" - const keyId = 42 - - pub := &PublicKey{ - PublicKey: &encryptedKeyPub, - KeyId: keyId, - PubKeyAlgo: PubKeyAlgoRSAEncryptOnly, - } - - buf := new(bytes.Buffer) - err := SerializeEncryptedKey(buf, pub, CipherAES128, key, nil) - if err != nil { - t.Errorf("error writing encrypted key packet: %s", err) - } - - p, err := Read(buf) - if err != nil { - t.Errorf("error from Read: %s", err) - return - } - ek, ok := p.(*EncryptedKey) - if !ok { - t.Errorf("didn't parse an EncryptedKey, got %#v", p) - return - } - - if ek.KeyId != keyId || ek.Algo != PubKeyAlgoRSAEncryptOnly { - t.Errorf("unexpected EncryptedKey contents: %#v", ek) - return - } - - err = ek.Decrypt(encryptedKeyPriv, nil) - if err != nil { - t.Errorf("error from Decrypt: %s", err) - return - } - - if ek.CipherFunc != CipherAES128 { - t.Errorf("unexpected EncryptedKey contents: %#v", ek) - return - } - - keyHex := fmt.Sprintf("%x", ek.Key) - if keyHex != expectedKeyHex { - t.Errorf("bad key, got %s want %x", keyHex, expectedKeyHex) - } -} - -func TestSerializingEncryptedKey(t *testing.T) { - const encryptedKeyHex = "c18c032a67d68660df41c70104005789d0de26b6a50c985a02a13131ca829c413a35d0e6fa8d6842599252162808ac7439c72151c8c6183e76923fe3299301414d0c25a2f06a2257db3839e7df0ec964773f6e4c4ac7ff3b48c444237166dd46ba8ff443a5410dc670cb486672fdbe7c9dfafb75b4fea83af3a204fe2a7dfa86bd20122b4f3d2646cbeecb8f7be8" - - p, err := Read(readerFromHex(encryptedKeyHex)) - if err != nil { - t.Fatalf("error from Read: %s", err) - } - ek, ok := p.(*EncryptedKey) - if !ok { - t.Fatalf("didn't parse an EncryptedKey, got %#v", p) - } - - var buf bytes.Buffer - ek.Serialize(&buf) - - if bufHex := hex.EncodeToString(buf.Bytes()); bufHex != encryptedKeyHex { - t.Fatalf("serialization of encrypted key differed from original. Original was %s, but reserialized as %s", encryptedKeyHex, bufHex) - } -} diff --git a/vendor/golang.org/x/crypto/openpgp/packet/literal.go b/vendor/golang.org/x/crypto/openpgp/packet/literal.go deleted file mode 100644 index 1a9ec6e..0000000 --- a/vendor/golang.org/x/crypto/openpgp/packet/literal.go +++ /dev/null @@ -1,89 +0,0 @@ -// 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 deleted file mode 100644 index ce2a33a..0000000 --- a/vendor/golang.org/x/crypto/openpgp/packet/ocfb.go +++ /dev/null @@ -1,143 +0,0 @@ -// 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/ocfb_test.go b/vendor/golang.org/x/crypto/openpgp/packet/ocfb_test.go deleted file mode 100644 index 91022c0..0000000 --- a/vendor/golang.org/x/crypto/openpgp/packet/ocfb_test.go +++ /dev/null @@ -1,46 +0,0 @@ -// 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 packet - -import ( - "bytes" - "crypto/aes" - "crypto/rand" - "testing" -) - -var commonKey128 = []byte{0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c} - -func testOCFB(t *testing.T, resync OCFBResyncOption) { - block, err := aes.NewCipher(commonKey128) - if err != nil { - t.Error(err) - return - } - - plaintext := []byte("this is the plaintext, which is long enough to span several blocks.") - randData := make([]byte, block.BlockSize()) - rand.Reader.Read(randData) - ocfb, prefix := NewOCFBEncrypter(block, randData, resync) - ciphertext := make([]byte, len(plaintext)) - ocfb.XORKeyStream(ciphertext, plaintext) - - ocfbdec := NewOCFBDecrypter(block, prefix, resync) - if ocfbdec == nil { - t.Errorf("NewOCFBDecrypter failed (resync: %t)", resync) - return - } - plaintextCopy := make([]byte, len(plaintext)) - ocfbdec.XORKeyStream(plaintextCopy, ciphertext) - - if !bytes.Equal(plaintextCopy, plaintext) { - t.Errorf("got: %x, want: %x (resync: %t)", plaintextCopy, plaintext, resync) - } -} - -func TestOCFB(t *testing.T) { - testOCFB(t, OCFBNoResync) - testOCFB(t, OCFBResync) -} 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 deleted file mode 100644 index 1713503..0000000 --- a/vendor/golang.org/x/crypto/openpgp/packet/one_pass_signature.go +++ /dev/null @@ -1,73 +0,0 @@ -// 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 deleted file mode 100644 index 456d807..0000000 --- a/vendor/golang.org/x/crypto/openpgp/packet/opaque.go +++ /dev/null @@ -1,162 +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. - -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/opaque_test.go b/vendor/golang.org/x/crypto/openpgp/packet/opaque_test.go deleted file mode 100644 index f27bbfe..0000000 --- a/vendor/golang.org/x/crypto/openpgp/packet/opaque_test.go +++ /dev/null @@ -1,67 +0,0 @@ -// 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" - "encoding/hex" - "io" - "testing" -) - -// Test packet.Read error handling in OpaquePacket.Parse, -// which attempts to re-read an OpaquePacket as a supported -// Packet type. -func TestOpaqueParseReason(t *testing.T) { - buf, err := hex.DecodeString(UnsupportedKeyHex) - if err != nil { - t.Fatal(err) - } - or := NewOpaqueReader(bytes.NewBuffer(buf)) - count := 0 - badPackets := 0 - var uid *UserId - for { - op, err := or.Next() - if err == io.EOF { - break - } else if err != nil { - t.Errorf("#%d: opaque read error: %v", count, err) - break - } - // try to parse opaque packet - p, err := op.Parse() - switch pkt := p.(type) { - case *UserId: - uid = pkt - case *OpaquePacket: - // If an OpaquePacket can't re-parse, packet.Read - // certainly had its reasons. - if pkt.Reason == nil { - t.Errorf("#%d: opaque packet, no reason", count) - } else { - badPackets++ - } - } - count++ - } - - const expectedBad = 3 - // Test post-conditions, make sure we actually parsed packets as expected. - if badPackets != expectedBad { - t.Errorf("unexpected # unparseable packets: %d (want %d)", badPackets, expectedBad) - } - if uid == nil { - t.Errorf("failed to find expected UID in unsupported keyring") - } else if uid.Id != "Armin M. Warda " { - t.Errorf("unexpected UID: %v", uid.Id) - } -} - -// This key material has public key and signature packet versions modified to -// an unsupported value (1), so that trying to parse the OpaquePacket to -// a typed packet will get an error. It also contains a GnuPG trust packet. -// (Created with: od -An -t x1 pubring.gpg | xargs | sed 's/ //g') -const UnsupportedKeyHex = `988d012e7a18a20000010400d6ac00d92b89c1f4396c243abb9b76d2e9673ad63483291fed88e22b82e255e441c078c6abbbf7d2d195e50b62eeaa915b85b0ec20c225ce2c64c167cacb6e711daf2e45da4a8356a059b8160e3b3628ac0dd8437b31f06d53d6e8ea4214d4a26406a6b63e1001406ef23e0bb3069fac9a99a91f77dfafd5de0f188a5da5e3c9000511b42741726d696e204d2e205761726461203c7761726461406e657068696c696d2e727568722e64653e8900950105102e8936c705d1eb399e58489901013f0e03ff5a0c4f421e34fcfa388129166420c08cd76987bcdec6f01bd0271459a85cc22048820dd4e44ac2c7d23908d540f54facf1b36b0d9c20488781ce9dca856531e76e2e846826e9951338020a03a09b57aa5faa82e9267458bd76105399885ac35af7dc1cbb6aaed7c39e1039f3b5beda2c0e916bd38560509bab81235d1a0ead83b0020000` diff --git a/vendor/golang.org/x/crypto/openpgp/packet/packet.go b/vendor/golang.org/x/crypto/openpgp/packet/packet.go deleted file mode 100644 index e2bde11..0000000 --- a/vendor/golang.org/x/crypto/openpgp/packet/packet.go +++ /dev/null @@ -1,539 +0,0 @@ -// 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. -package packet // import "golang.org/x/crypto/openpgp/packet" - -import ( - "bufio" - "crypto/aes" - "crypto/cipher" - "crypto/des" - "golang.org/x/crypto/cast5" - "golang.org/x/crypto/openpgp/errors" - "io" - "math/big" -) - -// 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 -} - -func (w *partialLengthWriter) Write(p []byte) (n int, err error) { - for len(p) > 0 { - for power := uint(14); power < 32; power-- { - l := 1 << power - if len(p) >= l { - w.lengthByte[0] = 224 + uint8(power) - _, err = w.w.Write(w.lengthByte[:]) - if err != nil { - return - } - var m int - m, err = w.w.Write(p[:l]) - n += m - if err != nil { - return - } - p = p[l:] - break - } - } - } - return -} - -func (w *partialLengthWriter) Close() error { - 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 - } - } - - panic("unreachable") -} - -// 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 - PubKeyAlgoRSAEncryptOnly PublicKeyAlgorithm = 2 - PubKeyAlgoRSASignOnly PublicKeyAlgorithm = 3 - PubKeyAlgoElGamal PublicKeyAlgorithm = 16 - PubKeyAlgoDSA PublicKeyAlgorithm = 17 - // RFC 6637, Section 5. - PubKeyAlgoECDH PublicKeyAlgorithm = 18 - PubKeyAlgoECDSA PublicKeyAlgorithm = 19 -) - -// 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) - return -} - -// mpiLength returns the length of the given *big.Int when serialized as an -// MPI. -func mpiLength(n *big.Int) (mpiLengthInBytes int) { - mpiLengthInBytes = 2 /* MPI length */ - mpiLengthInBytes += (n.BitLen() + 7) / 8 - return -} - -// writeMPI serializes a big integer to w. -func writeMPI(w io.Writer, bitLength uint16, mpiBytes []byte) (err error) { - _, 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()) -} - -// 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/packet_test.go b/vendor/golang.org/x/crypto/openpgp/packet/packet_test.go deleted file mode 100644 index 1dab5c3..0000000 --- a/vendor/golang.org/x/crypto/openpgp/packet/packet_test.go +++ /dev/null @@ -1,255 +0,0 @@ -// 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" - "encoding/hex" - "fmt" - "golang.org/x/crypto/openpgp/errors" - "io" - "io/ioutil" - "testing" -) - -func TestReadFull(t *testing.T) { - var out [4]byte - - b := bytes.NewBufferString("foo") - n, err := readFull(b, out[:3]) - if n != 3 || err != nil { - t.Errorf("full read failed n:%d err:%s", n, err) - } - - b = bytes.NewBufferString("foo") - n, err = readFull(b, out[:4]) - if n != 3 || err != io.ErrUnexpectedEOF { - t.Errorf("partial read failed n:%d err:%s", n, err) - } - - b = bytes.NewBuffer(nil) - n, err = readFull(b, out[:3]) - if n != 0 || err != io.ErrUnexpectedEOF { - t.Errorf("empty read failed n:%d err:%s", n, err) - } -} - -func readerFromHex(s string) io.Reader { - data, err := hex.DecodeString(s) - if err != nil { - panic("readerFromHex: bad input") - } - return bytes.NewBuffer(data) -} - -var readLengthTests = []struct { - hexInput string - length int64 - isPartial bool - err error -}{ - {"", 0, false, io.ErrUnexpectedEOF}, - {"1f", 31, false, nil}, - {"c0", 0, false, io.ErrUnexpectedEOF}, - {"c101", 256 + 1 + 192, false, nil}, - {"e0", 1, true, nil}, - {"e1", 2, true, nil}, - {"e2", 4, true, nil}, - {"ff", 0, false, io.ErrUnexpectedEOF}, - {"ff00", 0, false, io.ErrUnexpectedEOF}, - {"ff0000", 0, false, io.ErrUnexpectedEOF}, - {"ff000000", 0, false, io.ErrUnexpectedEOF}, - {"ff00000000", 0, false, nil}, - {"ff01020304", 16909060, false, nil}, -} - -func TestReadLength(t *testing.T) { - for i, test := range readLengthTests { - length, isPartial, err := readLength(readerFromHex(test.hexInput)) - if test.err != nil { - if err != test.err { - t.Errorf("%d: expected different error got:%s want:%s", i, err, test.err) - } - continue - } - if err != nil { - t.Errorf("%d: unexpected error: %s", i, err) - continue - } - if length != test.length || isPartial != test.isPartial { - t.Errorf("%d: bad result got:(%d,%t) want:(%d,%t)", i, length, isPartial, test.length, test.isPartial) - } - } -} - -var partialLengthReaderTests = []struct { - hexInput string - err error - hexOutput string -}{ - {"e0", io.ErrUnexpectedEOF, ""}, - {"e001", io.ErrUnexpectedEOF, ""}, - {"e0010102", nil, "0102"}, - {"ff00000000", nil, ""}, - {"e10102e1030400", nil, "01020304"}, - {"e101", io.ErrUnexpectedEOF, ""}, -} - -func TestPartialLengthReader(t *testing.T) { - for i, test := range partialLengthReaderTests { - r := &partialLengthReader{readerFromHex(test.hexInput), 0, true} - out, err := ioutil.ReadAll(r) - if test.err != nil { - if err != test.err { - t.Errorf("%d: expected different error got:%s want:%s", i, err, test.err) - } - continue - } - if err != nil { - t.Errorf("%d: unexpected error: %s", i, err) - continue - } - - got := fmt.Sprintf("%x", out) - if got != test.hexOutput { - t.Errorf("%d: got:%s want:%s", i, test.hexOutput, got) - } - } -} - -var readHeaderTests = []struct { - hexInput string - structuralError bool - unexpectedEOF bool - tag int - length int64 - hexOutput string -}{ - {"", false, false, 0, 0, ""}, - {"7f", true, false, 0, 0, ""}, - - // Old format headers - {"80", false, true, 0, 0, ""}, - {"8001", false, true, 0, 1, ""}, - {"800102", false, false, 0, 1, "02"}, - {"81000102", false, false, 0, 1, "02"}, - {"820000000102", false, false, 0, 1, "02"}, - {"860000000102", false, false, 1, 1, "02"}, - {"83010203", false, false, 0, -1, "010203"}, - - // New format headers - {"c0", false, true, 0, 0, ""}, - {"c000", false, false, 0, 0, ""}, - {"c00102", false, false, 0, 1, "02"}, - {"c0020203", false, false, 0, 2, "0203"}, - {"c00202", false, true, 0, 2, ""}, - {"c3020203", false, false, 3, 2, "0203"}, -} - -func TestReadHeader(t *testing.T) { - for i, test := range readHeaderTests { - tag, length, contents, err := readHeader(readerFromHex(test.hexInput)) - if test.structuralError { - if _, ok := err.(errors.StructuralError); ok { - continue - } - t.Errorf("%d: expected StructuralError, got:%s", i, err) - continue - } - if err != nil { - if len(test.hexInput) == 0 && err == io.EOF { - continue - } - if !test.unexpectedEOF || err != io.ErrUnexpectedEOF { - t.Errorf("%d: unexpected error from readHeader: %s", i, err) - } - continue - } - if int(tag) != test.tag || length != test.length { - t.Errorf("%d: got:(%d,%d) want:(%d,%d)", i, int(tag), length, test.tag, test.length) - continue - } - - body, err := ioutil.ReadAll(contents) - if err != nil { - if !test.unexpectedEOF || err != io.ErrUnexpectedEOF { - t.Errorf("%d: unexpected error from contents: %s", i, err) - } - continue - } - if test.unexpectedEOF { - t.Errorf("%d: expected ErrUnexpectedEOF from contents but got no error", i) - continue - } - got := fmt.Sprintf("%x", body) - if got != test.hexOutput { - t.Errorf("%d: got:%s want:%s", i, got, test.hexOutput) - } - } -} - -func TestSerializeHeader(t *testing.T) { - tag := packetTypePublicKey - lengths := []int{0, 1, 2, 64, 192, 193, 8000, 8384, 8385, 10000} - - for _, length := range lengths { - buf := bytes.NewBuffer(nil) - serializeHeader(buf, tag, length) - tag2, length2, _, err := readHeader(buf) - if err != nil { - t.Errorf("length %d, err: %s", length, err) - } - if tag2 != tag { - t.Errorf("length %d, tag incorrect (got %d, want %d)", length, tag2, tag) - } - if int(length2) != length { - t.Errorf("length %d, length incorrect (got %d)", length, length2) - } - } -} - -func TestPartialLengths(t *testing.T) { - buf := bytes.NewBuffer(nil) - w := new(partialLengthWriter) - w.w = noOpCloser{buf} - - const maxChunkSize = 64 - - var b [maxChunkSize]byte - var n uint8 - for l := 1; l <= maxChunkSize; l++ { - for i := 0; i < l; i++ { - b[i] = n - n++ - } - m, err := w.Write(b[:l]) - if m != l { - t.Errorf("short write got: %d want: %d", m, l) - } - if err != nil { - t.Errorf("error from write: %s", err) - } - } - w.Close() - - want := (maxChunkSize * (maxChunkSize + 1)) / 2 - copyBuf := bytes.NewBuffer(nil) - r := &partialLengthReader{buf, 0, true} - m, err := io.Copy(copyBuf, r) - if m != int64(want) { - t.Errorf("short copy got: %d want: %d", m, want) - } - if err != nil { - t.Errorf("error from copy: %s", err) - } - - copyBytes := copyBuf.Bytes() - for i := 0; i < want; i++ { - if copyBytes[i] != uint8(i) { - t.Errorf("bad pattern in copy at %d", i) - break - } - } -} diff --git a/vendor/golang.org/x/crypto/openpgp/packet/private_key.go b/vendor/golang.org/x/crypto/openpgp/packet/private_key.go deleted file mode 100644 index 545846b..0000000 --- a/vendor/golang.org/x/crypto/openpgp/packet/private_key.go +++ /dev/null @@ -1,362 +0,0 @@ -// 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" - "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.PrivateKey or *dsa.PrivateKey. - sha1Checksum bool - iv []byte -} - -func NewRSAPrivateKey(currentTime time.Time, priv *rsa.PrivateKey) *PrivateKey { - pk := new(PrivateKey) - pk.PublicKey = *NewRSAPublicKey(currentTime, &priv.PublicKey) - pk.PrivateKey = priv - return pk -} - -func NewDSAPrivateKey(currentTime time.Time, priv *dsa.PrivateKey) *PrivateKey { - pk := new(PrivateKey) - pk.PublicKey = *NewDSAPublicKey(currentTime, &priv.PublicKey) - pk.PrivateKey = priv - return pk -} - -func NewElGamalPrivateKey(currentTime time.Time, priv *elgamal.PrivateKey) *PrivateKey { - pk := new(PrivateKey) - pk.PublicKey = *NewElGamalPublicKey(currentTime, &priv.PublicKey) - pk.PrivateKey = priv - return pk -} - -func NewECDSAPrivateKey(currentTime time.Time, priv *ecdsa.PrivateKey) *PrivateKey { - pk := new(PrivateKey) - pk.PublicKey = *NewECDSAPublicKey(currentTime, &priv.PublicKey) - pk.PrivateKey = priv - 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/private_key_test.go b/vendor/golang.org/x/crypto/openpgp/packet/private_key_test.go deleted file mode 100644 index 81d3961..0000000 --- a/vendor/golang.org/x/crypto/openpgp/packet/private_key_test.go +++ /dev/null @@ -1,126 +0,0 @@ -// 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/ecdsa" - "crypto/elliptic" - "crypto/rand" - "hash" - "testing" - "time" -) - -var privateKeyTests = []struct { - privateKeyHex string - creationTime time.Time -}{ - { - privKeyRSAHex, - time.Unix(0x4cc349a8, 0), - }, - { - privKeyElGamalHex, - time.Unix(0x4df9ee1a, 0), - }, -} - -func TestPrivateKeyRead(t *testing.T) { - for i, test := range privateKeyTests { - packet, err := Read(readerFromHex(test.privateKeyHex)) - if err != nil { - t.Errorf("#%d: failed to parse: %s", i, err) - continue - } - - privKey := packet.(*PrivateKey) - - if !privKey.Encrypted { - t.Errorf("#%d: private key isn't encrypted", i) - continue - } - - err = privKey.Decrypt([]byte("wrong password")) - if err == nil { - t.Errorf("#%d: decrypted with incorrect key", i) - continue - } - - err = privKey.Decrypt([]byte("testing")) - if err != nil { - t.Errorf("#%d: failed to decrypt: %s", i, err) - continue - } - - if !privKey.CreationTime.Equal(test.creationTime) || privKey.Encrypted { - t.Errorf("#%d: bad result, got: %#v", i, privKey) - } - } -} - -func populateHash(hashFunc crypto.Hash, msg []byte) (hash.Hash, error) { - h := hashFunc.New() - if _, err := h.Write(msg); err != nil { - return nil, err - } - return h, nil -} - -func TestECDSAPrivateKey(t *testing.T) { - ecdsaPriv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) - if err != nil { - t.Fatal(err) - } - - var buf bytes.Buffer - if err := NewECDSAPrivateKey(time.Now(), ecdsaPriv).Serialize(&buf); err != nil { - t.Fatal(err) - } - - p, err := Read(&buf) - if err != nil { - t.Fatal(err) - } - - priv, ok := p.(*PrivateKey) - if !ok { - t.Fatal("didn't parse private key") - } - - sig := &Signature{ - PubKeyAlgo: PubKeyAlgoECDSA, - Hash: crypto.SHA256, - } - msg := []byte("Hello World!") - - h, err := populateHash(sig.Hash, msg) - if err != nil { - t.Fatal(err) - } - if err := sig.Sign(h, priv, nil); err != nil { - t.Fatal(err) - } - - if h, err = populateHash(sig.Hash, msg); err != nil { - t.Fatal(err) - } - if err := priv.VerifySignature(h, sig); err != nil { - t.Fatal(err) - } -} - -func TestIssue11505(t *testing.T) { - // parsing a rsa private key with p or q == 1 used to panic due to a divide by zero - _, _ = Read(readerFromHex("9c3004303030300100000011303030000000000000010130303030303030303030303030303030303030303030303030303030303030303030303030303030303030")) -} - -// Generated with `gpg --export-secret-keys "Test Key 2"` -const privKeyRSAHex = "9501fe044cc349a8010400b70ca0010e98c090008d45d1ee8f9113bd5861fd57b88bacb7c68658747663f1e1a3b5a98f32fda6472373c024b97359cd2efc88ff60f77751adfbf6af5e615e6a1408cfad8bf0cea30b0d5f53aa27ad59089ba9b15b7ebc2777a25d7b436144027e3bcd203909f147d0e332b240cf63d3395f5dfe0df0a6c04e8655af7eacdf0011010001fe0303024a252e7d475fd445607de39a265472aa74a9320ba2dac395faa687e9e0336aeb7e9a7397e511b5afd9dc84557c80ac0f3d4d7bfec5ae16f20d41c8c84a04552a33870b930420e230e179564f6d19bb153145e76c33ae993886c388832b0fa042ddda7f133924f3854481533e0ede31d51278c0519b29abc3bf53da673e13e3e1214b52413d179d7f66deee35cac8eacb060f78379d70ef4af8607e68131ff529439668fc39c9ce6dfef8a5ac234d234802cbfb749a26107db26406213ae5c06d4673253a3cbee1fcbae58d6ab77e38d6e2c0e7c6317c48e054edadb5a40d0d48acb44643d998139a8a66bb820be1f3f80185bc777d14b5954b60effe2448a036d565c6bc0b915fcea518acdd20ab07bc1529f561c58cd044f723109b93f6fd99f876ff891d64306b5d08f48bab59f38695e9109c4dec34013ba3153488ce070268381ba923ee1eb77125b36afcb4347ec3478c8f2735b06ef17351d872e577fa95d0c397c88c71b59629a36aec" - -// Generated by `gpg --export-secret-keys` followed by a manual extraction of -// the ElGamal subkey from the packets. -const privKeyElGamalHex = "9d0157044df9ee1a100400eb8e136a58ec39b582629cdadf830bc64e0a94ed8103ca8bb247b27b11b46d1d25297ef4bcc3071785ba0c0bedfe89eabc5287fcc0edf81ab5896c1c8e4b20d27d79813c7aede75320b33eaeeaa586edc00fd1036c10133e6ba0ff277245d0d59d04b2b3421b7244aca5f4a8d870c6f1c1fbff9e1c26699a860b9504f35ca1d700030503fd1ededd3b840795be6d9ccbe3c51ee42e2f39233c432b831ddd9c4e72b7025a819317e47bf94f9ee316d7273b05d5fcf2999c3a681f519b1234bbfa6d359b4752bd9c3f77d6b6456cde152464763414ca130f4e91d91041432f90620fec0e6d6b5116076c2985d5aeaae13be492b9b329efcaf7ee25120159a0a30cd976b42d7afe030302dae7eb80db744d4960c4df930d57e87fe81412eaace9f900e6c839817a614ddb75ba6603b9417c33ea7b6c93967dfa2bcff3fa3c74a5ce2c962db65b03aece14c96cbd0038fc" diff --git a/vendor/golang.org/x/crypto/openpgp/packet/public_key.go b/vendor/golang.org/x/crypto/openpgp/packet/public_key.go deleted file mode 100644 index c769933..0000000 --- a/vendor/golang.org/x/crypto/openpgp/packet/public_key.go +++ /dev/null @@ -1,750 +0,0 @@ -// 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) - pk.ec.p.bitLength = uint16(8 * len(pk.ec.p.bytes)) - - 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, 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") - } - panic("unreachable") -} - -// 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, 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") - } - panic("unreachable") -} - -// 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_test.go b/vendor/golang.org/x/crypto/openpgp/packet/public_key_test.go deleted file mode 100644 index 7ad7d91..0000000 --- a/vendor/golang.org/x/crypto/openpgp/packet/public_key_test.go +++ /dev/null @@ -1,202 +0,0 @@ -// 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" - "encoding/hex" - "testing" - "time" -) - -var pubKeyTests = []struct { - hexData string - hexFingerprint string - creationTime time.Time - pubKeyAlgo PublicKeyAlgorithm - keyId uint64 - keyIdString string - keyIdShort string -}{ - {rsaPkDataHex, rsaFingerprintHex, time.Unix(0x4d3c5c10, 0), PubKeyAlgoRSA, 0xa34d7e18c20c31bb, "A34D7E18C20C31BB", "C20C31BB"}, - {dsaPkDataHex, dsaFingerprintHex, time.Unix(0x4d432f89, 0), PubKeyAlgoDSA, 0x8e8fbe54062f19ed, "8E8FBE54062F19ED", "062F19ED"}, - {ecdsaPkDataHex, ecdsaFingerprintHex, time.Unix(0x5071c294, 0), PubKeyAlgoECDSA, 0x43fe956c542ca00b, "43FE956C542CA00B", "542CA00B"}, -} - -func TestPublicKeyRead(t *testing.T) { - for i, test := range pubKeyTests { - packet, err := Read(readerFromHex(test.hexData)) - if err != nil { - t.Errorf("#%d: Read error: %s", i, err) - continue - } - pk, ok := packet.(*PublicKey) - if !ok { - t.Errorf("#%d: failed to parse, got: %#v", i, packet) - continue - } - if pk.PubKeyAlgo != test.pubKeyAlgo { - t.Errorf("#%d: bad public key algorithm got:%x want:%x", i, pk.PubKeyAlgo, test.pubKeyAlgo) - } - if !pk.CreationTime.Equal(test.creationTime) { - t.Errorf("#%d: bad creation time got:%v want:%v", i, pk.CreationTime, test.creationTime) - } - expectedFingerprint, _ := hex.DecodeString(test.hexFingerprint) - if !bytes.Equal(expectedFingerprint, pk.Fingerprint[:]) { - t.Errorf("#%d: bad fingerprint got:%x want:%x", i, pk.Fingerprint[:], expectedFingerprint) - } - if pk.KeyId != test.keyId { - t.Errorf("#%d: bad keyid got:%x want:%x", i, pk.KeyId, test.keyId) - } - if g, e := pk.KeyIdString(), test.keyIdString; g != e { - t.Errorf("#%d: bad KeyIdString got:%q want:%q", i, g, e) - } - if g, e := pk.KeyIdShortString(), test.keyIdShort; g != e { - t.Errorf("#%d: bad KeyIdShortString got:%q want:%q", i, g, e) - } - } -} - -func TestPublicKeySerialize(t *testing.T) { - for i, test := range pubKeyTests { - packet, err := Read(readerFromHex(test.hexData)) - if err != nil { - t.Errorf("#%d: Read error: %s", i, err) - continue - } - pk, ok := packet.(*PublicKey) - if !ok { - t.Errorf("#%d: failed to parse, got: %#v", i, packet) - continue - } - serializeBuf := bytes.NewBuffer(nil) - err = pk.Serialize(serializeBuf) - if err != nil { - t.Errorf("#%d: failed to serialize: %s", i, err) - continue - } - - packet, err = Read(serializeBuf) - if err != nil { - t.Errorf("#%d: Read error (from serialized data): %s", i, err) - continue - } - pk, ok = packet.(*PublicKey) - if !ok { - t.Errorf("#%d: failed to parse serialized data, got: %#v", i, packet) - continue - } - } -} - -func TestEcc384Serialize(t *testing.T) { - r := readerFromHex(ecc384PubHex) - var w bytes.Buffer - for i := 0; i < 2; i++ { - // Public key - p, err := Read(r) - if err != nil { - t.Error(err) - } - pubkey := p.(*PublicKey) - if !bytes.Equal(pubkey.ec.oid, []byte{0x2b, 0x81, 0x04, 0x00, 0x22}) { - t.Errorf("Unexpected pubkey OID: %x", pubkey.ec.oid) - } - if !bytes.Equal(pubkey.ec.p.bytes[:5], []byte{0x04, 0xf6, 0xb8, 0xc5, 0xac}) { - t.Errorf("Unexpected pubkey P[:5]: %x", pubkey.ec.p.bytes) - } - if pubkey.KeyId != 0x098033880F54719F { - t.Errorf("Unexpected pubkey ID: %x", pubkey.KeyId) - } - err = pubkey.Serialize(&w) - if err != nil { - t.Error(err) - } - // User ID - p, err = Read(r) - if err != nil { - t.Error(err) - } - uid := p.(*UserId) - if uid.Id != "ec_dsa_dh_384 " { - t.Error("Unexpected UID:", uid.Id) - } - err = uid.Serialize(&w) - if err != nil { - t.Error(err) - } - // User ID Sig - p, err = Read(r) - if err != nil { - t.Error(err) - } - uidSig := p.(*Signature) - err = pubkey.VerifyUserIdSignature(uid.Id, pubkey, uidSig) - if err != nil { - t.Error(err, ": UID") - } - err = uidSig.Serialize(&w) - if err != nil { - t.Error(err) - } - // Subkey - p, err = Read(r) - if err != nil { - t.Error(err) - } - subkey := p.(*PublicKey) - if !bytes.Equal(subkey.ec.oid, []byte{0x2b, 0x81, 0x04, 0x00, 0x22}) { - t.Errorf("Unexpected subkey OID: %x", subkey.ec.oid) - } - if !bytes.Equal(subkey.ec.p.bytes[:5], []byte{0x04, 0x2f, 0xaa, 0x84, 0x02}) { - t.Errorf("Unexpected subkey P[:5]: %x", subkey.ec.p.bytes) - } - if subkey.ecdh.KdfHash != 0x09 { - t.Error("Expected KDF hash function SHA384 (0x09), got", subkey.ecdh.KdfHash) - } - if subkey.ecdh.KdfAlgo != 0x09 { - t.Error("Expected KDF symmetric alg AES256 (0x09), got", subkey.ecdh.KdfAlgo) - } - if subkey.KeyId != 0xAA8B938F9A201946 { - t.Errorf("Unexpected subkey ID: %x", subkey.KeyId) - } - err = subkey.Serialize(&w) - if err != nil { - t.Error(err) - } - // Subkey Sig - p, err = Read(r) - if err != nil { - t.Error(err) - } - subkeySig := p.(*Signature) - err = pubkey.VerifyKeySignature(subkey, subkeySig) - if err != nil { - t.Error(err) - } - err = subkeySig.Serialize(&w) - if err != nil { - t.Error(err) - } - // Now read back what we've written again - r = bytes.NewBuffer(w.Bytes()) - w.Reset() - } -} - -const rsaFingerprintHex = "5fb74b1d03b1e3cb31bc2f8aa34d7e18c20c31bb" - -const rsaPkDataHex = "988d044d3c5c10010400b1d13382944bd5aba23a4312968b5095d14f947f600eb478e14a6fcb16b0e0cac764884909c020bc495cfcc39a935387c661507bdb236a0612fb582cac3af9b29cc2c8c70090616c41b662f4da4c1201e195472eb7f4ae1ccbcbf9940fe21d985e379a5563dde5b9a23d35f1cfaa5790da3b79db26f23695107bfaca8e7b5bcd0011010001" - -const dsaFingerprintHex = "eece4c094db002103714c63c8e8fbe54062f19ed" - -const dsaPkDataHex = "9901a2044d432f89110400cd581334f0d7a1e1bdc8b9d6d8c0baf68793632735d2bb0903224cbaa1dfbf35a60ee7a13b92643421e1eb41aa8d79bea19a115a677f6b8ba3c7818ce53a6c2a24a1608bd8b8d6e55c5090cbde09dd26e356267465ae25e69ec8bdd57c7bbb2623e4d73336f73a0a9098f7f16da2e25252130fd694c0e8070c55a812a423ae7f00a0ebf50e70c2f19c3520a551bd4b08d30f23530d3d03ff7d0bf4a53a64a09dc5e6e6e35854b7d70c882b0c60293401958b1bd9e40abec3ea05ba87cf64899299d4bd6aa7f459c201d3fbbd6c82004bdc5e8a9eb8082d12054cc90fa9d4ec251a843236a588bf49552441817436c4f43326966fe85447d4e6d0acf8fa1ef0f014730770603ad7634c3088dc52501c237328417c31c89ed70400b2f1a98b0bf42f11fefc430704bebbaa41d9f355600c3facee1e490f64208e0e094ea55e3a598a219a58500bf78ac677b670a14f4e47e9cf8eab4f368cc1ddcaa18cc59309d4cc62dd4f680e73e6cc3e1ce87a84d0925efbcb26c575c093fc42eecf45135fabf6403a25c2016e1774c0484e440a18319072c617cc97ac0a3bb0" - -const ecdsaFingerprintHex = "9892270b38b8980b05c8d56d43fe956c542ca00b" - -const ecdsaPkDataHex = "9893045071c29413052b8104002304230401f4867769cedfa52c325018896245443968e52e51d0c2df8d939949cb5b330f2921711fbee1c9b9dddb95d15cb0255e99badeddda7cc23d9ddcaacbc290969b9f24019375d61c2e4e3b36953a28d8b2bc95f78c3f1d592fb24499be348656a7b17e3963187b4361afe497bc5f9f81213f04069f8e1fb9e6a6290ae295ca1a92b894396cb4" - -// Source: https://sites.google.com/site/brainhub/pgpecckeys#TOC-ECC-NIST-P-384-key -const ecc384PubHex = `99006f044d53059213052b81040022030304f6b8c5aced5b84ef9f4a209db2e4a9dfb70d28cb8c10ecd57674a9fa5a67389942b62d5e51367df4c7bfd3f8e500feecf07ed265a621a8ebbbe53e947ec78c677eba143bd1533c2b350e1c29f82313e1e1108eba063be1e64b10e6950e799c2db42465635f6473615f64685f333834203c6f70656e70677040627261696e6875622e6f72673e8900cb04101309005305024d530592301480000000002000077072656665727265642d656d61696c2d656e636f64696e67407067702e636f6d7067706d696d65040b090807021901051b03000000021602051e010000000415090a08000a0910098033880f54719fca2b0180aa37350968bd5f115afd8ce7bc7b103822152dbff06d0afcda835329510905b98cb469ba208faab87c7412b799e7b633017f58364ea480e8a1a3f253a0c5f22c446e8be9a9fce6210136ee30811abbd49139de28b5bdf8dc36d06ae748579e9ff503b90073044d53059212052b810400220303042faa84024a20b6735c4897efa5bfb41bf85b7eefeab5ca0cb9ffc8ea04a46acb25534a577694f9e25340a4ab5223a9dd1eda530c8aa2e6718db10d7e672558c7736fe09369ea5739a2a3554bf16d41faa50562f11c6d39bbd5dffb6b9a9ec9180301090989008404181309000c05024d530592051b0c000000000a0910098033880f54719f80970180eee7a6d8fcee41ee4f9289df17f9bcf9d955dca25c583b94336f3a2b2d4986dc5cf417b8d2dc86f741a9e1a6d236c0e3017d1c76575458a0cfb93ae8a2b274fcc65ceecd7a91eec83656ba13219969f06945b48c56bd04152c3a0553c5f2f4bd1267` 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 deleted file mode 100644 index 26337f5..0000000 --- a/vendor/golang.org/x/crypto/openpgp/packet/public_key_v3.go +++ /dev/null @@ -1,280 +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 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") - } - panic("unreachable") -} - -// 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/public_key_v3_test.go b/vendor/golang.org/x/crypto/openpgp/packet/public_key_v3_test.go deleted file mode 100644 index e064059..0000000 --- a/vendor/golang.org/x/crypto/openpgp/packet/public_key_v3_test.go +++ /dev/null @@ -1,82 +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 packet - -import ( - "bytes" - "encoding/hex" - "testing" - "time" -) - -var pubKeyV3Test = struct { - hexFingerprint string - creationTime time.Time - pubKeyAlgo PublicKeyAlgorithm - keyId uint64 - keyIdString string - keyIdShort string -}{ - "103BECF5BD1E837C89D19E98487767F7", - time.Unix(779753634, 0), - PubKeyAlgoRSA, - 0xDE0F188A5DA5E3C9, - "DE0F188A5DA5E3C9", - "5DA5E3C9"} - -func TestPublicKeyV3Read(t *testing.T) { - i, test := 0, pubKeyV3Test - packet, err := Read(v3KeyReader(t)) - if err != nil { - t.Fatalf("#%d: Read error: %s", i, err) - } - pk, ok := packet.(*PublicKeyV3) - if !ok { - t.Fatalf("#%d: failed to parse, got: %#v", i, packet) - } - if pk.PubKeyAlgo != test.pubKeyAlgo { - t.Errorf("#%d: bad public key algorithm got:%x want:%x", i, pk.PubKeyAlgo, test.pubKeyAlgo) - } - if !pk.CreationTime.Equal(test.creationTime) { - t.Errorf("#%d: bad creation time got:%v want:%v", i, pk.CreationTime, test.creationTime) - } - expectedFingerprint, _ := hex.DecodeString(test.hexFingerprint) - if !bytes.Equal(expectedFingerprint, pk.Fingerprint[:]) { - t.Errorf("#%d: bad fingerprint got:%x want:%x", i, pk.Fingerprint[:], expectedFingerprint) - } - if pk.KeyId != test.keyId { - t.Errorf("#%d: bad keyid got:%x want:%x", i, pk.KeyId, test.keyId) - } - if g, e := pk.KeyIdString(), test.keyIdString; g != e { - t.Errorf("#%d: bad KeyIdString got:%q want:%q", i, g, e) - } - if g, e := pk.KeyIdShortString(), test.keyIdShort; g != e { - t.Errorf("#%d: bad KeyIdShortString got:%q want:%q", i, g, e) - } -} - -func TestPublicKeyV3Serialize(t *testing.T) { - //for i, test := range pubKeyV3Tests { - i := 0 - packet, err := Read(v3KeyReader(t)) - if err != nil { - t.Fatalf("#%d: Read error: %s", i, err) - } - pk, ok := packet.(*PublicKeyV3) - if !ok { - t.Fatalf("#%d: failed to parse, got: %#v", i, packet) - } - var serializeBuf bytes.Buffer - if err = pk.Serialize(&serializeBuf); err != nil { - t.Fatalf("#%d: failed to serialize: %s", i, err) - } - - if packet, err = Read(bytes.NewBuffer(serializeBuf.Bytes())); err != nil { - t.Fatalf("#%d: Read error (from serialized data): %s", i, err) - } - if pk, ok = packet.(*PublicKeyV3); !ok { - t.Fatalf("#%d: failed to parse serialized data, got: %#v", i, packet) - } -} diff --git a/vendor/golang.org/x/crypto/openpgp/packet/reader.go b/vendor/golang.org/x/crypto/openpgp/packet/reader.go deleted file mode 100644 index 34bc7c6..0000000 --- a/vendor/golang.org/x/crypto/openpgp/packet/reader.go +++ /dev/null @@ -1,76 +0,0 @@ -// 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 deleted file mode 100644 index 4368f6b..0000000 --- a/vendor/golang.org/x/crypto/openpgp/packet/signature.go +++ /dev/null @@ -1,706 +0,0 @@ -// 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/rsa" - "encoding/binary" - "hash" - "io" - "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: - sig.RSASignature.bytes, err = rsa.SignPKCS1v15(config.Random(), priv.PrivateKey.(*rsa.PrivateKey), sig.Hash, digest) - 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: - r, s, err := ecdsa.Sign(config.Random(), priv.PrivateKey.(*ecdsa.PrivateKey), digest) - if err == nil { - sig.ECDSASigR = fromBig(r) - sig.ECDSASigS = fromBig(s) - } - default: - err = errors.UnsupportedError("public key algorithm: " + strconv.Itoa(int(sig.PubKeyAlgo))) - } - - return -} - -// 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 nil - } - 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_test.go b/vendor/golang.org/x/crypto/openpgp/packet/signature_test.go deleted file mode 100644 index c1bbde8..0000000 --- a/vendor/golang.org/x/crypto/openpgp/packet/signature_test.go +++ /dev/null @@ -1,42 +0,0 @@ -// 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" - "encoding/hex" - "testing" -) - -func TestSignatureRead(t *testing.T) { - packet, err := Read(readerFromHex(signatureDataHex)) - if err != nil { - t.Error(err) - return - } - sig, ok := packet.(*Signature) - if !ok || sig.SigType != SigTypeBinary || sig.PubKeyAlgo != PubKeyAlgoRSA || sig.Hash != crypto.SHA1 { - t.Errorf("failed to parse, got: %#v", packet) - } -} - -func TestSignatureReserialize(t *testing.T) { - packet, _ := Read(readerFromHex(signatureDataHex)) - sig := packet.(*Signature) - out := new(bytes.Buffer) - err := sig.Serialize(out) - if err != nil { - t.Errorf("error reserializing: %s", err) - return - } - - expected, _ := hex.DecodeString(signatureDataHex) - if !bytes.Equal(expected, out.Bytes()) { - t.Errorf("output doesn't match input (got vs expected):\n%s\n%s", hex.Dump(out.Bytes()), hex.Dump(expected)) - } -} - -const signatureDataHex = "c2c05c04000102000605024cb45112000a0910ab105c91af38fb158f8d07ff5596ea368c5efe015bed6e78348c0f033c931d5f2ce5db54ce7f2a7e4b4ad64db758d65a7a71773edeab7ba2a9e0908e6a94a1175edd86c1d843279f045b021a6971a72702fcbd650efc393c5474d5b59a15f96d2eaad4c4c426797e0dcca2803ef41c6ff234d403eec38f31d610c344c06f2401c262f0993b2e66cad8a81ebc4322c723e0d4ba09fe917e8777658307ad8329adacba821420741009dfe87f007759f0982275d028a392c6ed983a0d846f890b36148c7358bdb8a516007fac760261ecd06076813831a36d0459075d1befa245ae7f7fb103d92ca759e9498fe60ef8078a39a3beda510deea251ea9f0a7f0df6ef42060f20780360686f3e400e" diff --git a/vendor/golang.org/x/crypto/openpgp/packet/signature_v3.go b/vendor/golang.org/x/crypto/openpgp/packet/signature_v3.go deleted file mode 100644 index 6edff88..0000000 --- a/vendor/golang.org/x/crypto/openpgp/packet/signature_v3.go +++ /dev/null @@ -1,146 +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 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/signature_v3_test.go b/vendor/golang.org/x/crypto/openpgp/packet/signature_v3_test.go deleted file mode 100644 index ad7b62a..0000000 --- a/vendor/golang.org/x/crypto/openpgp/packet/signature_v3_test.go +++ /dev/null @@ -1,92 +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 packet - -import ( - "bytes" - "crypto" - "encoding/hex" - "io" - "io/ioutil" - "testing" - - "golang.org/x/crypto/openpgp/armor" -) - -func TestSignatureV3Read(t *testing.T) { - r := v3KeyReader(t) - Read(r) // Skip public key - Read(r) // Skip uid - packet, err := Read(r) // Signature - if err != nil { - t.Error(err) - return - } - sig, ok := packet.(*SignatureV3) - if !ok || sig.SigType != SigTypeGenericCert || sig.PubKeyAlgo != PubKeyAlgoRSA || sig.Hash != crypto.MD5 { - t.Errorf("failed to parse, got: %#v", packet) - } -} - -func TestSignatureV3Reserialize(t *testing.T) { - r := v3KeyReader(t) - Read(r) // Skip public key - Read(r) // Skip uid - packet, err := Read(r) - if err != nil { - t.Error(err) - return - } - sig := packet.(*SignatureV3) - out := new(bytes.Buffer) - if err = sig.Serialize(out); err != nil { - t.Errorf("error reserializing: %s", err) - return - } - expected, err := ioutil.ReadAll(v3KeyReader(t)) - if err != nil { - t.Error(err) - return - } - expected = expected[4+141+4+39:] // See pgpdump offsets below, this is where the sig starts - if !bytes.Equal(expected, out.Bytes()) { - t.Errorf("output doesn't match input (got vs expected):\n%s\n%s", hex.Dump(out.Bytes()), hex.Dump(expected)) - } -} - -func v3KeyReader(t *testing.T) io.Reader { - armorBlock, err := armor.Decode(bytes.NewBufferString(keySigV3Armor)) - if err != nil { - t.Fatalf("armor Decode failed: %v", err) - } - return armorBlock.Body -} - -// keySigV3Armor is some V3 public key I found in an SKS dump. -// Old: Public Key Packet(tag 6)(141 bytes) -// Ver 4 - new -// Public key creation time - Fri Sep 16 17:13:54 CDT 1994 -// Pub alg - unknown(pub 0) -// Unknown public key(pub 0) -// Old: User ID Packet(tag 13)(39 bytes) -// User ID - Armin M. Warda -// Old: Signature Packet(tag 2)(149 bytes) -// Ver 4 - new -// Sig type - unknown(05) -// Pub alg - ElGamal Encrypt-Only(pub 16) -// Hash alg - unknown(hash 46) -// Hashed Sub: unknown(sub 81, critical)(1988 bytes) -const keySigV3Armor = `-----BEGIN PGP PUBLIC KEY BLOCK----- -Version: SKS 1.0.10 - -mI0CLnoYogAAAQQA1qwA2SuJwfQ5bCQ6u5t20ulnOtY0gykf7YjiK4LiVeRBwHjGq7v30tGV -5Qti7qqRW4Ww7CDCJc4sZMFnystucR2vLkXaSoNWoFm4Fg47NiisDdhDezHwbVPW6OpCFNSi -ZAamtj4QAUBu8j4LswafrJqZqR9336/V3g8Yil2l48kABRG0J0FybWluIE0uIFdhcmRhIDx3 -YXJkYUBuZXBoaWxpbS5ydWhyLmRlPoiVAgUQLok2xwXR6zmeWEiZAQE/DgP/WgxPQh40/Po4 -gSkWZCDAjNdph7zexvAb0CcUWahcwiBIgg3U5ErCx9I5CNVA9U+s8bNrDZwgSIeBzp3KhWUx -524uhGgm6ZUTOAIKA6CbV6pfqoLpJnRYvXYQU5mIWsNa99wcu2qu18OeEDnztb7aLA6Ra9OF -YFCbq4EjXRoOrYM= -=LPjs ------END PGP PUBLIC KEY BLOCK-----` 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 deleted file mode 100644 index 4b1105b..0000000 --- a/vendor/golang.org/x/crypto/openpgp/packet/symmetric_key_encrypted.go +++ /dev/null @@ -1,155 +0,0 @@ -// 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 := len(plaintextKey); l == 0 || l%cipherFunc.blockSize() != 0 { - return nil, cipherFunc, errors.StructuralError("length of decrypted key not a multiple of block size") - } - - 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/symmetric_key_encrypted_test.go b/vendor/golang.org/x/crypto/openpgp/packet/symmetric_key_encrypted_test.go deleted file mode 100644 index 19538df..0000000 --- a/vendor/golang.org/x/crypto/openpgp/packet/symmetric_key_encrypted_test.go +++ /dev/null @@ -1,103 +0,0 @@ -// 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" - "encoding/hex" - "io" - "io/ioutil" - "testing" -) - -func TestSymmetricKeyEncrypted(t *testing.T) { - buf := readerFromHex(symmetricallyEncryptedHex) - packet, err := Read(buf) - if err != nil { - t.Errorf("failed to read SymmetricKeyEncrypted: %s", err) - return - } - ske, ok := packet.(*SymmetricKeyEncrypted) - if !ok { - t.Error("didn't find SymmetricKeyEncrypted packet") - return - } - key, cipherFunc, err := ske.Decrypt([]byte("password")) - if err != nil { - t.Error(err) - return - } - - packet, err = Read(buf) - if err != nil { - t.Errorf("failed to read SymmetricallyEncrypted: %s", err) - return - } - se, ok := packet.(*SymmetricallyEncrypted) - if !ok { - t.Error("didn't find SymmetricallyEncrypted packet") - return - } - r, err := se.Decrypt(cipherFunc, key) - if err != nil { - t.Error(err) - return - } - - contents, err := ioutil.ReadAll(r) - if err != nil && err != io.EOF { - t.Error(err) - return - } - - expectedContents, _ := hex.DecodeString(symmetricallyEncryptedContentsHex) - if !bytes.Equal(expectedContents, contents) { - t.Errorf("bad contents got:%x want:%x", contents, expectedContents) - } -} - -const symmetricallyEncryptedHex = "8c0d04030302371a0b38d884f02060c91cf97c9973b8e58e028e9501708ccfe618fb92afef7fa2d80ddadd93cf" -const symmetricallyEncryptedContentsHex = "cb1062004d14c4df636f6e74656e74732e0a" - -func TestSerializeSymmetricKeyEncrypted(t *testing.T) { - buf := bytes.NewBuffer(nil) - passphrase := []byte("testing") - const cipherFunc = CipherAES128 - config := &Config{ - DefaultCipher: cipherFunc, - } - - key, err := SerializeSymmetricKeyEncrypted(buf, passphrase, config) - if err != nil { - t.Errorf("failed to serialize: %s", err) - return - } - - p, err := Read(buf) - if err != nil { - t.Errorf("failed to reparse: %s", err) - return - } - ske, ok := p.(*SymmetricKeyEncrypted) - if !ok { - t.Errorf("parsed a different packet type: %#v", p) - return - } - - if ske.CipherFunc != config.DefaultCipher { - t.Errorf("SKE cipher function is %d (expected %d)", ske.CipherFunc, config.DefaultCipher) - } - parsedKey, parsedCipherFunc, err := ske.Decrypt(passphrase) - if err != nil { - t.Errorf("failed to decrypt reparsed SKE: %s", err) - return - } - if !bytes.Equal(key, parsedKey) { - t.Errorf("keys don't match after Decrypt: %x (original) vs %x (parsed)", key, parsedKey) - } - if parsedCipherFunc != cipherFunc { - t.Errorf("cipher function doesn't match after Decrypt: %d (original) vs %d (parsed)", cipherFunc, parsedCipherFunc) - } -} diff --git a/vendor/golang.org/x/crypto/openpgp/packet/symmetrically_encrypted.go b/vendor/golang.org/x/crypto/openpgp/packet/symmetrically_encrypted.go deleted file mode 100644 index 6126030..0000000 --- a/vendor/golang.org/x/crypto/openpgp/packet/symmetrically_encrypted.go +++ /dev/null @@ -1,290 +0,0 @@ -// 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/symmetrically_encrypted_test.go b/vendor/golang.org/x/crypto/openpgp/packet/symmetrically_encrypted_test.go deleted file mode 100644 index c5c00f7..0000000 --- a/vendor/golang.org/x/crypto/openpgp/packet/symmetrically_encrypted_test.go +++ /dev/null @@ -1,123 +0,0 @@ -// 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/sha1" - "encoding/hex" - "golang.org/x/crypto/openpgp/errors" - "io" - "io/ioutil" - "testing" -) - -// TestReader wraps a []byte and returns reads of a specific length. -type testReader struct { - data []byte - stride int -} - -func (t *testReader) Read(buf []byte) (n int, err error) { - n = t.stride - if n > len(t.data) { - n = len(t.data) - } - if n > len(buf) { - n = len(buf) - } - copy(buf, t.data) - t.data = t.data[n:] - if len(t.data) == 0 { - err = io.EOF - } - return -} - -func testMDCReader(t *testing.T) { - mdcPlaintext, _ := hex.DecodeString(mdcPlaintextHex) - - for stride := 1; stride < len(mdcPlaintext)/2; stride++ { - r := &testReader{data: mdcPlaintext, stride: stride} - mdcReader := &seMDCReader{in: r, h: sha1.New()} - body, err := ioutil.ReadAll(mdcReader) - if err != nil { - t.Errorf("stride: %d, error: %s", stride, err) - continue - } - if !bytes.Equal(body, mdcPlaintext[:len(mdcPlaintext)-22]) { - t.Errorf("stride: %d: bad contents %x", stride, body) - continue - } - - err = mdcReader.Close() - if err != nil { - t.Errorf("stride: %d, error on Close: %s", stride, err) - } - } - - mdcPlaintext[15] ^= 80 - - r := &testReader{data: mdcPlaintext, stride: 2} - mdcReader := &seMDCReader{in: r, h: sha1.New()} - _, err := ioutil.ReadAll(mdcReader) - if err != nil { - t.Errorf("corruption test, error: %s", err) - return - } - err = mdcReader.Close() - if err == nil { - t.Error("corruption: no error") - } else if _, ok := err.(*errors.SignatureError); !ok { - t.Errorf("corruption: expected SignatureError, got: %s", err) - } -} - -const mdcPlaintextHex = "a302789c3b2d93c4e0eb9aba22283539b3203335af44a134afb800c849cb4c4de10200aff40b45d31432c80cb384299a0655966d6939dfdeed1dddf980" - -func TestSerialize(t *testing.T) { - buf := bytes.NewBuffer(nil) - c := CipherAES128 - key := make([]byte, c.KeySize()) - - w, err := SerializeSymmetricallyEncrypted(buf, c, key, nil) - if err != nil { - t.Errorf("error from SerializeSymmetricallyEncrypted: %s", err) - return - } - - contents := []byte("hello world\n") - - w.Write(contents) - w.Close() - - p, err := Read(buf) - if err != nil { - t.Errorf("error from Read: %s", err) - return - } - - se, ok := p.(*SymmetricallyEncrypted) - if !ok { - t.Errorf("didn't read a *SymmetricallyEncrypted") - return - } - - r, err := se.Decrypt(c, key) - if err != nil { - t.Errorf("error from Decrypt: %s", err) - return - } - - contentsCopy := bytes.NewBuffer(nil) - _, err = io.Copy(contentsCopy, r) - if err != nil { - t.Errorf("error from io.Copy: %s", err) - return - } - if !bytes.Equal(contentsCopy.Bytes(), contents) { - t.Errorf("contents not equal got: %x want: %x", contentsCopy.Bytes(), contents) - } -} diff --git a/vendor/golang.org/x/crypto/openpgp/packet/userattribute.go b/vendor/golang.org/x/crypto/openpgp/packet/userattribute.go deleted file mode 100644 index 96a2b38..0000000 --- a/vendor/golang.org/x/crypto/openpgp/packet/userattribute.go +++ /dev/null @@ -1,91 +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 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 -// 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/userattribute_test.go b/vendor/golang.org/x/crypto/openpgp/packet/userattribute_test.go deleted file mode 100644 index 13ca514..0000000 --- a/vendor/golang.org/x/crypto/openpgp/packet/userattribute_test.go +++ /dev/null @@ -1,109 +0,0 @@ -// 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" - "encoding/base64" - "image/color" - "image/jpeg" - "testing" -) - -func TestParseUserAttribute(t *testing.T) { - r := base64.NewDecoder(base64.StdEncoding, bytes.NewBufferString(userAttributePacket)) - for i := 0; i < 2; i++ { - p, err := Read(r) - if err != nil { - t.Fatal(err) - } - uat := p.(*UserAttribute) - imgs := uat.ImageData() - if len(imgs) != 1 { - t.Errorf("Unexpected number of images in user attribute packet: %d", len(imgs)) - } - if len(imgs[0]) != 3395 { - t.Errorf("Unexpected JPEG image size: %d", len(imgs[0])) - } - img, err := jpeg.Decode(bytes.NewBuffer(imgs[0])) - if err != nil { - t.Errorf("Error decoding JPEG image: %v", err) - } - // A pixel in my right eye. - pixel := color.NRGBAModel.Convert(img.At(56, 36)) - ref := color.NRGBA{R: 157, G: 128, B: 124, A: 255} - if pixel != ref { - t.Errorf("Unexpected pixel color: %v", pixel) - } - w := bytes.NewBuffer(nil) - err = uat.Serialize(w) - if err != nil { - t.Errorf("Error writing user attribute: %v", err) - } - r = bytes.NewBuffer(w.Bytes()) - } -} - -const userAttributePacket = ` -0cyWzJQBEAABAQAAAAAAAAAAAAAAAP/Y/+AAEEpGSUYAAQIAAAEAAQAA/9sAQwAFAwQEBAMFBAQE -BQUFBgcMCAcHBwcPCgsJDBEPEhIRDxEQExYcFxMUGhUQERghGBocHR8fHxMXIiQiHiQcHh8e/9sA -QwEFBQUHBgcOCAgOHhQRFB4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4e -Hh4eHh4eHh4e/8AAEQgAZABkAwEiAAIRAQMRAf/EAB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYH -CAkKC//EALUQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHw -JDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6 -g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk -5ebn6Onq8fLz9PX29/j5+v/EAB8BAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkKC//EALURAAIB -AgQEAwQHBQQEAAECdwABAgMRBAUhMQYSQVEHYXETIjKBCBRCkaGxwQkjM1LwFWJy0QoWJDThJfEX -GBkaJicoKSo1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoKDhIWGh4iJipKT -lJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5+jp6vLz9PX2 -9/j5+v/aAAwDAQACEQMRAD8A5uGP06VehQ4pIox04q5EnHSvAep+hIIl4zVuMHGPWmRrUWtalaaN -pU2oXsgSGJSxPr6ClvoitErs0Itqjc7BQOpPAFYmrfEnwjojtHNqaXEynBjtx5hH4jj9a8B8d+Od -W8UXZjWR4LJT+7t0Jwfc+prnIdO1CWZEW2mZ3HyDactXXDB3V5s8evm1namj6r0H4weCLtxG+ova -ueP30RA/MV6not1bX0Ed1ZzxzwyDKvGwZSPqK+Ff+ES8R8t/ZV2oHUmM10Hgbxp4m8BatEfNnWBH -/eWshOxx9Kmpg4te49RUM1kn+8Wh9zQ4P1FaMC7l465rjPh14y0fxnoseoaXOpfaPOgJ+eI98j09 -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` diff --git a/vendor/golang.org/x/crypto/openpgp/packet/userid.go b/vendor/golang.org/x/crypto/openpgp/packet/userid.go deleted file mode 100644 index d6bea7d..0000000 --- a/vendor/golang.org/x/crypto/openpgp/packet/userid.go +++ /dev/null @@ -1,160 +0,0 @@ -// 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) " -type UserId struct { - Id string // By convention, this takes the form "Full Name (Comment) " 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) ". -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/packet/userid_test.go b/vendor/golang.org/x/crypto/openpgp/packet/userid_test.go deleted file mode 100644 index 2968193..0000000 --- a/vendor/golang.org/x/crypto/openpgp/packet/userid_test.go +++ /dev/null @@ -1,87 +0,0 @@ -// 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 ( - "testing" -) - -var userIdTests = []struct { - id string - name, comment, email string -}{ - {"", "", "", ""}, - {"John Smith", "John Smith", "", ""}, - {"John Smith ()", "John Smith", "", ""}, - {"John Smith () <>", "John Smith", "", ""}, - {"(comment", "", "comment", ""}, - {"(comment)", "", "comment", ""}, - {" sdfk", "", "", "email"}, - {" John Smith ( Comment ) asdkflj < email > lksdfj", "John Smith", "Comment", "email"}, - {" John Smith < email > lksdfj", "John Smith", "", "email"}, - {"("}, - {"foo", "bar", "", "foo (bar)"}, - {"foo", "", "baz", "foo "}, - {"", "bar", "baz", "(bar) "}, - {"foo", "bar", "baz", "foo (bar) "}, -} - -func TestNewUserId(t *testing.T) { - for i, test := range newUserIdTests { - uid := NewUserId(test.name, test.comment, test.email) - if uid == nil { - t.Errorf("#%d: returned nil", i) - continue - } - if uid.Id != test.id { - t.Errorf("#%d: got '%s', want '%s'", i, uid.Id, test.id) - } - } -} - -var invalidNewUserIdTests = []struct { - name, comment, email string -}{ - {"foo(", "", ""}, - {"foo<", "", ""}, - {"", "bar)", ""}, - {"", "bar<", ""}, - {"", "", "baz>"}, - {"", "", "baz)"}, - {"", "", "baz\x00"}, -} - -func TestNewUserIdWithInvalidInput(t *testing.T) { - for i, test := range invalidNewUserIdTests { - if uid := NewUserId(test.name, test.comment, test.email); uid != nil { - t.Errorf("#%d: returned non-nil value: %#v", i, uid) - } - } -} diff --git a/vendor/golang.org/x/crypto/openpgp/read.go b/vendor/golang.org/x/crypto/openpgp/read.go deleted file mode 100644 index a8bb3de..0000000 --- a/vendor/golang.org/x/crypto/openpgp/read.go +++ /dev/null @@ -1,442 +0,0 @@ -// 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. -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 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/read_test.go b/vendor/golang.org/x/crypto/openpgp/read_test.go deleted file mode 100644 index 1fbfbac..0000000 --- a/vendor/golang.org/x/crypto/openpgp/read_test.go +++ /dev/null @@ -1,613 +0,0 @@ -// 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 ( - "bytes" - _ "crypto/sha512" - "encoding/hex" - "io" - "io/ioutil" - "strings" - "testing" - - "golang.org/x/crypto/openpgp/armor" - "golang.org/x/crypto/openpgp/errors" -) - -func readerFromHex(s string) io.Reader { - data, err := hex.DecodeString(s) - if err != nil { - panic("readerFromHex: bad input") - } - return bytes.NewBuffer(data) -} - -func TestReadKeyRing(t *testing.T) { - kring, err := ReadKeyRing(readerFromHex(testKeys1And2Hex)) - if err != nil { - t.Error(err) - return - } - if len(kring) != 2 || uint32(kring[0].PrimaryKey.KeyId) != 0xC20C31BB || uint32(kring[1].PrimaryKey.KeyId) != 0x1E35246B { - t.Errorf("bad keyring: %#v", kring) - } -} - -func TestRereadKeyRing(t *testing.T) { - kring, err := ReadKeyRing(readerFromHex(testKeys1And2Hex)) - if err != nil { - t.Errorf("error in initial parse: %s", err) - return - } - out := new(bytes.Buffer) - err = kring[0].Serialize(out) - if err != nil { - t.Errorf("error in serialization: %s", err) - return - } - kring, err = ReadKeyRing(out) - if err != nil { - t.Errorf("error in second parse: %s", err) - return - } - - if len(kring) != 1 || uint32(kring[0].PrimaryKey.KeyId) != 0xC20C31BB { - t.Errorf("bad keyring: %#v", kring) - } -} - -func TestReadPrivateKeyRing(t *testing.T) { - kring, err := ReadKeyRing(readerFromHex(testKeys1And2PrivateHex)) - if err != nil { - t.Error(err) - return - } - if len(kring) != 2 || uint32(kring[0].PrimaryKey.KeyId) != 0xC20C31BB || uint32(kring[1].PrimaryKey.KeyId) != 0x1E35246B || kring[0].PrimaryKey == nil { - t.Errorf("bad keyring: %#v", kring) - } -} - -func TestReadDSAKey(t *testing.T) { - kring, err := ReadKeyRing(readerFromHex(dsaTestKeyHex)) - if err != nil { - t.Error(err) - return - } - if len(kring) != 1 || uint32(kring[0].PrimaryKey.KeyId) != 0x0CCC0360 { - t.Errorf("bad parse: %#v", kring) - } -} - -func TestReadP256Key(t *testing.T) { - kring, err := ReadKeyRing(readerFromHex(p256TestKeyHex)) - if err != nil { - t.Error(err) - return - } - if len(kring) != 1 || uint32(kring[0].PrimaryKey.KeyId) != 0x5918513E { - t.Errorf("bad parse: %#v", kring) - } -} - -func TestDSAHashTruncatation(t *testing.T) { - // dsaKeyWithSHA512 was generated with GnuPG and --cert-digest-algo - // SHA512 in order to require DSA hash truncation to verify correctly. - _, err := ReadKeyRing(readerFromHex(dsaKeyWithSHA512)) - if err != nil { - t.Error(err) - } -} - -func TestGetKeyById(t *testing.T) { - kring, _ := ReadKeyRing(readerFromHex(testKeys1And2Hex)) - - keys := kring.KeysById(0xa34d7e18c20c31bb) - if len(keys) != 1 || keys[0].Entity != kring[0] { - t.Errorf("bad result for 0xa34d7e18c20c31bb: %#v", keys) - } - - keys = kring.KeysById(0xfd94408d4543314f) - if len(keys) != 1 || keys[0].Entity != kring[0] { - t.Errorf("bad result for 0xa34d7e18c20c31bb: %#v", keys) - } -} - -func checkSignedMessage(t *testing.T, signedHex, expected string) { - kring, _ := ReadKeyRing(readerFromHex(testKeys1And2Hex)) - - md, err := ReadMessage(readerFromHex(signedHex), kring, nil, nil) - if err != nil { - t.Error(err) - return - } - - if !md.IsSigned || md.SignedByKeyId != 0xa34d7e18c20c31bb || md.SignedBy == nil || md.IsEncrypted || md.IsSymmetricallyEncrypted || len(md.EncryptedToKeyIds) != 0 || md.IsSymmetricallyEncrypted { - t.Errorf("bad MessageDetails: %#v", md) - } - - contents, err := ioutil.ReadAll(md.UnverifiedBody) - if err != nil { - t.Errorf("error reading UnverifiedBody: %s", err) - } - if string(contents) != expected { - t.Errorf("bad UnverifiedBody got:%s want:%s", string(contents), expected) - } - if md.SignatureError != nil || md.Signature == nil { - t.Errorf("failed to validate: %s", md.SignatureError) - } -} - -func TestSignedMessage(t *testing.T) { - checkSignedMessage(t, signedMessageHex, signedInput) -} - -func TestTextSignedMessage(t *testing.T) { - checkSignedMessage(t, signedTextMessageHex, signedTextInput) -} - -// The reader should detect "compressed quines", which are compressed -// packets that expand into themselves and cause an infinite recursive -// parsing loop. -// The packet in this test case comes from Taylor R. Campbell at -// http://mumble.net/~campbell/misc/pgp-quine/ -func TestCampbellQuine(t *testing.T) { - md, err := ReadMessage(readerFromHex(campbellQuine), nil, nil, nil) - if md != nil { - t.Errorf("Reading a compressed quine should not return any data: %#v", md) - } - structural, ok := err.(errors.StructuralError) - if !ok { - t.Fatalf("Unexpected class of error: %T", err) - } - if !strings.Contains(string(structural), "too many layers of packets") { - t.Fatalf("Unexpected error: %s", err) - } -} - -var signedEncryptedMessageTests = []struct { - keyRingHex string - messageHex string - signedByKeyId uint64 - encryptedToKeyId uint64 -}{ - { - testKeys1And2PrivateHex, - signedEncryptedMessageHex, - 0xa34d7e18c20c31bb, - 0x2a67d68660df41c7, - }, - { - dsaElGamalTestKeysHex, - signedEncryptedMessage2Hex, - 0x33af447ccd759b09, - 0xcf6a7abcd43e3673, - }, -} - -func TestSignedEncryptedMessage(t *testing.T) { - for i, test := range signedEncryptedMessageTests { - expected := "Signed and encrypted message\n" - kring, _ := ReadKeyRing(readerFromHex(test.keyRingHex)) - prompt := func(keys []Key, symmetric bool) ([]byte, error) { - if symmetric { - t.Errorf("prompt: message was marked as symmetrically encrypted") - return nil, errors.ErrKeyIncorrect - } - - if len(keys) == 0 { - t.Error("prompt: no keys requested") - return nil, errors.ErrKeyIncorrect - } - - err := keys[0].PrivateKey.Decrypt([]byte("passphrase")) - if err != nil { - t.Errorf("prompt: error decrypting key: %s", err) - return nil, errors.ErrKeyIncorrect - } - - return nil, nil - } - - md, err := ReadMessage(readerFromHex(test.messageHex), kring, prompt, nil) - if err != nil { - t.Errorf("#%d: error reading message: %s", i, err) - return - } - - if !md.IsSigned || md.SignedByKeyId != test.signedByKeyId || md.SignedBy == nil || !md.IsEncrypted || md.IsSymmetricallyEncrypted || len(md.EncryptedToKeyIds) == 0 || md.EncryptedToKeyIds[0] != test.encryptedToKeyId { - t.Errorf("#%d: bad MessageDetails: %#v", i, md) - } - - contents, err := ioutil.ReadAll(md.UnverifiedBody) - if err != nil { - t.Errorf("#%d: error reading UnverifiedBody: %s", i, err) - } - if string(contents) != expected { - t.Errorf("#%d: bad UnverifiedBody got:%s want:%s", i, string(contents), expected) - } - - if md.SignatureError != nil || md.Signature == nil { - t.Errorf("#%d: failed to validate: %s", i, md.SignatureError) - } - } -} - -func TestUnspecifiedRecipient(t *testing.T) { - expected := "Recipient unspecified\n" - kring, _ := ReadKeyRing(readerFromHex(testKeys1And2PrivateHex)) - - md, err := ReadMessage(readerFromHex(recipientUnspecifiedHex), kring, nil, nil) - if err != nil { - t.Errorf("error reading message: %s", err) - return - } - - contents, err := ioutil.ReadAll(md.UnverifiedBody) - if err != nil { - t.Errorf("error reading UnverifiedBody: %s", err) - } - if string(contents) != expected { - t.Errorf("bad UnverifiedBody got:%s want:%s", string(contents), expected) - } -} - -func TestSymmetricallyEncrypted(t *testing.T) { - firstTimeCalled := true - - prompt := func(keys []Key, symmetric bool) ([]byte, error) { - if len(keys) != 0 { - t.Errorf("prompt: len(keys) = %d (want 0)", len(keys)) - } - - if !symmetric { - t.Errorf("symmetric is not set") - } - - if firstTimeCalled { - firstTimeCalled = false - return []byte("wrongpassword"), nil - } - - return []byte("password"), nil - } - - md, err := ReadMessage(readerFromHex(symmetricallyEncryptedCompressedHex), nil, prompt, nil) - if err != nil { - t.Errorf("ReadMessage: %s", err) - return - } - - contents, err := ioutil.ReadAll(md.UnverifiedBody) - if err != nil { - t.Errorf("ReadAll: %s", err) - } - - expectedCreationTime := uint32(1295992998) - if md.LiteralData.Time != expectedCreationTime { - t.Errorf("LiteralData.Time is %d, want %d", md.LiteralData.Time, expectedCreationTime) - } - - const expected = "Symmetrically encrypted.\n" - if string(contents) != expected { - t.Errorf("contents got: %s want: %s", string(contents), expected) - } -} - -func testDetachedSignature(t *testing.T, kring KeyRing, signature io.Reader, sigInput, tag string, expectedSignerKeyId uint64) { - signed := bytes.NewBufferString(sigInput) - signer, err := CheckDetachedSignature(kring, signed, signature) - if err != nil { - t.Errorf("%s: signature error: %s", tag, err) - return - } - if signer == nil { - t.Errorf("%s: signer is nil", tag) - return - } - if signer.PrimaryKey.KeyId != expectedSignerKeyId { - t.Errorf("%s: wrong signer got:%x want:%x", tag, signer.PrimaryKey.KeyId, expectedSignerKeyId) - } -} - -func TestDetachedSignature(t *testing.T) { - kring, _ := ReadKeyRing(readerFromHex(testKeys1And2Hex)) - testDetachedSignature(t, kring, readerFromHex(detachedSignatureHex), signedInput, "binary", testKey1KeyId) - testDetachedSignature(t, kring, readerFromHex(detachedSignatureTextHex), signedInput, "text", testKey1KeyId) - testDetachedSignature(t, kring, readerFromHex(detachedSignatureV3TextHex), signedInput, "v3", testKey1KeyId) - - incorrectSignedInput := signedInput + "X" - _, err := CheckDetachedSignature(kring, bytes.NewBufferString(incorrectSignedInput), readerFromHex(detachedSignatureHex)) - if err == nil { - t.Fatal("CheckDetachedSignature returned without error for bad signature") - } - if err == errors.ErrUnknownIssuer { - t.Fatal("CheckDetachedSignature returned ErrUnknownIssuer when the signer was known, but the signature invalid") - } -} - -func TestDetachedSignatureDSA(t *testing.T) { - kring, _ := ReadKeyRing(readerFromHex(dsaTestKeyHex)) - testDetachedSignature(t, kring, readerFromHex(detachedSignatureDSAHex), signedInput, "binary", testKey3KeyId) -} - -func TestMultipleSignaturePacketsDSA(t *testing.T) { - kring, _ := ReadKeyRing(readerFromHex(dsaTestKeyHex)) - testDetachedSignature(t, kring, readerFromHex(missingHashFunctionHex+detachedSignatureDSAHex), signedInput, "binary", testKey3KeyId) -} - -func TestDetachedSignatureP256(t *testing.T) { - kring, _ := ReadKeyRing(readerFromHex(p256TestKeyHex)) - testDetachedSignature(t, kring, readerFromHex(detachedSignatureP256Hex), signedInput, "binary", testKeyP256KeyId) -} - -func testHashFunctionError(t *testing.T, signatureHex string) { - kring, _ := ReadKeyRing(readerFromHex(testKeys1And2Hex)) - _, err := CheckDetachedSignature(kring, nil, readerFromHex(signatureHex)) - if err == nil { - t.Fatal("Packet with bad hash type was correctly parsed") - } - unsupported, ok := err.(errors.UnsupportedError) - if !ok { - t.Fatalf("Unexpected class of error: %s", err) - } - if !strings.Contains(string(unsupported), "hash ") { - t.Fatalf("Unexpected error: %s", err) - } -} - -func TestUnknownHashFunction(t *testing.T) { - // unknownHashFunctionHex contains a signature packet with hash - // function type 153 (which isn't a real hash function id). - testHashFunctionError(t, unknownHashFunctionHex) -} - -func TestMissingHashFunction(t *testing.T) { - // missingHashFunctionHex contains a signature packet that uses - // RIPEMD160, which isn't compiled in. Since that's the only signature - // packet we don't find any suitable packets and end up with ErrUnknownIssuer - kring, _ := ReadKeyRing(readerFromHex(testKeys1And2Hex)) - _, err := CheckDetachedSignature(kring, nil, readerFromHex(missingHashFunctionHex)) - if err == nil { - t.Fatal("Packet with missing hash type was correctly parsed") - } - if err != errors.ErrUnknownIssuer { - t.Fatalf("Unexpected class of error: %s", err) - } -} - -func TestReadingArmoredPrivateKey(t *testing.T) { - el, err := ReadArmoredKeyRing(bytes.NewBufferString(armoredPrivateKeyBlock)) - if err != nil { - t.Error(err) - } - if len(el) != 1 { - t.Errorf("got %d entities, wanted 1\n", len(el)) - } -} - -func TestReadingArmoredPublicKey(t *testing.T) { - el, err := ReadArmoredKeyRing(bytes.NewBufferString(e2ePublicKey)) - if err != nil { - t.Error(err) - } - if len(el) != 1 { - t.Errorf("didn't get a valid entity") - } -} - -func TestNoArmoredData(t *testing.T) { - _, err := ReadArmoredKeyRing(bytes.NewBufferString("foo")) - if _, ok := err.(errors.InvalidArgumentError); !ok { - t.Errorf("error was not an InvalidArgumentError: %s", err) - } -} - -func testReadMessageError(t *testing.T, messageHex string) { - buf, err := hex.DecodeString(messageHex) - if err != nil { - t.Errorf("hex.DecodeString(): %v", err) - } - - kr, err := ReadKeyRing(new(bytes.Buffer)) - if err != nil { - t.Errorf("ReadKeyring(): %v", err) - } - - _, err = ReadMessage(bytes.NewBuffer(buf), kr, - func([]Key, bool) ([]byte, error) { - return []byte("insecure"), nil - }, nil) - - if err == nil { - t.Errorf("ReadMessage(): Unexpected nil error") - } -} - -func TestIssue11503(t *testing.T) { - testReadMessageError(t, "8c040402000aa430aa8228b9248b01fc899a91197130303030") -} - -func TestIssue11504(t *testing.T) { - testReadMessageError(t, "9303000130303030303030303030983002303030303030030000000130") -} - -// TestSignatureV3Message tests the verification of V3 signature, generated -// with a modern V4-style key. Some people have their clients set to generate -// V3 signatures, so it's useful to be able to verify them. -func TestSignatureV3Message(t *testing.T) { - sig, err := armor.Decode(strings.NewReader(signedMessageV3)) - if err != nil { - t.Error(err) - return - } - key, err := ReadArmoredKeyRing(strings.NewReader(keyV4forVerifyingSignedMessageV3)) - if err != nil { - t.Error(err) - return - } - md, err := ReadMessage(sig.Body, key, nil, nil) - if err != nil { - t.Error(err) - return - } - - _, err = ioutil.ReadAll(md.UnverifiedBody) - if err != nil { - t.Error(err) - return - } - - // We'll see a sig error here after reading in the UnverifiedBody above, - // if there was one to see. - if err = md.SignatureError; err != nil { - t.Error(err) - return - } - - if md.SignatureV3 == nil { - t.Errorf("No available signature after checking signature") - return - } - if md.Signature != nil { - t.Errorf("Did not expect a signature V4 back") - return - } - return -} - -const testKey1KeyId = 0xA34D7E18C20C31BB -const testKey3KeyId = 0x338934250CCC0360 -const testKeyP256KeyId = 0xd44a2c495918513e - -const signedInput = "Signed message\nline 2\nline 3\n" -const signedTextInput = "Signed message\r\nline 2\r\nline 3\r\n" - -const recipientUnspecifiedHex = "848c0300000000000000000103ff62d4d578d03cf40c3da998dfe216c074fa6ddec5e31c197c9666ba292830d91d18716a80f699f9d897389a90e6d62d0238f5f07a5248073c0f24920e4bc4a30c2d17ee4e0cae7c3d4aaa4e8dced50e3010a80ee692175fa0385f62ecca4b56ee6e9980aa3ec51b61b077096ac9e800edaf161268593eedb6cc7027ff5cb32745d250010d407a6221ae22ef18469b444f2822478c4d190b24d36371a95cb40087cdd42d9399c3d06a53c0673349bfb607927f20d1e122bde1e2bf3aa6cae6edf489629bcaa0689539ae3b718914d88ededc3b" - -const detachedSignatureHex = "889c04000102000605024d449cd1000a0910a34d7e18c20c31bb167603ff57718d09f28a519fdc7b5a68b6a3336da04df85e38c5cd5d5bd2092fa4629848a33d85b1729402a2aab39c3ac19f9d573f773cc62c264dc924c067a79dfd8a863ae06c7c8686120760749f5fd9b1e03a64d20a7df3446ddc8f0aeadeaeba7cbaee5c1e366d65b6a0c6cc749bcb912d2f15013f812795c2e29eb7f7b77f39ce77" - -const detachedSignatureTextHex = "889c04010102000605024d449d21000a0910a34d7e18c20c31bbc8c60400a24fbef7342603a41cb1165767bd18985d015fb72fe05db42db36cfb2f1d455967f1e491194fbf6cf88146222b23bf6ffbd50d17598d976a0417d3192ff9cc0034fd00f287b02e90418bbefe609484b09231e4e7a5f3562e199bf39909ab5276c4d37382fe088f6b5c3426fc1052865da8b3ab158672d58b6264b10823dc4b39" - -const detachedSignatureV3TextHex = "8900950305005255c25ca34d7e18c20c31bb0102bb3f04009f6589ef8a028d6e54f6eaf25432e590d31c3a41f4710897585e10c31e5e332c7f9f409af8512adceaff24d0da1474ab07aa7bce4f674610b010fccc5b579ae5eb00a127f272fb799f988ab8e4574c141da6dbfecfef7e6b2c478d9a3d2551ba741f260ee22bec762812f0053e05380bfdd55ad0f22d8cdf71b233fe51ae8a24" - -const detachedSignatureDSAHex = "884604001102000605024d6c4eac000a0910338934250ccc0360f18d00a087d743d6405ed7b87755476629600b8b694a39e900a0abff8126f46faf1547c1743c37b21b4ea15b8f83" - -const detachedSignatureP256Hex = "885e0400130a0006050256e5bb00000a0910d44a2c495918513edef001009841a4f792beb0befccb35c8838a6a87d9b936beaa86db6745ddc7b045eee0cf00fd1ac1f78306b17e965935dd3f8bae4587a76587e4af231efe19cc4011a8434817" - -const testKeys1And2Hex = "988d044d3c5c10010400b1d13382944bd5aba23a4312968b5095d14f947f600eb478e14a6fcb16b0e0cac764884909c020bc495cfcc39a935387c661507bdb236a0612fb582cac3af9b29cc2c8c70090616c41b662f4da4c1201e195472eb7f4ae1ccbcbf9940fe21d985e379a5563dde5b9a23d35f1cfaa5790da3b79db26f23695107bfaca8e7b5bcd0011010001b41054657374204b6579203120285253412988b804130102002205024d3c5c10021b03060b090807030206150802090a0b0416020301021e01021780000a0910a34d7e18c20c31bbb5b304009cc45fe610b641a2c146331be94dade0a396e73ca725e1b25c21708d9cab46ecca5ccebc23055879df8f99eea39b377962a400f2ebdc36a7c99c333d74aeba346315137c3ff9d0a09b0273299090343048afb8107cf94cbd1400e3026f0ccac7ecebbc4d78588eb3e478fe2754d3ca664bcf3eac96ca4a6b0c8d7df5102f60f6b0020003b88d044d3c5c10010400b201df61d67487301f11879d514f4248ade90c8f68c7af1284c161098de4c28c2850f1ec7b8e30f959793e571542ffc6532189409cb51c3d30dad78c4ad5165eda18b20d9826d8707d0f742e2ab492103a85bbd9ddf4f5720f6de7064feb0d39ee002219765bb07bcfb8b877f47abe270ddeda4f676108cecb6b9bb2ad484a4f0011010001889f04180102000905024d3c5c10021b0c000a0910a34d7e18c20c31bb1a03040085c8d62e16d05dc4e9dad64953c8a2eed8b6c12f92b1575eeaa6dcf7be9473dd5b24b37b6dffbb4e7c99ed1bd3cb11634be19b3e6e207bed7505c7ca111ccf47cb323bf1f8851eb6360e8034cbff8dd149993c959de89f8f77f38e7e98b8e3076323aa719328e2b408db5ec0d03936efd57422ba04f925cdc7b4c1af7590e40ab0020003988d044d3c5c33010400b488c3e5f83f4d561f317817538d9d0397981e9aef1321ca68ebfae1cf8b7d388e19f4b5a24a82e2fbbf1c6c26557a6c5845307a03d815756f564ac7325b02bc83e87d5480a8fae848f07cb891f2d51ce7df83dcafdc12324517c86d472cc0ee10d47a68fd1d9ae49a6c19bbd36d82af597a0d88cc9c49de9df4e696fc1f0b5d0011010001b42754657374204b6579203220285253412c20656e637279707465642070726976617465206b65792988b804130102002205024d3c5c33021b03060b090807030206150802090a0b0416020301021e01021780000a0910d4984f961e35246b98940400908a73b6a6169f700434f076c6c79015a49bee37130eaf23aaa3cfa9ce60bfe4acaa7bc95f1146ada5867e0079babb38804891f4f0b8ebca57a86b249dee786161a755b7a342e68ccf3f78ed6440a93a6626beb9a37aa66afcd4f888790cb4bb46d94a4ae3eb3d7d3e6b00f6bfec940303e89ec5b32a1eaaacce66497d539328b0020003b88d044d3c5c33010400a4e913f9442abcc7f1804ccab27d2f787ffa592077ca935a8bb23165bd8d57576acac647cc596b2c3f814518cc8c82953c7a4478f32e0cf645630a5ba38d9618ef2bc3add69d459ae3dece5cab778938d988239f8c5ae437807075e06c828019959c644ff05ef6a5a1dab72227c98e3a040b0cf219026640698d7a13d8538a570011010001889f04180102000905024d3c5c33021b0c000a0910d4984f961e35246b26c703ff7ee29ef53bc1ae1ead533c408fa136db508434e233d6e62be621e031e5940bbd4c08142aed0f82217e7c3e1ec8de574bc06ccf3c36633be41ad78a9eacd209f861cae7b064100758545cc9dd83db71806dc1cfd5fb9ae5c7474bba0c19c44034ae61bae5eca379383339dece94ff56ff7aa44a582f3e5c38f45763af577c0934b0020003" - -const testKeys1And2PrivateHex = "9501d8044d3c5c10010400b1d13382944bd5aba23a4312968b5095d14f947f600eb478e14a6fcb16b0e0cac764884909c020bc495cfcc39a935387c661507bdb236a0612fb582cac3af9b29cc2c8c70090616c41b662f4da4c1201e195472eb7f4ae1ccbcbf9940fe21d985e379a5563dde5b9a23d35f1cfaa5790da3b79db26f23695107bfaca8e7b5bcd00110100010003ff4d91393b9a8e3430b14d6209df42f98dc927425b881f1209f319220841273a802a97c7bdb8b3a7740b3ab5866c4d1d308ad0d3a79bd1e883aacf1ac92dfe720285d10d08752a7efe3c609b1d00f17f2805b217be53999a7da7e493bfc3e9618fd17018991b8128aea70a05dbce30e4fbe626aa45775fa255dd9177aabf4df7cf0200c1ded12566e4bc2bb590455e5becfb2e2c9796482270a943343a7835de41080582c2be3caf5981aa838140e97afa40ad652a0b544f83eb1833b0957dce26e47b0200eacd6046741e9ce2ec5beb6fb5e6335457844fb09477f83b050a96be7da043e17f3a9523567ed40e7a521f818813a8b8a72209f1442844843ccc7eb9805442570200bdafe0438d97ac36e773c7162028d65844c4d463e2420aa2228c6e50dc2743c3d6c72d0d782a5173fe7be2169c8a9f4ef8a7cf3e37165e8c61b89c346cdc6c1799d2b41054657374204b6579203120285253412988b804130102002205024d3c5c10021b03060b090807030206150802090a0b0416020301021e01021780000a0910a34d7e18c20c31bbb5b304009cc45fe610b641a2c146331be94dade0a396e73ca725e1b25c21708d9cab46ecca5ccebc23055879df8f99eea39b377962a400f2ebdc36a7c99c333d74aeba346315137c3ff9d0a09b0273299090343048afb8107cf94cbd1400e3026f0ccac7ecebbc4d78588eb3e478fe2754d3ca664bcf3eac96ca4a6b0c8d7df5102f60f6b00200009d01d8044d3c5c10010400b201df61d67487301f11879d514f4248ade90c8f68c7af1284c161098de4c28c2850f1ec7b8e30f959793e571542ffc6532189409cb51c3d30dad78c4ad5165eda18b20d9826d8707d0f742e2ab492103a85bbd9ddf4f5720f6de7064feb0d39ee002219765bb07bcfb8b877f47abe270ddeda4f676108cecb6b9bb2ad484a4f00110100010003fd17a7490c22a79c59281fb7b20f5e6553ec0c1637ae382e8adaea295f50241037f8997cf42c1ce26417e015091451b15424b2c59eb8d4161b0975630408e394d3b00f88d4b4e18e2cc85e8251d4753a27c639c83f5ad4a571c4f19d7cd460b9b73c25ade730c99df09637bd173d8e3e981ac64432078263bb6dc30d3e974150dd0200d0ee05be3d4604d2146fb0457f31ba17c057560785aa804e8ca5530a7cd81d3440d0f4ba6851efcfd3954b7e68908fc0ba47f7ac37bf559c6c168b70d3a7c8cd0200da1c677c4bce06a068070f2b3733b0a714e88d62aa3f9a26c6f5216d48d5c2b5624144f3807c0df30be66b3268eeeca4df1fbded58faf49fc95dc3c35f134f8b01fd1396b6c0fc1b6c4f0eb8f5e44b8eace1e6073e20d0b8bc5385f86f1cf3f050f66af789f3ef1fc107b7f4421e19e0349c730c68f0a226981f4e889054fdb4dc149e8e889f04180102000905024d3c5c10021b0c000a0910a34d7e18c20c31bb1a03040085c8d62e16d05dc4e9dad64953c8a2eed8b6c12f92b1575eeaa6dcf7be9473dd5b24b37b6dffbb4e7c99ed1bd3cb11634be19b3e6e207bed7505c7ca111ccf47cb323bf1f8851eb6360e8034cbff8dd149993c959de89f8f77f38e7e98b8e3076323aa719328e2b408db5ec0d03936efd57422ba04f925cdc7b4c1af7590e40ab00200009501fe044d3c5c33010400b488c3e5f83f4d561f317817538d9d0397981e9aef1321ca68ebfae1cf8b7d388e19f4b5a24a82e2fbbf1c6c26557a6c5845307a03d815756f564ac7325b02bc83e87d5480a8fae848f07cb891f2d51ce7df83dcafdc12324517c86d472cc0ee10d47a68fd1d9ae49a6c19bbd36d82af597a0d88cc9c49de9df4e696fc1f0b5d0011010001fe030302e9030f3c783e14856063f16938530e148bc57a7aa3f3e4f90df9dceccdc779bc0835e1ad3d006e4a8d7b36d08b8e0de5a0d947254ecfbd22037e6572b426bcfdc517796b224b0036ff90bc574b5509bede85512f2eefb520fb4b02aa523ba739bff424a6fe81c5041f253f8d757e69a503d3563a104d0d49e9e890b9d0c26f96b55b743883b472caa7050c4acfd4a21f875bdf1258d88bd61224d303dc9df77f743137d51e6d5246b88c406780528fd9a3e15bab5452e5b93970d9dcc79f48b38651b9f15bfbcf6da452837e9cc70683d1bdca94507870f743e4ad902005812488dd342f836e72869afd00ce1850eea4cfa53ce10e3608e13d3c149394ee3cbd0e23d018fcbcb6e2ec5a1a22972d1d462ca05355d0d290dd2751e550d5efb38c6c89686344df64852bf4ff86638708f644e8ec6bd4af9b50d8541cb91891a431326ab2e332faa7ae86cfb6e0540aa63160c1e5cdd5a4add518b303fff0a20117c6bc77f7cfbaf36b04c865c6c2b42754657374204b6579203220285253412c20656e637279707465642070726976617465206b65792988b804130102002205024d3c5c33021b03060b090807030206150802090a0b0416020301021e01021780000a0910d4984f961e35246b98940400908a73b6a6169f700434f076c6c79015a49bee37130eaf23aaa3cfa9ce60bfe4acaa7bc95f1146ada5867e0079babb38804891f4f0b8ebca57a86b249dee786161a755b7a342e68ccf3f78ed6440a93a6626beb9a37aa66afcd4f888790cb4bb46d94a4ae3eb3d7d3e6b00f6bfec940303e89ec5b32a1eaaacce66497d539328b00200009d01fe044d3c5c33010400a4e913f9442abcc7f1804ccab27d2f787ffa592077ca935a8bb23165bd8d57576acac647cc596b2c3f814518cc8c82953c7a4478f32e0cf645630a5ba38d9618ef2bc3add69d459ae3dece5cab778938d988239f8c5ae437807075e06c828019959c644ff05ef6a5a1dab72227c98e3a040b0cf219026640698d7a13d8538a570011010001fe030302e9030f3c783e148560f936097339ae381d63116efcf802ff8b1c9360767db5219cc987375702a4123fd8657d3e22700f23f95020d1b261eda5257e9a72f9a918e8ef22dd5b3323ae03bbc1923dd224db988cadc16acc04b120a9f8b7e84da9716c53e0334d7b66586ddb9014df604b41be1e960dcfcbc96f4ed150a1a0dd070b9eb14276b9b6be413a769a75b519a53d3ecc0c220e85cd91ca354d57e7344517e64b43b6e29823cbd87eae26e2b2e78e6dedfbb76e3e9f77bcb844f9a8932eb3db2c3f9e44316e6f5d60e9e2a56e46b72abe6b06dc9a31cc63f10023d1f5e12d2a3ee93b675c96f504af0001220991c88db759e231b3320dcedf814dcf723fd9857e3d72d66a0f2af26950b915abdf56c1596f46a325bf17ad4810d3535fb02a259b247ac3dbd4cc3ecf9c51b6c07cebb009c1506fba0a89321ec8683e3fd009a6e551d50243e2d5092fefb3321083a4bad91320dc624bd6b5dddf93553e3d53924c05bfebec1fb4bd47e89a1a889f04180102000905024d3c5c33021b0c000a0910d4984f961e35246b26c703ff7ee29ef53bc1ae1ead533c408fa136db508434e233d6e62be621e031e5940bbd4c08142aed0f82217e7c3e1ec8de574bc06ccf3c36633be41ad78a9eacd209f861cae7b064100758545cc9dd83db71806dc1cfd5fb9ae5c7474bba0c19c44034ae61bae5eca379383339dece94ff56ff7aa44a582f3e5c38f45763af577c0934b0020000" - -const dsaElGamalTestKeysHex = "9501e1044dfcb16a110400aa3e5c1a1f43dd28c2ffae8abf5cfce555ee874134d8ba0a0f7b868ce2214beddc74e5e1e21ded354a95d18acdaf69e5e342371a71fbb9093162e0c5f3427de413a7f2c157d83f5cd2f9d791256dc4f6f0e13f13c3302af27f2384075ab3021dff7a050e14854bbde0a1094174855fc02f0bae8e00a340d94a1f22b32e48485700a0cec672ac21258fb95f61de2ce1af74b2c4fa3e6703ff698edc9be22c02ae4d916e4fa223f819d46582c0516235848a77b577ea49018dcd5e9e15cff9dbb4663a1ae6dd7580fa40946d40c05f72814b0f88481207e6c0832c3bded4853ebba0a7e3bd8e8c66df33d5a537cd4acf946d1080e7a3dcea679cb2b11a72a33a2b6a9dc85f466ad2ddf4c3db6283fa645343286971e3dd700703fc0c4e290d45767f370831a90187e74e9972aae5bff488eeff7d620af0362bfb95c1a6c3413ab5d15a2e4139e5d07a54d72583914661ed6a87cce810be28a0aa8879a2dd39e52fb6fe800f4f181ac7e328f740cde3d09a05cecf9483e4cca4253e60d4429ffd679d9996a520012aad119878c941e3cf151459873bdfc2a9563472fe0303027a728f9feb3b864260a1babe83925ce794710cfd642ee4ae0e5b9d74cee49e9c67b6cd0ea5dfbb582132195a121356a1513e1bca73e5b80c58c7ccb4164453412f456c47616d616c2054657374204b65792031886204131102002205024dfcb16a021b03060b090807030206150802090a0b0416020301021e01021780000a091033af447ccd759b09fadd00a0b8fd6f5a790bad7e9f2dbb7632046dc4493588db009c087c6a9ba9f7f49fab221587a74788c00db4889ab00200009d0157044dfcb16a1004008dec3f9291205255ccff8c532318133a6840739dd68b03ba942676f9038612071447bf07d00d559c5c0875724ea16a4c774f80d8338b55fca691a0522e530e604215b467bbc9ccfd483a1da99d7bc2648b4318fdbd27766fc8bfad3fddb37c62b8ae7ccfe9577e9b8d1e77c1d417ed2c2ef02d52f4da11600d85d3229607943700030503ff506c94c87c8cab778e963b76cf63770f0a79bf48fb49d3b4e52234620fc9f7657f9f8d56c96a2b7c7826ae6b57ebb2221a3fe154b03b6637cea7e6d98e3e45d87cf8dc432f723d3d71f89c5192ac8d7290684d2c25ce55846a80c9a7823f6acd9bb29fa6cd71f20bc90eccfca20451d0c976e460e672b000df49466408d527affe0303027a728f9feb3b864260abd761730327bca2aaa4ea0525c175e92bf240682a0e83b226f97ecb2e935b62c9a133858ce31b271fa8eb41f6a1b3cd72a63025ce1a75ee4180dcc284884904181102000905024dfcb16a021b0c000a091033af447ccd759b09dd0b009e3c3e7296092c81bee5a19929462caaf2fff3ae26009e218c437a2340e7ea628149af1ec98ec091a43992b00200009501e1044dfcb1be1104009f61faa61aa43df75d128cbe53de528c4aec49ce9360c992e70c77072ad5623de0a3a6212771b66b39a30dad6781799e92608316900518ec01184a85d872365b7d2ba4bacfb5882ea3c2473d3750dc6178cc1cf82147fb58caa28b28e9f12f6d1efcb0534abed644156c91cca4ab78834268495160b2400bc422beb37d237c2300a0cac94911b6d493bda1e1fbc6feeca7cb7421d34b03fe22cec6ccb39675bb7b94a335c2b7be888fd3906a1125f33301d8aa6ec6ee6878f46f73961c8d57a3e9544d8ef2a2cbfd4d52da665b1266928cfe4cb347a58c412815f3b2d2369dec04b41ac9a71cc9547426d5ab941cccf3b18575637ccfb42df1a802df3cfe0a999f9e7109331170e3a221991bf868543960f8c816c28097e503fe319db10fb98049f3a57d7c80c420da66d56f3644371631fad3f0ff4040a19a4fedc2d07727a1b27576f75a4d28c47d8246f27071e12d7a8de62aad216ddbae6aa02efd6b8a3e2818cda48526549791ab277e447b3a36c57cefe9b592f5eab73959743fcc8e83cbefec03a329b55018b53eec196765ae40ef9e20521a603c551efe0303020950d53a146bf9c66034d00c23130cce95576a2ff78016ca471276e8227fb30b1ffbd92e61804fb0c3eff9e30b1a826ee8f3e4730b4d86273ca977b4164453412f456c47616d616c2054657374204b65792032886204131102002205024dfcb1be021b03060b090807030206150802090a0b0416020301021e01021780000a0910a86bf526325b21b22bd9009e34511620415c974750a20df5cb56b182f3b48e6600a0a9466cb1a1305a84953445f77d461593f1d42bc1b00200009d0157044dfcb1be1004009565a951da1ee87119d600c077198f1c1bceb0f7aa54552489298e41ff788fa8f0d43a69871f0f6f77ebdfb14a4260cf9fbeb65d5844b4272a1904dd95136d06c3da745dc46327dd44a0f16f60135914368c8039a34033862261806bb2c5ce1152e2840254697872c85441ccb7321431d75a747a4bfb1d2c66362b51ce76311700030503fc0ea76601c196768070b7365a200e6ddb09307f262d5f39eec467b5f5784e22abdf1aa49226f59ab37cb49969d8f5230ea65caf56015abda62604544ed526c5c522bf92bed178a078789f6c807b6d34885688024a5bed9e9f8c58d11d4b82487b44c5f470c5606806a0443b79cadb45e0f897a561a53f724e5349b9267c75ca17fe0303020950d53a146bf9c660bc5f4ce8f072465e2d2466434320c1e712272fafc20e342fe7608101580fa1a1a367e60486a7cd1246b7ef5586cf5e10b32762b710a30144f12dd17dd4884904181102000905024dfcb1be021b0c000a0910a86bf526325b21b2904c00a0b2b66b4b39ccffda1d10f3ea8d58f827e30a8b8e009f4255b2d8112a184e40cde43a34e8655ca7809370b0020000" - -const signedMessageHex = "a3019bc0cbccc0c4b8d8b74ee2108fe16ec6d3ca490cbe362d3f8333d3f352531472538b8b13d353b97232f352158c20943157c71c16064626063656269052062e4e01987e9b6fccff4b7df3a34c534b23e679cbec3bc0f8f6e64dfb4b55fe3f8efa9ce110ddb5cd79faf1d753c51aecfa669f7e7aa043436596cccc3359cb7dd6bbe9ecaa69e5989d9e57209571edc0b2fa7f57b9b79a64ee6e99ce1371395fee92fec2796f7b15a77c386ff668ee27f6d38f0baa6c438b561657377bf6acff3c5947befd7bf4c196252f1d6e5c524d0300" - -const signedTextMessageHex = "a3019bc0cbccc8c4b8d8b74ee2108fe16ec6d36a250cbece0c178233d3f352531472538b8b13d35379b97232f352158ca0b4312f57c71c1646462606365626906a062e4e019811591798ff99bf8afee860b0d8a8c2a85c3387e3bcf0bb3b17987f2bbcfab2aa526d930cbfd3d98757184df3995c9f3e7790e36e3e9779f06089d4c64e9e47dd6202cb6e9bc73c5d11bb59fbaf89d22d8dc7cf199ddf17af96e77c5f65f9bbed56f427bd8db7af37f6c9984bf9385efaf5f184f986fb3e6adb0ecfe35bbf92d16a7aa2a344fb0bc52fb7624f0200" - -const signedEncryptedMessageHex = "848c032a67d68660df41c70103ff5789d0de26b6a50c985a02a13131ca829c413a35d0e6fa8d6842599252162808ac7439c72151c8c6183e76923fe3299301414d0c25a2f06a2257db3839e7df0ec964773f6e4c4ac7ff3b48c444237166dd46ba8ff443a5410dc670cb486672fdbe7c9dfafb75b4fea83af3a204fe2a7dfa86bd20122b4f3d2646cbeecb8f7be8d2c03b018bd210b1d3791e1aba74b0f1034e122ab72e760492c192383cf5e20b5628bd043272d63df9b923f147eb6091cd897553204832aba48fec54aa447547bb16305a1024713b90e77fd0065f1918271947549205af3c74891af22ee0b56cd29bfec6d6e351901cd4ab3ece7c486f1e32a792d4e474aed98ee84b3f591c7dff37b64e0ecd68fd036d517e412dcadf85840ce184ad7921ad446c4ee28db80447aea1ca8d4f574db4d4e37688158ddd19e14ee2eab4873d46947d65d14a23e788d912cf9a19624ca7352469b72a83866b7c23cb5ace3deab3c7018061b0ba0f39ed2befe27163e5083cf9b8271e3e3d52cc7ad6e2a3bd81d4c3d7022f8d" - -const signedEncryptedMessage2Hex = "85010e03cf6a7abcd43e36731003fb057f5495b79db367e277cdbe4ab90d924ddee0c0381494112ff8c1238fb0184af35d1731573b01bc4c55ecacd2aafbe2003d36310487d1ecc9ac994f3fada7f9f7f5c3a64248ab7782906c82c6ff1303b69a84d9a9529c31ecafbcdb9ba87e05439897d87e8a2a3dec55e14df19bba7f7bd316291c002ae2efd24f83f9e3441203fc081c0c23dc3092a454ca8a082b27f631abf73aca341686982e8fbda7e0e7d863941d68f3de4a755c2964407f4b5e0477b3196b8c93d551dd23c8beef7d0f03fbb1b6066f78907faf4bf1677d8fcec72651124080e0b7feae6b476e72ab207d38d90b958759fdedfc3c6c35717c9dbfc979b3cfbbff0a76d24a5e57056bb88acbd2a901ef64bc6e4db02adc05b6250ff378de81dca18c1910ab257dff1b9771b85bb9bbe0a69f5989e6d1710a35e6dfcceb7d8fb5ccea8db3932b3d9ff3fe0d327597c68b3622aec8e3716c83a6c93f497543b459b58ba504ed6bcaa747d37d2ca746fe49ae0a6ce4a8b694234e941b5159ff8bd34b9023da2814076163b86f40eed7c9472f81b551452d5ab87004a373c0172ec87ea6ce42ccfa7dbdad66b745496c4873d8019e8c28d6b3" - -const symmetricallyEncryptedCompressedHex = "8c0d04030302eb4a03808145d0d260c92f714339e13de5a79881216431925bf67ee2898ea61815f07894cd0703c50d0a76ef64d482196f47a8bc729af9b80bb6" - -const dsaTestKeyHex = "9901a2044d6c49de110400cb5ce438cf9250907ac2ba5bf6547931270b89f7c4b53d9d09f4d0213a5ef2ec1f26806d3d259960f872a4a102ef1581ea3f6d6882d15134f21ef6a84de933cc34c47cc9106efe3bd84c6aec12e78523661e29bc1a61f0aab17fa58a627fd5fd33f5149153fbe8cd70edf3d963bc287ef875270ff14b5bfdd1bca4483793923b00a0fe46d76cb6e4cbdc568435cd5480af3266d610d303fe33ae8273f30a96d4d34f42fa28ce1112d425b2e3bf7ea553d526e2db6b9255e9dc7419045ce817214d1a0056dbc8d5289956a4b1b69f20f1105124096e6a438f41f2e2495923b0f34b70642607d45559595c7fe94d7fa85fc41bf7d68c1fd509ebeaa5f315f6059a446b9369c277597e4f474a9591535354c7e7f4fd98a08aa60400b130c24ff20bdfbf683313f5daebf1c9b34b3bdadfc77f2ddd72ee1fb17e56c473664bc21d66467655dd74b9005e3a2bacce446f1920cd7017231ae447b67036c9b431b8179deacd5120262d894c26bc015bffe3d827ba7087ad9b700d2ca1f6d16cc1786581e5dd065f293c31209300f9b0afcc3f7c08dd26d0a22d87580b4db41054657374204b65792033202844534129886204131102002205024d6c49de021b03060b090807030206150802090a0b0416020301021e01021780000a0910338934250ccc03607e0400a0bdb9193e8a6b96fc2dfc108ae848914b504481f100a09c4dc148cb693293a67af24dd40d2b13a9e36794" - -const dsaTestKeyPrivateHex = "9501bb044d6c49de110400cb5ce438cf9250907ac2ba5bf6547931270b89f7c4b53d9d09f4d0213a5ef2ec1f26806d3d259960f872a4a102ef1581ea3f6d6882d15134f21ef6a84de933cc34c47cc9106efe3bd84c6aec12e78523661e29bc1a61f0aab17fa58a627fd5fd33f5149153fbe8cd70edf3d963bc287ef875270ff14b5bfdd1bca4483793923b00a0fe46d76cb6e4cbdc568435cd5480af3266d610d303fe33ae8273f30a96d4d34f42fa28ce1112d425b2e3bf7ea553d526e2db6b9255e9dc7419045ce817214d1a0056dbc8d5289956a4b1b69f20f1105124096e6a438f41f2e2495923b0f34b70642607d45559595c7fe94d7fa85fc41bf7d68c1fd509ebeaa5f315f6059a446b9369c277597e4f474a9591535354c7e7f4fd98a08aa60400b130c24ff20bdfbf683313f5daebf1c9b34b3bdadfc77f2ddd72ee1fb17e56c473664bc21d66467655dd74b9005e3a2bacce446f1920cd7017231ae447b67036c9b431b8179deacd5120262d894c26bc015bffe3d827ba7087ad9b700d2ca1f6d16cc1786581e5dd065f293c31209300f9b0afcc3f7c08dd26d0a22d87580b4d00009f592e0619d823953577d4503061706843317e4fee083db41054657374204b65792033202844534129886204131102002205024d6c49de021b03060b090807030206150802090a0b0416020301021e01021780000a0910338934250ccc03607e0400a0bdb9193e8a6b96fc2dfc108ae848914b504481f100a09c4dc148cb693293a67af24dd40d2b13a9e36794" - -const p256TestKeyHex = "98520456e5b83813082a8648ce3d030107020304a2072cd6d21321266c758cc5b83fab0510f751cb8d91897cddb7047d8d6f185546e2107111b0a95cb8ef063c33245502af7a65f004d5919d93ee74eb71a66253b424502d3235362054657374204b6579203c696e76616c6964406578616d706c652e636f6d3e8879041313080021050256e5b838021b03050b09080702061508090a0b020416020301021e01021780000a0910d44a2c495918513e54e50100dfa64f97d9b47766fc1943c6314ba3f2b2a103d71ad286dc5b1efb96a345b0c80100dbc8150b54241f559da6ef4baacea6d31902b4f4b1bdc09b34bf0502334b7754b8560456e5b83812082a8648ce3d030107020304bfe3cea9cee13486f8d518aa487fecab451f25467d2bf08e58f63e5fa525d5482133e6a79299c274b068ef0be448152ad65cf11cf764348588ca4f6a0bcf22b6030108078861041813080009050256e5b838021b0c000a0910d44a2c495918513e4a4800ff49d589fa64024ad30be363a032e3a0e0e6f5db56ba4c73db850518bf0121b8f20100fd78e065f4c70ea5be9df319ea67e493b936fc78da834a71828043d3154af56e" - -const p256TestKeyPrivateHex = "94a50456e5b83813082a8648ce3d030107020304a2072cd6d21321266c758cc5b83fab0510f751cb8d91897cddb7047d8d6f185546e2107111b0a95cb8ef063c33245502af7a65f004d5919d93ee74eb71a66253fe070302f0c2bfb0b6c30f87ee1599472b8636477eab23ced13b271886a4b50ed34c9d8436af5af5b8f88921f0efba6ef8c37c459bbb88bc1c6a13bbd25c4ce9b1e97679569ee77645d469bf4b43de637f5561b424502d3235362054657374204b6579203c696e76616c6964406578616d706c652e636f6d3e8879041313080021050256e5b838021b03050b09080702061508090a0b020416020301021e01021780000a0910d44a2c495918513e54e50100dfa64f97d9b47766fc1943c6314ba3f2b2a103d71ad286dc5b1efb96a345b0c80100dbc8150b54241f559da6ef4baacea6d31902b4f4b1bdc09b34bf0502334b77549ca90456e5b83812082a8648ce3d030107020304bfe3cea9cee13486f8d518aa487fecab451f25467d2bf08e58f63e5fa525d5482133e6a79299c274b068ef0be448152ad65cf11cf764348588ca4f6a0bcf22b603010807fe0703027510012471a603cfee2968dce19f732721ddf03e966fd133b4e3c7a685b788705cbc46fb026dc94724b830c9edbaecd2fb2c662f23169516cacd1fe423f0475c364ecc10abcabcfd4bbbda1a36a1bd8861041813080009050256e5b838021b0c000a0910d44a2c495918513e4a4800ff49d589fa64024ad30be363a032e3a0e0e6f5db56ba4c73db850518bf0121b8f20100fd78e065f4c70ea5be9df319ea67e493b936fc78da834a71828043d3154af56e" - -const armoredPrivateKeyBlock = `-----BEGIN PGP PRIVATE KEY BLOCK----- -Version: GnuPG v1.4.10 (GNU/Linux) - -lQHYBE2rFNoBBADFwqWQIW/DSqcB4yCQqnAFTJ27qS5AnB46ccAdw3u4Greeu3Bp -idpoHdjULy7zSKlwR1EA873dO/k/e11Ml3dlAFUinWeejWaK2ugFP6JjiieSsrKn -vWNicdCS4HTWn0X4sjl0ZiAygw6GNhqEQ3cpLeL0g8E9hnYzJKQ0LWJa0QARAQAB -AAP/TB81EIo2VYNmTq0pK1ZXwUpxCrvAAIG3hwKjEzHcbQznsjNvPUihZ+NZQ6+X -0HCfPAdPkGDCLCb6NavcSW+iNnLTrdDnSI6+3BbIONqWWdRDYJhqZCkqmG6zqSfL -IdkJgCw94taUg5BWP/AAeQrhzjChvpMQTVKQL5mnuZbUCeMCAN5qrYMP2S9iKdnk -VANIFj7656ARKt/nf4CBzxcpHTyB8+d2CtPDKCmlJP6vL8t58Jmih+kHJMvC0dzn -gr5f5+sCAOOe5gt9e0am7AvQWhdbHVfJU0TQJx+m2OiCJAqGTB1nvtBLHdJnfdC9 -TnXXQ6ZXibqLyBies/xeY2sCKL5qtTMCAKnX9+9d/5yQxRyrQUHt1NYhaXZnJbHx -q4ytu0eWz+5i68IYUSK69jJ1NWPM0T6SkqpB3KCAIv68VFm9PxqG1KmhSrQIVGVz -dCBLZXmIuAQTAQIAIgUCTasU2gIbAwYLCQgHAwIGFQgCCQoLBBYCAwECHgECF4AA -CgkQO9o98PRieSoLhgQAkLEZex02Qt7vGhZzMwuN0R22w3VwyYyjBx+fM3JFETy1 -ut4xcLJoJfIaF5ZS38UplgakHG0FQ+b49i8dMij0aZmDqGxrew1m4kBfjXw9B/v+ -eIqpODryb6cOSwyQFH0lQkXC040pjq9YqDsO5w0WYNXYKDnzRV0p4H1pweo2VDid -AdgETasU2gEEAN46UPeWRqKHvA99arOxee38fBt2CI08iiWyI8T3J6ivtFGixSqV -bRcPxYO/qLpVe5l84Nb3X71GfVXlc9hyv7CD6tcowL59hg1E/DC5ydI8K8iEpUmK -/UnHdIY5h8/kqgGxkY/T/hgp5fRQgW1ZoZxLajVlMRZ8W4tFtT0DeA+JABEBAAEA -A/0bE1jaaZKj6ndqcw86jd+QtD1SF+Cf21CWRNeLKnUds4FRRvclzTyUMuWPkUeX -TaNNsUOFqBsf6QQ2oHUBBK4VCHffHCW4ZEX2cd6umz7mpHW6XzN4DECEzOVksXtc -lUC1j4UB91DC/RNQqwX1IV2QLSwssVotPMPqhOi0ZLNY7wIA3n7DWKInxYZZ4K+6 -rQ+POsz6brEoRHwr8x6XlHenq1Oki855pSa1yXIARoTrSJkBtn5oI+f8AzrnN0BN -oyeQAwIA/7E++3HDi5aweWrViiul9cd3rcsS0dEnksPhvS0ozCJiHsq/6GFmy7J8 -QSHZPteedBnZyNp5jR+H7cIfVN3KgwH/Skq4PsuPhDq5TKK6i8Pc1WW8MA6DXTdU -nLkX7RGmMwjC0DBf7KWAlPjFaONAX3a8ndnz//fy1q7u2l9AZwrj1qa1iJ8EGAEC -AAkFAk2rFNoCGwwACgkQO9o98PRieSo2/QP/WTzr4ioINVsvN1akKuekmEMI3LAp -BfHwatufxxP1U+3Si/6YIk7kuPB9Hs+pRqCXzbvPRrI8NHZBmc8qIGthishdCYad -AHcVnXjtxrULkQFGbGvhKURLvS9WnzD/m1K2zzwxzkPTzT9/Yf06O6Mal5AdugPL -VrM0m72/jnpKo04= -=zNCn ------END PGP PRIVATE KEY BLOCK-----` - -const e2ePublicKey = `-----BEGIN PGP PUBLIC KEY BLOCK----- -Charset: UTF-8 - -xv8AAABSBAAAAAATCCqGSM49AwEHAgME1LRoXSpOxtHXDUdmuvzchyg6005qIBJ4 -sfaSxX7QgH9RV2ONUhC+WiayCNADq+UMzuR/vunSr4aQffXvuGnR383/AAAAFDxk -Z2lsQHlhaG9vLWluYy5jb20+wv8AAACGBBATCAA4/wAAAAWCVGvAG/8AAAACiwn/ -AAAACZC2VkQCOjdvYf8AAAAFlQgJCgv/AAAAA5YBAv8AAAACngEAAE1BAP0X8veD -24IjmI5/C6ZAfVNXxgZZFhTAACFX75jUA3oD6AEAzoSwKf1aqH6oq62qhCN/pekX -+WAsVMBhNwzLpqtCRjLO/wAAAFYEAAAAABIIKoZIzj0DAQcCAwT50ain7vXiIRv8 -B1DO3x3cE/aattZ5sHNixJzRCXi2vQIA5QmOxZ6b5jjUekNbdHG3SZi1a2Ak5mfX -fRxC/5VGAwEIB8L/AAAAZQQYEwgAGP8AAAAFglRrwBz/AAAACZC2VkQCOjdvYQAA -FJAA9isX3xtGyMLYwp2F3nXm7QEdY5bq5VUcD/RJlj792VwA/1wH0pCzVLl4Q9F9 -ex7En5r7rHR5xwX82Msc+Rq9dSyO -=7MrZ ------END PGP PUBLIC KEY BLOCK-----` - -const dsaKeyWithSHA512 = `9901a2044f04b07f110400db244efecc7316553ee08d179972aab87bb1214de7692593fcf5b6feb1c80fba268722dd464748539b85b81d574cd2d7ad0ca2444de4d849b8756bad7768c486c83a824f9bba4af773d11742bdfb4ac3b89ef8cc9452d4aad31a37e4b630d33927bff68e879284a1672659b8b298222fc68f370f3e24dccacc4a862442b9438b00a0ea444a24088dc23e26df7daf8f43cba3bffc4fe703fe3d6cd7fdca199d54ed8ae501c30e3ec7871ea9cdd4cf63cfe6fc82281d70a5b8bb493f922cd99fba5f088935596af087c8d818d5ec4d0b9afa7f070b3d7c1dd32a84fca08d8280b4890c8da1dde334de8e3cad8450eed2a4a4fcc2db7b8e5528b869a74a7f0189e11ef097ef1253582348de072bb07a9fa8ab838e993cef0ee203ff49298723e2d1f549b00559f886cd417a41692ce58d0ac1307dc71d85a8af21b0cf6eaa14baf2922d3a70389bedf17cc514ba0febbd107675a372fe84b90162a9e88b14d4b1c6be855b96b33fb198c46f058568817780435b6936167ebb3724b680f32bf27382ada2e37a879b3d9de2abe0c3f399350afd1ad438883f4791e2e3b4184453412068617368207472756e636174696f6e207465737488620413110a002205024f04b07f021b03060b090807030206150802090a0b0416020301021e01021780000a0910ef20e0cefca131581318009e2bf3bf047a44d75a9bacd00161ee04d435522397009a03a60d51bd8a568c6c021c8d7cf1be8d990d6417b0020003` - -const unknownHashFunctionHex = `8a00000040040001990006050253863c24000a09103b4fe6acc0b21f32ffff01010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101` - -const missingHashFunctionHex = `8a00000040040001030006050253863c24000a09103b4fe6acc0b21f32ffff0101010101010101010101010101010101010101010101010101010101010101010101010101` - -const campbellQuine = `a0b001000300fcffa0b001000d00f2ff000300fcffa0b001000d00f2ff8270a01c00000500faff8270a01c00000500faff000500faff001400ebff8270a01c00000500faff000500faff001400ebff428821c400001400ebff428821c400001400ebff428821c400001400ebff428821c400001400ebff428821c400000000ffff000000ffff000b00f4ff428821c400000000ffff000000ffff000b00f4ff0233214c40000100feff000233214c40000100feff0000` - -const keyV4forVerifyingSignedMessageV3 = `-----BEGIN PGP PUBLIC KEY BLOCK----- -Comment: GPGTools - https://gpgtools.org - -mI0EVfxoFQEEAMBIqmbDfYygcvP6Phr1wr1XI41IF7Qixqybs/foBF8qqblD9gIY -BKpXjnBOtbkcVOJ0nljd3/sQIfH4E0vQwK5/4YRQSI59eKOqd6Fx+fWQOLG+uu6z -tewpeCj9LLHvibx/Sc7VWRnrznia6ftrXxJ/wHMezSab3tnGC0YPVdGNABEBAAG0 -JEdvY3J5cHRvIFRlc3QgS2V5IDx0aGVtYXhAZ21haWwuY29tPoi5BBMBCgAjBQJV -/GgVAhsDBwsJCAcDAgEGFQgCCQoLBBYCAwECHgECF4AACgkQeXnQmhdGW9PFVAP+ -K7TU0qX5ArvIONIxh/WAweyOk884c5cE8f+3NOPOOCRGyVy0FId5A7MmD5GOQh4H -JseOZVEVCqlmngEvtHZb3U1VYtVGE5WZ+6rQhGsMcWP5qaT4soYwMBlSYxgYwQcx -YhN9qOr292f9j2Y//TTIJmZT4Oa+lMxhWdqTfX+qMgG4jQRV/GgVAQQArhFSiij1 -b+hT3dnapbEU+23Z1yTu1DfF6zsxQ4XQWEV3eR8v+8mEDDNcz8oyyF56k6UQ3rXi -UMTIwRDg4V6SbZmaFbZYCOwp/EmXJ3rfhm7z7yzXj2OFN22luuqbyVhuL7LRdB0M -pxgmjXb4tTvfgKd26x34S+QqUJ7W6uprY4sAEQEAAYifBBgBCgAJBQJV/GgVAhsM -AAoJEHl50JoXRlvT7y8D/02ckx4OMkKBZo7viyrBw0MLG92i+DC2bs35PooHR6zz -786mitjOp5z2QWNLBvxC70S0qVfCIz8jKupO1J6rq6Z8CcbLF3qjm6h1omUBf8Nd -EfXKD2/2HV6zMKVknnKzIEzauh+eCKS2CeJUSSSryap/QLVAjRnckaES/OsEWhNB -=RZia ------END PGP PUBLIC KEY BLOCK----- -` - -const signedMessageV3 = `-----BEGIN PGP MESSAGE----- -Comment: GPGTools - https://gpgtools.org - -owGbwMvMwMVYWXlhlrhb9GXG03JJDKF/MtxDMjKLFYAoUaEktbhEITe1uDgxPVWP -q5NhKjMrWAVcC9evD8z/bF/uWNjqtk/X3y5/38XGRQHm/57rrDRYuGnTw597Xqka -uM3137/hH3Os+Jf2dc0fXOITKwJvXJvecPVs0ta+Vg7ZO1MLn8w58Xx+6L58mbka -DGHyU9yTueZE8D+QF/Tz28Y78dqtF56R1VPn9Xw4uJqrWYdd7b3vIZ1V6R4Nh05d -iT57d/OhWwA= -=hG7R ------END PGP MESSAGE----- -` diff --git a/vendor/golang.org/x/crypto/openpgp/s2k/s2k.go b/vendor/golang.org/x/crypto/openpgp/s2k/s2k.go deleted file mode 100644 index 4b9a44c..0000000 --- a/vendor/golang.org/x/crypto/openpgp/s2k/s2k.go +++ /dev/null @@ -1,273 +0,0 @@ -// 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. -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/s2k/s2k_test.go b/vendor/golang.org/x/crypto/openpgp/s2k/s2k_test.go deleted file mode 100644 index 183d260..0000000 --- a/vendor/golang.org/x/crypto/openpgp/s2k/s2k_test.go +++ /dev/null @@ -1,137 +0,0 @@ -// 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 - -import ( - "bytes" - "crypto" - _ "crypto/md5" - "crypto/rand" - "crypto/sha1" - _ "crypto/sha256" - _ "crypto/sha512" - "encoding/hex" - "testing" - - _ "golang.org/x/crypto/ripemd160" -) - -var saltedTests = []struct { - in, out string -}{ - {"hello", "10295ac1"}, - {"world", "ac587a5e"}, - {"foo", "4dda8077"}, - {"bar", "bd8aac6b9ea9cae04eae6a91c6133b58b5d9a61c14f355516ed9370456"}, - {"x", "f1d3f289"}, - {"xxxxxxxxxxxxxxxxxxxxxxx", "e00d7b45"}, -} - -func TestSalted(t *testing.T) { - h := sha1.New() - salt := [4]byte{1, 2, 3, 4} - - for i, test := range saltedTests { - expected, _ := hex.DecodeString(test.out) - out := make([]byte, len(expected)) - Salted(out, h, []byte(test.in), salt[:]) - if !bytes.Equal(expected, out) { - t.Errorf("#%d, got: %x want: %x", i, out, expected) - } - } -} - -var iteratedTests = []struct { - in, out string -}{ - {"hello", "83126105"}, - {"world", "6fa317f9"}, - {"foo", "8fbc35b9"}, - {"bar", "2af5a99b54f093789fd657f19bd245af7604d0f6ae06f66602a46a08ae"}, - {"x", "5a684dfe"}, - {"xxxxxxxxxxxxxxxxxxxxxxx", "18955174"}, -} - -func TestIterated(t *testing.T) { - h := sha1.New() - salt := [4]byte{4, 3, 2, 1} - - for i, test := range iteratedTests { - expected, _ := hex.DecodeString(test.out) - out := make([]byte, len(expected)) - Iterated(out, h, []byte(test.in), salt[:], 31) - if !bytes.Equal(expected, out) { - t.Errorf("#%d, got: %x want: %x", i, out, expected) - } - } -} - -var parseTests = []struct { - spec, in, out string -}{ - /* Simple with SHA1 */ - {"0002", "hello", "aaf4c61d"}, - /* Salted with SHA1 */ - {"01020102030405060708", "hello", "f4f7d67e"}, - /* Iterated with SHA1 */ - {"03020102030405060708f1", "hello", "f2a57b7c"}, -} - -func TestParse(t *testing.T) { - for i, test := range parseTests { - spec, _ := hex.DecodeString(test.spec) - buf := bytes.NewBuffer(spec) - f, err := Parse(buf) - if err != nil { - t.Errorf("%d: Parse returned error: %s", i, err) - continue - } - - expected, _ := hex.DecodeString(test.out) - out := make([]byte, len(expected)) - f(out, []byte(test.in)) - if !bytes.Equal(out, expected) { - t.Errorf("%d: output got: %x want: %x", i, out, expected) - } - if testing.Short() { - break - } - } -} - -func TestSerialize(t *testing.T) { - hashes := []crypto.Hash{crypto.MD5, crypto.SHA1, crypto.RIPEMD160, - crypto.SHA256, crypto.SHA384, crypto.SHA512, crypto.SHA224} - testCounts := []int{-1, 0, 1024, 65536, 4063232, 65011712} - for _, h := range hashes { - for _, c := range testCounts { - testSerializeConfig(t, &Config{Hash: h, S2KCount: c}) - } - } -} - -func testSerializeConfig(t *testing.T, c *Config) { - t.Logf("Running testSerializeConfig() with config: %+v", c) - - buf := bytes.NewBuffer(nil) - key := make([]byte, 16) - passphrase := []byte("testing") - err := Serialize(buf, key, rand.Reader, passphrase, c) - if err != nil { - t.Errorf("failed to serialize: %s", err) - return - } - - f, err := Parse(buf) - if err != nil { - t.Errorf("failed to reparse: %s", err) - return - } - key2 := make([]byte, len(key)) - f(key2, passphrase) - if !bytes.Equal(key2, key) { - t.Errorf("keys don't match: %x (serialied) vs %x (parsed)", key, key2) - } -} diff --git a/vendor/golang.org/x/crypto/openpgp/write.go b/vendor/golang.org/x/crypto/openpgp/write.go deleted file mode 100644 index 15aaa1a..0000000 --- a/vendor/golang.org/x/crypto/openpgp/write.go +++ /dev/null @@ -1,378 +0,0 @@ -// 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 -} - -// 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) { - 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") - } - } - - // 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.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 specifed 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 - } - } - - 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.)") - } - - 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 - } - } - - encryptedData, err := packet.SerializeSymmetricallyEncrypted(ciphertext, cipher, symKey, config) - if err != nil { - return - } - - if signer != nil { - ops := &packet.OnePassSignature{ - SigType: packet.SigTypeBinary, - Hash: hash, - PubKeyAlgo: signer.PubKeyAlgo, - KeyId: signer.KeyId, - IsLast: true, - } - if err := ops.Serialize(encryptedData); err != nil { - return nil, err - } - } - - if hints == nil { - hints = &FileHints{} - } - - w := encryptedData - 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{encryptedData} - - } - 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{encryptedData, literalData, hash, hash.New(), signer, config}, nil - } - return literalData, nil -} - -// 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/openpgp/write_test.go b/vendor/golang.org/x/crypto/openpgp/write_test.go deleted file mode 100644 index 2161ebc..0000000 --- a/vendor/golang.org/x/crypto/openpgp/write_test.go +++ /dev/null @@ -1,273 +0,0 @@ -// 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 ( - "bytes" - "io" - "io/ioutil" - "testing" - "time" - - "golang.org/x/crypto/openpgp/packet" -) - -func TestSignDetached(t *testing.T) { - kring, _ := ReadKeyRing(readerFromHex(testKeys1And2PrivateHex)) - out := bytes.NewBuffer(nil) - message := bytes.NewBufferString(signedInput) - err := DetachSign(out, kring[0], message, nil) - if err != nil { - t.Error(err) - } - - testDetachedSignature(t, kring, out, signedInput, "check", testKey1KeyId) -} - -func TestSignTextDetached(t *testing.T) { - kring, _ := ReadKeyRing(readerFromHex(testKeys1And2PrivateHex)) - out := bytes.NewBuffer(nil) - message := bytes.NewBufferString(signedInput) - err := DetachSignText(out, kring[0], message, nil) - if err != nil { - t.Error(err) - } - - testDetachedSignature(t, kring, out, signedInput, "check", testKey1KeyId) -} - -func TestSignDetachedDSA(t *testing.T) { - kring, _ := ReadKeyRing(readerFromHex(dsaTestKeyPrivateHex)) - out := bytes.NewBuffer(nil) - message := bytes.NewBufferString(signedInput) - err := DetachSign(out, kring[0], message, nil) - if err != nil { - t.Error(err) - } - - testDetachedSignature(t, kring, out, signedInput, "check", testKey3KeyId) -} - -func TestSignDetachedP256(t *testing.T) { - kring, _ := ReadKeyRing(readerFromHex(p256TestKeyPrivateHex)) - kring[0].PrivateKey.Decrypt([]byte("passphrase")) - - out := bytes.NewBuffer(nil) - message := bytes.NewBufferString(signedInput) - err := DetachSign(out, kring[0], message, nil) - if err != nil { - t.Error(err) - } - - testDetachedSignature(t, kring, out, signedInput, "check", testKeyP256KeyId) -} - -func TestNewEntity(t *testing.T) { - if testing.Short() { - return - } - - // Check bit-length with no config. - e, err := NewEntity("Test User", "test", "test@example.com", nil) - if err != nil { - t.Errorf("failed to create entity: %s", err) - return - } - bl, err := e.PrimaryKey.BitLength() - if err != nil { - t.Errorf("failed to find bit length: %s", err) - } - if int(bl) != defaultRSAKeyBits { - t.Errorf("BitLength %v, expected %v", defaultRSAKeyBits) - } - - // Check bit-length with a config. - cfg := &packet.Config{RSABits: 1024} - e, err = NewEntity("Test User", "test", "test@example.com", cfg) - if err != nil { - t.Errorf("failed to create entity: %s", err) - return - } - bl, err = e.PrimaryKey.BitLength() - if err != nil { - t.Errorf("failed to find bit length: %s", err) - } - if int(bl) != cfg.RSABits { - t.Errorf("BitLength %v, expected %v", bl, cfg.RSABits) - } - - w := bytes.NewBuffer(nil) - if err := e.SerializePrivate(w, nil); err != nil { - t.Errorf("failed to serialize entity: %s", err) - return - } - serialized := w.Bytes() - - el, err := ReadKeyRing(w) - if err != nil { - t.Errorf("failed to reparse entity: %s", err) - return - } - - if len(el) != 1 { - t.Errorf("wrong number of entities found, got %d, want 1", len(el)) - } - - w = bytes.NewBuffer(nil) - if err := e.SerializePrivate(w, nil); err != nil { - t.Errorf("failed to serialize entity second time: %s", err) - return - } - - if !bytes.Equal(w.Bytes(), serialized) { - t.Errorf("results differed") - } -} - -func TestSymmetricEncryption(t *testing.T) { - buf := new(bytes.Buffer) - plaintext, err := SymmetricallyEncrypt(buf, []byte("testing"), nil, nil) - if err != nil { - t.Errorf("error writing headers: %s", err) - return - } - message := []byte("hello world\n") - _, err = plaintext.Write(message) - if err != nil { - t.Errorf("error writing to plaintext writer: %s", err) - } - err = plaintext.Close() - if err != nil { - t.Errorf("error closing plaintext writer: %s", err) - } - - md, err := ReadMessage(buf, nil, func(keys []Key, symmetric bool) ([]byte, error) { - return []byte("testing"), nil - }, nil) - if err != nil { - t.Errorf("error rereading message: %s", err) - } - messageBuf := bytes.NewBuffer(nil) - _, err = io.Copy(messageBuf, md.UnverifiedBody) - if err != nil { - t.Errorf("error rereading message: %s", err) - } - if !bytes.Equal(message, messageBuf.Bytes()) { - t.Errorf("recovered message incorrect got '%s', want '%s'", messageBuf.Bytes(), message) - } -} - -var testEncryptionTests = []struct { - keyRingHex string - isSigned bool -}{ - { - testKeys1And2PrivateHex, - false, - }, - { - testKeys1And2PrivateHex, - true, - }, - { - dsaElGamalTestKeysHex, - false, - }, - { - dsaElGamalTestKeysHex, - true, - }, -} - -func TestEncryption(t *testing.T) { - for i, test := range testEncryptionTests { - kring, _ := ReadKeyRing(readerFromHex(test.keyRingHex)) - - passphrase := []byte("passphrase") - for _, entity := range kring { - if entity.PrivateKey != nil && entity.PrivateKey.Encrypted { - err := entity.PrivateKey.Decrypt(passphrase) - if err != nil { - t.Errorf("#%d: failed to decrypt key", i) - } - } - for _, subkey := range entity.Subkeys { - if subkey.PrivateKey != nil && subkey.PrivateKey.Encrypted { - err := subkey.PrivateKey.Decrypt(passphrase) - if err != nil { - t.Errorf("#%d: failed to decrypt subkey", i) - } - } - } - } - - var signed *Entity - if test.isSigned { - signed = kring[0] - } - - buf := new(bytes.Buffer) - w, err := Encrypt(buf, kring[:1], signed, nil /* no hints */, nil) - if err != nil { - t.Errorf("#%d: error in Encrypt: %s", i, err) - continue - } - - const message = "testing" - _, err = w.Write([]byte(message)) - if err != nil { - t.Errorf("#%d: error writing plaintext: %s", i, err) - continue - } - err = w.Close() - if err != nil { - t.Errorf("#%d: error closing WriteCloser: %s", i, err) - continue - } - - md, err := ReadMessage(buf, kring, nil /* no prompt */, nil) - if err != nil { - t.Errorf("#%d: error reading message: %s", i, err) - continue - } - - testTime, _ := time.Parse("2006-01-02", "2013-07-01") - if test.isSigned { - signKey, _ := kring[0].signingKey(testTime) - expectedKeyId := signKey.PublicKey.KeyId - if md.SignedByKeyId != expectedKeyId { - t.Errorf("#%d: message signed by wrong key id, got: %d, want: %d", i, *md.SignedBy, expectedKeyId) - } - if md.SignedBy == nil { - t.Errorf("#%d: failed to find the signing Entity", i) - } - } - - plaintext, err := ioutil.ReadAll(md.UnverifiedBody) - if err != nil { - t.Errorf("#%d: error reading encrypted contents: %s", i, err) - continue - } - - encryptKey, _ := kring[0].encryptionKey(testTime) - expectedKeyId := encryptKey.PublicKey.KeyId - if len(md.EncryptedToKeyIds) != 1 || md.EncryptedToKeyIds[0] != expectedKeyId { - t.Errorf("#%d: expected message to be encrypted to %v, but got %#v", i, expectedKeyId, md.EncryptedToKeyIds) - } - - if string(plaintext) != message { - t.Errorf("#%d: got: %s, want: %s", i, string(plaintext), message) - } - - if test.isSigned { - if md.SignatureError != nil { - t.Errorf("#%d: signature error: %s", i, md.SignatureError) - } - if md.Signature == nil { - t.Error("signature missing") - } - } - } -} diff --git a/vendor/golang.org/x/crypto/otr/libotr_test_helper.c b/vendor/golang.org/x/crypto/otr/libotr_test_helper.c deleted file mode 100644 index b3ca072..0000000 --- a/vendor/golang.org/x/crypto/otr/libotr_test_helper.c +++ /dev/null @@ -1,197 +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 can be compiled and used to test the otr package against libotr. -// See otr_test.go. - -// +build ignore - -#include -#include -#include - -#include -#include -#include - -static int g_session_established = 0; - -OtrlPolicy policy(void *opdata, ConnContext *context) { - return OTRL_POLICY_ALWAYS; -} - -int is_logged_in(void *opdata, const char *accountname, const char *protocol, - const char *recipient) { - return 1; -} - -void inject_message(void *opdata, const char *accountname, const char *protocol, - const char *recipient, const char *message) { - printf("%s\n", message); - fflush(stdout); - fprintf(stderr, "libotr helper sent: %s\n", message); -} - -void update_context_list(void *opdata) {} - -void new_fingerprint(void *opdata, OtrlUserState us, const char *accountname, - const char *protocol, const char *username, - unsigned char fingerprint[20]) { - fprintf(stderr, "NEW FINGERPRINT\n"); - g_session_established = 1; -} - -void write_fingerprints(void *opdata) {} - -void gone_secure(void *opdata, ConnContext *context) {} - -void gone_insecure(void *opdata, ConnContext *context) {} - -void still_secure(void *opdata, ConnContext *context, int is_reply) {} - -int max_message_size(void *opdata, ConnContext *context) { return 99999; } - -const char *account_name(void *opdata, const char *account, - const char *protocol) { - return "ACCOUNT"; -} - -void account_name_free(void *opdata, const char *account_name) {} - -const char *error_message(void *opdata, ConnContext *context, - OtrlErrorCode err_code) { - return "ERR"; -} - -void error_message_free(void *opdata, const char *msg) {} - -void resent_msg_prefix_free(void *opdata, const char *prefix) {} - -void handle_smp_event(void *opdata, OtrlSMPEvent smp_event, - ConnContext *context, unsigned short progress_event, - char *question) {} - -void handle_msg_event(void *opdata, OtrlMessageEvent msg_event, - ConnContext *context, const char *message, - gcry_error_t err) { - fprintf(stderr, "msg event: %d %s\n", msg_event, message); -} - -OtrlMessageAppOps uiops = { - policy, - NULL, - is_logged_in, - inject_message, - update_context_list, - new_fingerprint, - write_fingerprints, - gone_secure, - gone_insecure, - still_secure, - max_message_size, - account_name, - account_name_free, - NULL, /* received_symkey */ - error_message, - error_message_free, - NULL, /* resent_msg_prefix */ - resent_msg_prefix_free, - handle_smp_event, - handle_msg_event, - NULL /* create_instag */, - NULL /* convert_msg */, - NULL /* convert_free */, - NULL /* timer_control */, -}; - -static const char kPrivateKeyData[] = - "(privkeys (account (name \"account\") (protocol proto) (private-key (dsa " - "(p " - "#00FC07ABCF0DC916AFF6E9AE47BEF60C7AB9B4D6B2469E436630E36F8A489BE812486A09F" - "30B71224508654940A835301ACC525A4FF133FC152CC53DCC59D65C30A54F1993FE13FE63E" - "5823D4C746DB21B90F9B9C00B49EC7404AB1D929BA7FBA12F2E45C6E0A651689750E8528AB" - "8C031D3561FECEE72EBB4A090D450A9B7A857#) (q " - "#00997BD266EF7B1F60A5C23F3A741F2AEFD07A2081#) (g " - "#535E360E8A95EBA46A4F7DE50AD6E9B2A6DB785A66B64EB9F20338D2A3E8FB0E94725848F" - "1AA6CC567CB83A1CC517EC806F2E92EAE71457E80B2210A189B91250779434B41FC8A8873F" - "6DB94BEA7D177F5D59E7E114EE10A49CFD9CEF88AE43387023B672927BA74B04EB6BBB5E57" - "597766A2F9CE3857D7ACE3E1E3BC1FC6F26#) (y " - "#0AC8670AD767D7A8D9D14CC1AC6744CD7D76F993B77FFD9E39DF01E5A6536EF65E775FCEF" - "2A983E2A19BD6415500F6979715D9FD1257E1FE2B6F5E1E74B333079E7C880D39868462A93" - "454B41877BE62E5EF0A041C2EE9C9E76BD1E12AE25D9628DECB097025DD625EF49C3258A1A" - "3C0FF501E3DC673B76D7BABF349009B6ECF#) (x " - "#14D0345A3562C480A039E3C72764F72D79043216#)))))\n"; - -int main() { - OTRL_INIT; - - // We have to write the private key information to a file because the libotr - // API demands a filename to read from. - const char *tmpdir = "/tmp"; - if (getenv("TMP")) { - tmpdir = getenv("TMP"); - } - - char private_key_file[256]; - snprintf(private_key_file, sizeof(private_key_file), - "%s/libotr_test_helper_privatekeys-XXXXXX", tmpdir); - int fd = mkstemp(private_key_file); - if (fd == -1) { - perror("creating temp file"); - } - write(fd, kPrivateKeyData, sizeof(kPrivateKeyData) - 1); - close(fd); - - OtrlUserState userstate = otrl_userstate_create(); - otrl_privkey_read(userstate, private_key_file); - unlink(private_key_file); - - fprintf(stderr, "libotr helper started\n"); - - char buf[4096]; - - for (;;) { - char *message = fgets(buf, sizeof(buf), stdin); - if (strlen(message) == 0) { - break; - } - message[strlen(message) - 1] = 0; - fprintf(stderr, "libotr helper got: %s\n", message); - - char *newmessage = NULL; - OtrlTLV *tlvs; - int ignore_message = otrl_message_receiving( - userstate, &uiops, NULL, "account", "proto", "peer", message, - &newmessage, &tlvs, NULL, NULL, NULL); - if (tlvs) { - otrl_tlv_free(tlvs); - } - - if (newmessage != NULL) { - fprintf(stderr, "libotr got: %s\n", newmessage); - otrl_message_free(newmessage); - - gcry_error_t err; - char *newmessage = NULL; - - err = otrl_message_sending(userstate, &uiops, NULL, "account", "proto", - "peer", 0, "test message", NULL, &newmessage, - OTRL_FRAGMENT_SEND_SKIP, NULL, NULL, NULL); - if (newmessage == NULL) { - fprintf(stderr, "libotr didn't encrypt message\n"); - return 1; - } - write(1, newmessage, strlen(newmessage)); - write(1, "\n", 1); - fprintf(stderr, "libotr sent: %s\n", newmessage); - otrl_message_free(newmessage); - - g_session_established = 0; - write(1, "?OTRv2?\n", 8); - fprintf(stderr, "libotr sent: ?OTRv2\n"); - } - } - - return 0; -} diff --git a/vendor/golang.org/x/crypto/otr/otr.go b/vendor/golang.org/x/crypto/otr/otr.go deleted file mode 100644 index 549be11..0000000 --- a/vendor/golang.org/x/crypto/otr/otr.go +++ /dev/null @@ -1,1408 +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. - -// Package otr implements the Off The Record protocol as specified in -// http://www.cypherpunks.ca/otr/Protocol-v2-3.1.0.html -package otr // import "golang.org/x/crypto/otr" - -import ( - "bytes" - "crypto/aes" - "crypto/cipher" - "crypto/dsa" - "crypto/hmac" - "crypto/rand" - "crypto/sha1" - "crypto/sha256" - "crypto/subtle" - "encoding/base64" - "encoding/hex" - "errors" - "hash" - "io" - "math/big" - "strconv" -) - -// SecurityChange describes a change in the security state of a Conversation. -type SecurityChange int - -const ( - NoChange SecurityChange = iota - // NewKeys indicates that a key exchange has completed. This occurs - // when a conversation first becomes encrypted, and when the keys are - // renegotiated within an encrypted conversation. - NewKeys - // SMPSecretNeeded indicates that the peer has started an - // authentication and that we need to supply a secret. Call SMPQuestion - // to get the optional, human readable challenge and then Authenticate - // to supply the matching secret. - SMPSecretNeeded - // SMPComplete indicates that an authentication completed. The identity - // of the peer has now been confirmed. - SMPComplete - // SMPFailed indicates that an authentication failed. - SMPFailed - // ConversationEnded indicates that the peer ended the secure - // conversation. - ConversationEnded -) - -// QueryMessage can be sent to a peer to start an OTR conversation. -var QueryMessage = "?OTRv2?" - -// ErrorPrefix can be used to make an OTR error by appending an error message -// to it. -var ErrorPrefix = "?OTR Error:" - -var ( - fragmentPartSeparator = []byte(",") - fragmentPrefix = []byte("?OTR,") - msgPrefix = []byte("?OTR:") - queryMarker = []byte("?OTR") -) - -// isQuery attempts to parse an OTR query from msg and returns the greatest -// common version, or 0 if msg is not an OTR query. -func isQuery(msg []byte) (greatestCommonVersion int) { - pos := bytes.Index(msg, queryMarker) - if pos == -1 { - return 0 - } - for i, c := range msg[pos+len(queryMarker):] { - if i == 0 { - if c == '?' { - // Indicates support for version 1, but we don't - // implement that. - continue - } - - if c != 'v' { - // Invalid message - return 0 - } - - continue - } - - if c == '?' { - // End of message - return - } - - if c == ' ' || c == '\t' { - // Probably an invalid message - return 0 - } - - if c == '2' { - greatestCommonVersion = 2 - } - } - - return 0 -} - -const ( - statePlaintext = iota - stateEncrypted - stateFinished -) - -const ( - authStateNone = iota - authStateAwaitingDHKey - authStateAwaitingRevealSig - authStateAwaitingSig -) - -const ( - msgTypeDHCommit = 2 - msgTypeData = 3 - msgTypeDHKey = 10 - msgTypeRevealSig = 17 - msgTypeSig = 18 -) - -const ( - // If the requested fragment size is less than this, it will be ignored. - minFragmentSize = 18 - // Messages are padded to a multiple of this number of bytes. - paddingGranularity = 256 - // The number of bytes in a Diffie-Hellman private value (320-bits). - dhPrivateBytes = 40 - // The number of bytes needed to represent an element of the DSA - // subgroup (160-bits). - dsaSubgroupBytes = 20 - // The number of bytes of the MAC that are sent on the wire (160-bits). - macPrefixBytes = 20 -) - -// These are the global, common group parameters for OTR. -var ( - p *big.Int // group prime - g *big.Int // group generator - q *big.Int // group order - pMinus2 *big.Int -) - -func init() { - p, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF", 16) - q, _ = new(big.Int).SetString("7FFFFFFFFFFFFFFFE487ED5110B4611A62633145C06E0E68948127044533E63A0105DF531D89CD9128A5043CC71A026EF7CA8CD9E69D218D98158536F92F8A1BA7F09AB6B6A8E122F242DABB312F3F637A262174D31BF6B585FFAE5B7A035BF6F71C35FDAD44CFD2D74F9208BE258FF324943328F6722D9EE1003E5C50B1DF82CC6D241B0E2AE9CD348B1FD47E9267AFC1B2AE91EE51D6CB0E3179AB1042A95DCF6A9483B84B4B36B3861AA7255E4C0278BA36046511B993FFFFFFFFFFFFFFFF", 16) - g = new(big.Int).SetInt64(2) - pMinus2 = new(big.Int).Sub(p, g) -} - -// Conversation represents a relation with a peer. The zero value is a valid -// Conversation, although PrivateKey must be set. -// -// When communicating with a peer, all inbound messages should be passed to -// Conversation.Receive and all outbound messages to Conversation.Send. The -// Conversation will take care of maintaining the encryption state and -// negotiating encryption as needed. -type Conversation struct { - // PrivateKey contains the private key to use to sign key exchanges. - PrivateKey *PrivateKey - - // Rand can be set to override the entropy source. Otherwise, - // crypto/rand will be used. - Rand io.Reader - // If FragmentSize is set, all messages produced by Receive and Send - // will be fragmented into messages of, at most, this number of bytes. - FragmentSize int - - // Once Receive has returned NewKeys once, the following fields are - // valid. - SSID [8]byte - TheirPublicKey PublicKey - - state, authState int - - r [16]byte - x, y *big.Int - gx, gy *big.Int - gxBytes []byte - digest [sha256.Size]byte - - revealKeys, sigKeys akeKeys - - myKeyId uint32 - myCurrentDHPub *big.Int - myCurrentDHPriv *big.Int - myLastDHPub *big.Int - myLastDHPriv *big.Int - - theirKeyId uint32 - theirCurrentDHPub *big.Int - theirLastDHPub *big.Int - - keySlots [4]keySlot - - myCounter [8]byte - theirLastCtr [8]byte - oldMACs []byte - - k, n int // fragment state - frag []byte - - smp smpState -} - -// A keySlot contains key material for a specific (their keyid, my keyid) pair. -type keySlot struct { - // used is true if this slot is valid. If false, it's free for reuse. - used bool - theirKeyId uint32 - myKeyId uint32 - sendAESKey, recvAESKey []byte - sendMACKey, recvMACKey []byte - theirLastCtr [8]byte -} - -// akeKeys are generated during key exchange. There's one set for the reveal -// signature message and another for the signature message. In the protocol -// spec the latter are indicated with a prime mark. -type akeKeys struct { - c [16]byte - m1, m2 [32]byte -} - -func (c *Conversation) rand() io.Reader { - if c.Rand != nil { - return c.Rand - } - return rand.Reader -} - -func (c *Conversation) randMPI(buf []byte) *big.Int { - _, err := io.ReadFull(c.rand(), buf) - if err != nil { - panic("otr: short read from random source") - } - - return new(big.Int).SetBytes(buf) -} - -// tlv represents the type-length value from the protocol. -type tlv struct { - typ, length uint16 - data []byte -} - -const ( - tlvTypePadding = 0 - tlvTypeDisconnected = 1 - tlvTypeSMP1 = 2 - tlvTypeSMP2 = 3 - tlvTypeSMP3 = 4 - tlvTypeSMP4 = 5 - tlvTypeSMPAbort = 6 - tlvTypeSMP1WithQuestion = 7 -) - -// Receive handles a message from a peer. It returns a human readable message, -// an indicator of whether that message was encrypted, a hint about the -// encryption state and zero or more messages to send back to the peer. -// These messages do not need to be passed to Send before transmission. -func (c *Conversation) Receive(in []byte) (out []byte, encrypted bool, change SecurityChange, toSend [][]byte, err error) { - if bytes.HasPrefix(in, fragmentPrefix) { - in, err = c.processFragment(in) - if in == nil || err != nil { - return - } - } - - if bytes.HasPrefix(in, msgPrefix) && in[len(in)-1] == '.' { - in = in[len(msgPrefix) : len(in)-1] - } else if version := isQuery(in); version > 0 { - c.authState = authStateAwaitingDHKey - c.reset() - toSend = c.encode(c.generateDHCommit()) - return - } else { - // plaintext message - out = in - return - } - - msg := make([]byte, base64.StdEncoding.DecodedLen(len(in))) - msgLen, err := base64.StdEncoding.Decode(msg, in) - if err != nil { - err = errors.New("otr: invalid base64 encoding in message") - return - } - msg = msg[:msgLen] - - // The first two bytes are the protocol version (2) - if len(msg) < 3 || msg[0] != 0 || msg[1] != 2 { - err = errors.New("otr: invalid OTR message") - return - } - - msgType := int(msg[2]) - msg = msg[3:] - - switch msgType { - case msgTypeDHCommit: - switch c.authState { - case authStateNone: - c.authState = authStateAwaitingRevealSig - if err = c.processDHCommit(msg); err != nil { - return - } - c.reset() - toSend = c.encode(c.generateDHKey()) - return - case authStateAwaitingDHKey: - // This is a 'SYN-crossing'. The greater digest wins. - var cmp int - if cmp, err = c.compareToDHCommit(msg); err != nil { - return - } - if cmp > 0 { - // We win. Retransmit DH commit. - toSend = c.encode(c.serializeDHCommit()) - return - } else { - // They win. We forget about our DH commit. - c.authState = authStateAwaitingRevealSig - if err = c.processDHCommit(msg); err != nil { - return - } - c.reset() - toSend = c.encode(c.generateDHKey()) - return - } - case authStateAwaitingRevealSig: - if err = c.processDHCommit(msg); err != nil { - return - } - toSend = c.encode(c.serializeDHKey()) - case authStateAwaitingSig: - if err = c.processDHCommit(msg); err != nil { - return - } - c.reset() - toSend = c.encode(c.generateDHKey()) - c.authState = authStateAwaitingRevealSig - default: - panic("bad state") - } - case msgTypeDHKey: - switch c.authState { - case authStateAwaitingDHKey: - var isSame bool - if isSame, err = c.processDHKey(msg); err != nil { - return - } - if isSame { - err = errors.New("otr: unexpected duplicate DH key") - return - } - toSend = c.encode(c.generateRevealSig()) - c.authState = authStateAwaitingSig - case authStateAwaitingSig: - var isSame bool - if isSame, err = c.processDHKey(msg); err != nil { - return - } - if isSame { - toSend = c.encode(c.serializeDHKey()) - } - } - case msgTypeRevealSig: - if c.authState != authStateAwaitingRevealSig { - return - } - if err = c.processRevealSig(msg); err != nil { - return - } - toSend = c.encode(c.generateSig()) - c.authState = authStateNone - c.state = stateEncrypted - change = NewKeys - case msgTypeSig: - if c.authState != authStateAwaitingSig { - return - } - if err = c.processSig(msg); err != nil { - return - } - c.authState = authStateNone - c.state = stateEncrypted - change = NewKeys - case msgTypeData: - if c.state != stateEncrypted { - err = errors.New("otr: encrypted message received without encrypted session established") - return - } - var tlvs []tlv - out, tlvs, err = c.processData(msg) - encrypted = true - - EachTLV: - for _, inTLV := range tlvs { - switch inTLV.typ { - case tlvTypeDisconnected: - change = ConversationEnded - c.state = stateFinished - break EachTLV - case tlvTypeSMP1, tlvTypeSMP2, tlvTypeSMP3, tlvTypeSMP4, tlvTypeSMPAbort, tlvTypeSMP1WithQuestion: - var reply tlv - var complete bool - reply, complete, err = c.processSMP(inTLV) - if err == smpSecretMissingError { - err = nil - change = SMPSecretNeeded - c.smp.saved = &inTLV - return - } - if err == smpFailureError { - err = nil - change = SMPFailed - } else if complete { - change = SMPComplete - } - if reply.typ != 0 { - toSend = c.encode(c.generateData(nil, &reply)) - } - break EachTLV - default: - // skip unknown TLVs - } - } - default: - err = errors.New("otr: unknown message type " + strconv.Itoa(msgType)) - } - - return -} - -// Send takes a human readable message from the local user, possibly encrypts -// it and returns zero one or more messages to send to the peer. -func (c *Conversation) Send(msg []byte) ([][]byte, error) { - switch c.state { - case statePlaintext: - return [][]byte{msg}, nil - case stateEncrypted: - return c.encode(c.generateData(msg, nil)), nil - case stateFinished: - return nil, errors.New("otr: cannot send message because secure conversation has finished") - } - - return nil, errors.New("otr: cannot send message in current state") -} - -// SMPQuestion returns the human readable challenge question from the peer. -// It's only valid after Receive has returned SMPSecretNeeded. -func (c *Conversation) SMPQuestion() string { - return c.smp.question -} - -// Authenticate begins an authentication with the peer. Authentication involves -// an optional challenge message and a shared secret. The authentication -// proceeds until either Receive returns SMPComplete, SMPSecretNeeded (which -// indicates that a new authentication is happening and thus this one was -// aborted) or SMPFailed. -func (c *Conversation) Authenticate(question string, mutualSecret []byte) (toSend [][]byte, err error) { - if c.state != stateEncrypted { - err = errors.New("otr: can't authenticate a peer without a secure conversation established") - return - } - - if c.smp.saved != nil { - c.calcSMPSecret(mutualSecret, false /* they started it */) - - var out tlv - var complete bool - out, complete, err = c.processSMP(*c.smp.saved) - if complete { - panic("SMP completed on the first message") - } - c.smp.saved = nil - if out.typ != 0 { - toSend = c.encode(c.generateData(nil, &out)) - } - return - } - - c.calcSMPSecret(mutualSecret, true /* we started it */) - outs := c.startSMP(question) - for _, out := range outs { - toSend = append(toSend, c.encode(c.generateData(nil, &out))...) - } - return -} - -// End ends a secure conversation by generating a termination message for -// the peer and switches to unencrypted communication. -func (c *Conversation) End() (toSend [][]byte) { - switch c.state { - case statePlaintext: - return nil - case stateEncrypted: - c.state = statePlaintext - return c.encode(c.generateData(nil, &tlv{typ: tlvTypeDisconnected})) - case stateFinished: - c.state = statePlaintext - return nil - } - panic("unreachable") -} - -// IsEncrypted returns true if a message passed to Send would be encrypted -// before transmission. This result remains valid until the next call to -// Receive or End, which may change the state of the Conversation. -func (c *Conversation) IsEncrypted() bool { - return c.state == stateEncrypted -} - -var fragmentError = errors.New("otr: invalid OTR fragment") - -// processFragment processes a fragmented OTR message and possibly returns a -// complete message. Fragmented messages look like "?OTR,k,n,msg," where k is -// the fragment number (starting from 1), n is the number of fragments in this -// message and msg is a substring of the base64 encoded message. -func (c *Conversation) processFragment(in []byte) (out []byte, err error) { - in = in[len(fragmentPrefix):] // remove "?OTR," - parts := bytes.Split(in, fragmentPartSeparator) - if len(parts) != 4 || len(parts[3]) != 0 { - return nil, fragmentError - } - - k, err := strconv.Atoi(string(parts[0])) - if err != nil { - return nil, fragmentError - } - - n, err := strconv.Atoi(string(parts[1])) - if err != nil { - return nil, fragmentError - } - - if k < 1 || n < 1 || k > n { - return nil, fragmentError - } - - if k == 1 { - c.frag = append(c.frag[:0], parts[2]...) - c.k, c.n = k, n - } else if n == c.n && k == c.k+1 { - c.frag = append(c.frag, parts[2]...) - c.k++ - } else { - c.frag = c.frag[:0] - c.n, c.k = 0, 0 - } - - if c.n > 0 && c.k == c.n { - c.n, c.k = 0, 0 - return c.frag, nil - } - - return nil, nil -} - -func (c *Conversation) generateDHCommit() []byte { - _, err := io.ReadFull(c.rand(), c.r[:]) - if err != nil { - panic("otr: short read from random source") - } - - var xBytes [dhPrivateBytes]byte - c.x = c.randMPI(xBytes[:]) - c.gx = new(big.Int).Exp(g, c.x, p) - c.gy = nil - c.gxBytes = appendMPI(nil, c.gx) - - h := sha256.New() - h.Write(c.gxBytes) - h.Sum(c.digest[:0]) - - aesCipher, err := aes.NewCipher(c.r[:]) - if err != nil { - panic(err.Error()) - } - - var iv [aes.BlockSize]byte - ctr := cipher.NewCTR(aesCipher, iv[:]) - ctr.XORKeyStream(c.gxBytes, c.gxBytes) - - return c.serializeDHCommit() -} - -func (c *Conversation) serializeDHCommit() []byte { - var ret []byte - ret = appendU16(ret, 2) // protocol version - ret = append(ret, msgTypeDHCommit) - ret = appendData(ret, c.gxBytes) - ret = appendData(ret, c.digest[:]) - return ret -} - -func (c *Conversation) processDHCommit(in []byte) error { - var ok1, ok2 bool - c.gxBytes, in, ok1 = getData(in) - digest, in, ok2 := getData(in) - if !ok1 || !ok2 || len(in) > 0 { - return errors.New("otr: corrupt DH commit message") - } - copy(c.digest[:], digest) - return nil -} - -func (c *Conversation) compareToDHCommit(in []byte) (int, error) { - _, in, ok1 := getData(in) - digest, in, ok2 := getData(in) - if !ok1 || !ok2 || len(in) > 0 { - return 0, errors.New("otr: corrupt DH commit message") - } - return bytes.Compare(c.digest[:], digest), nil -} - -func (c *Conversation) generateDHKey() []byte { - var yBytes [dhPrivateBytes]byte - c.y = c.randMPI(yBytes[:]) - c.gy = new(big.Int).Exp(g, c.y, p) - return c.serializeDHKey() -} - -func (c *Conversation) serializeDHKey() []byte { - var ret []byte - ret = appendU16(ret, 2) // protocol version - ret = append(ret, msgTypeDHKey) - ret = appendMPI(ret, c.gy) - return ret -} - -func (c *Conversation) processDHKey(in []byte) (isSame bool, err error) { - gy, in, ok := getMPI(in) - if !ok { - err = errors.New("otr: corrupt DH key message") - return - } - if gy.Cmp(g) < 0 || gy.Cmp(pMinus2) > 0 { - err = errors.New("otr: DH value out of range") - return - } - if c.gy != nil { - isSame = c.gy.Cmp(gy) == 0 - return - } - c.gy = gy - return -} - -func (c *Conversation) generateEncryptedSignature(keys *akeKeys, xFirst bool) ([]byte, []byte) { - var xb []byte - xb = c.PrivateKey.PublicKey.Serialize(xb) - - var verifyData []byte - if xFirst { - verifyData = appendMPI(verifyData, c.gx) - verifyData = appendMPI(verifyData, c.gy) - } else { - verifyData = appendMPI(verifyData, c.gy) - verifyData = appendMPI(verifyData, c.gx) - } - verifyData = append(verifyData, xb...) - verifyData = appendU32(verifyData, c.myKeyId) - - mac := hmac.New(sha256.New, keys.m1[:]) - mac.Write(verifyData) - mb := mac.Sum(nil) - - xb = appendU32(xb, c.myKeyId) - xb = append(xb, c.PrivateKey.Sign(c.rand(), mb)...) - - aesCipher, err := aes.NewCipher(keys.c[:]) - if err != nil { - panic(err.Error()) - } - var iv [aes.BlockSize]byte - ctr := cipher.NewCTR(aesCipher, iv[:]) - ctr.XORKeyStream(xb, xb) - - mac = hmac.New(sha256.New, keys.m2[:]) - encryptedSig := appendData(nil, xb) - mac.Write(encryptedSig) - - return encryptedSig, mac.Sum(nil) -} - -func (c *Conversation) generateRevealSig() []byte { - s := new(big.Int).Exp(c.gy, c.x, p) - c.calcAKEKeys(s) - c.myKeyId++ - - encryptedSig, mac := c.generateEncryptedSignature(&c.revealKeys, true /* gx comes first */) - - c.myCurrentDHPub = c.gx - c.myCurrentDHPriv = c.x - c.rotateDHKeys() - incCounter(&c.myCounter) - - var ret []byte - ret = appendU16(ret, 2) - ret = append(ret, msgTypeRevealSig) - ret = appendData(ret, c.r[:]) - ret = append(ret, encryptedSig...) - ret = append(ret, mac[:20]...) - return ret -} - -func (c *Conversation) processEncryptedSig(encryptedSig, theirMAC []byte, keys *akeKeys, xFirst bool) error { - mac := hmac.New(sha256.New, keys.m2[:]) - mac.Write(appendData(nil, encryptedSig)) - myMAC := mac.Sum(nil)[:20] - - if len(myMAC) != len(theirMAC) || subtle.ConstantTimeCompare(myMAC, theirMAC) == 0 { - return errors.New("bad signature MAC in encrypted signature") - } - - aesCipher, err := aes.NewCipher(keys.c[:]) - if err != nil { - panic(err.Error()) - } - var iv [aes.BlockSize]byte - ctr := cipher.NewCTR(aesCipher, iv[:]) - ctr.XORKeyStream(encryptedSig, encryptedSig) - - sig := encryptedSig - sig, ok1 := c.TheirPublicKey.Parse(sig) - keyId, sig, ok2 := getU32(sig) - if !ok1 || !ok2 { - return errors.New("otr: corrupt encrypted signature") - } - - var verifyData []byte - if xFirst { - verifyData = appendMPI(verifyData, c.gx) - verifyData = appendMPI(verifyData, c.gy) - } else { - verifyData = appendMPI(verifyData, c.gy) - verifyData = appendMPI(verifyData, c.gx) - } - verifyData = c.TheirPublicKey.Serialize(verifyData) - verifyData = appendU32(verifyData, keyId) - - mac = hmac.New(sha256.New, keys.m1[:]) - mac.Write(verifyData) - mb := mac.Sum(nil) - - sig, ok1 = c.TheirPublicKey.Verify(mb, sig) - if !ok1 { - return errors.New("bad signature in encrypted signature") - } - if len(sig) > 0 { - return errors.New("corrupt encrypted signature") - } - - c.theirKeyId = keyId - zero(c.theirLastCtr[:]) - return nil -} - -func (c *Conversation) processRevealSig(in []byte) error { - r, in, ok1 := getData(in) - encryptedSig, in, ok2 := getData(in) - theirMAC := in - if !ok1 || !ok2 || len(theirMAC) != 20 { - return errors.New("otr: corrupt reveal signature message") - } - - aesCipher, err := aes.NewCipher(r) - if err != nil { - return errors.New("otr: cannot create AES cipher from reveal signature message: " + err.Error()) - } - var iv [aes.BlockSize]byte - ctr := cipher.NewCTR(aesCipher, iv[:]) - ctr.XORKeyStream(c.gxBytes, c.gxBytes) - h := sha256.New() - h.Write(c.gxBytes) - digest := h.Sum(nil) - if len(digest) != len(c.digest) || subtle.ConstantTimeCompare(digest, c.digest[:]) == 0 { - return errors.New("otr: bad commit MAC in reveal signature message") - } - var rest []byte - c.gx, rest, ok1 = getMPI(c.gxBytes) - if !ok1 || len(rest) > 0 { - return errors.New("otr: gx corrupt after decryption") - } - if c.gx.Cmp(g) < 0 || c.gx.Cmp(pMinus2) > 0 { - return errors.New("otr: DH value out of range") - } - s := new(big.Int).Exp(c.gx, c.y, p) - c.calcAKEKeys(s) - - if err := c.processEncryptedSig(encryptedSig, theirMAC, &c.revealKeys, true /* gx comes first */); err != nil { - return errors.New("otr: in reveal signature message: " + err.Error()) - } - - c.theirCurrentDHPub = c.gx - c.theirLastDHPub = nil - - return nil -} - -func (c *Conversation) generateSig() []byte { - c.myKeyId++ - - encryptedSig, mac := c.generateEncryptedSignature(&c.sigKeys, false /* gy comes first */) - - c.myCurrentDHPub = c.gy - c.myCurrentDHPriv = c.y - c.rotateDHKeys() - incCounter(&c.myCounter) - - var ret []byte - ret = appendU16(ret, 2) - ret = append(ret, msgTypeSig) - ret = append(ret, encryptedSig...) - ret = append(ret, mac[:macPrefixBytes]...) - return ret -} - -func (c *Conversation) processSig(in []byte) error { - encryptedSig, in, ok1 := getData(in) - theirMAC := in - if !ok1 || len(theirMAC) != macPrefixBytes { - return errors.New("otr: corrupt signature message") - } - - if err := c.processEncryptedSig(encryptedSig, theirMAC, &c.sigKeys, false /* gy comes first */); err != nil { - return errors.New("otr: in signature message: " + err.Error()) - } - - c.theirCurrentDHPub = c.gy - c.theirLastDHPub = nil - - return nil -} - -func (c *Conversation) rotateDHKeys() { - // evict slots using our retired key id - for i := range c.keySlots { - slot := &c.keySlots[i] - if slot.used && slot.myKeyId == c.myKeyId-1 { - slot.used = false - c.oldMACs = append(c.oldMACs, slot.recvMACKey...) - } - } - - c.myLastDHPriv = c.myCurrentDHPriv - c.myLastDHPub = c.myCurrentDHPub - - var xBytes [dhPrivateBytes]byte - c.myCurrentDHPriv = c.randMPI(xBytes[:]) - c.myCurrentDHPub = new(big.Int).Exp(g, c.myCurrentDHPriv, p) - c.myKeyId++ -} - -func (c *Conversation) processData(in []byte) (out []byte, tlvs []tlv, err error) { - origIn := in - flags, in, ok1 := getU8(in) - theirKeyId, in, ok2 := getU32(in) - myKeyId, in, ok3 := getU32(in) - y, in, ok4 := getMPI(in) - counter, in, ok5 := getNBytes(in, 8) - encrypted, in, ok6 := getData(in) - macedData := origIn[:len(origIn)-len(in)] - theirMAC, in, ok7 := getNBytes(in, macPrefixBytes) - _, in, ok8 := getData(in) - if !ok1 || !ok2 || !ok3 || !ok4 || !ok5 || !ok6 || !ok7 || !ok8 || len(in) > 0 { - err = errors.New("otr: corrupt data message") - return - } - - ignoreErrors := flags&1 != 0 - - slot, err := c.calcDataKeys(myKeyId, theirKeyId) - if err != nil { - if ignoreErrors { - err = nil - } - return - } - - mac := hmac.New(sha1.New, slot.recvMACKey) - mac.Write([]byte{0, 2, 3}) - mac.Write(macedData) - myMAC := mac.Sum(nil) - if len(myMAC) != len(theirMAC) || subtle.ConstantTimeCompare(myMAC, theirMAC) == 0 { - if !ignoreErrors { - err = errors.New("otr: bad MAC on data message") - } - return - } - - if bytes.Compare(counter, slot.theirLastCtr[:]) <= 0 { - err = errors.New("otr: counter regressed") - return - } - copy(slot.theirLastCtr[:], counter) - - var iv [aes.BlockSize]byte - copy(iv[:], counter) - aesCipher, err := aes.NewCipher(slot.recvAESKey) - if err != nil { - panic(err.Error()) - } - ctr := cipher.NewCTR(aesCipher, iv[:]) - ctr.XORKeyStream(encrypted, encrypted) - decrypted := encrypted - - if myKeyId == c.myKeyId { - c.rotateDHKeys() - } - if theirKeyId == c.theirKeyId { - // evict slots using their retired key id - for i := range c.keySlots { - slot := &c.keySlots[i] - if slot.used && slot.theirKeyId == theirKeyId-1 { - slot.used = false - c.oldMACs = append(c.oldMACs, slot.recvMACKey...) - } - } - - c.theirLastDHPub = c.theirCurrentDHPub - c.theirKeyId++ - c.theirCurrentDHPub = y - } - - if nulPos := bytes.IndexByte(decrypted, 0); nulPos >= 0 { - out = decrypted[:nulPos] - tlvData := decrypted[nulPos+1:] - for len(tlvData) > 0 { - var t tlv - var ok1, ok2, ok3 bool - - t.typ, tlvData, ok1 = getU16(tlvData) - t.length, tlvData, ok2 = getU16(tlvData) - t.data, tlvData, ok3 = getNBytes(tlvData, int(t.length)) - if !ok1 || !ok2 || !ok3 { - err = errors.New("otr: corrupt tlv data") - } - tlvs = append(tlvs, t) - } - } else { - out = decrypted - } - - return -} - -func (c *Conversation) generateData(msg []byte, extra *tlv) []byte { - slot, err := c.calcDataKeys(c.myKeyId-1, c.theirKeyId) - if err != nil { - panic("otr: failed to generate sending keys: " + err.Error()) - } - - var plaintext []byte - plaintext = append(plaintext, msg...) - plaintext = append(plaintext, 0) - - padding := paddingGranularity - ((len(plaintext) + 4) % paddingGranularity) - plaintext = appendU16(plaintext, tlvTypePadding) - plaintext = appendU16(plaintext, uint16(padding)) - for i := 0; i < padding; i++ { - plaintext = append(plaintext, 0) - } - - if extra != nil { - plaintext = appendU16(plaintext, extra.typ) - plaintext = appendU16(plaintext, uint16(len(extra.data))) - plaintext = append(plaintext, extra.data...) - } - - encrypted := make([]byte, len(plaintext)) - - var iv [aes.BlockSize]byte - copy(iv[:], c.myCounter[:]) - aesCipher, err := aes.NewCipher(slot.sendAESKey) - if err != nil { - panic(err.Error()) - } - ctr := cipher.NewCTR(aesCipher, iv[:]) - ctr.XORKeyStream(encrypted, plaintext) - - var ret []byte - ret = appendU16(ret, 2) - ret = append(ret, msgTypeData) - ret = append(ret, 0 /* flags */) - ret = appendU32(ret, c.myKeyId-1) - ret = appendU32(ret, c.theirKeyId) - ret = appendMPI(ret, c.myCurrentDHPub) - ret = append(ret, c.myCounter[:]...) - ret = appendData(ret, encrypted) - - mac := hmac.New(sha1.New, slot.sendMACKey) - mac.Write(ret) - ret = append(ret, mac.Sum(nil)[:macPrefixBytes]...) - ret = appendData(ret, c.oldMACs) - c.oldMACs = nil - incCounter(&c.myCounter) - - return ret -} - -func incCounter(counter *[8]byte) { - for i := 7; i >= 0; i-- { - counter[i]++ - if counter[i] > 0 { - break - } - } -} - -// calcDataKeys computes the keys used to encrypt a data message given the key -// IDs. -func (c *Conversation) calcDataKeys(myKeyId, theirKeyId uint32) (slot *keySlot, err error) { - // Check for a cache hit. - for i := range c.keySlots { - slot = &c.keySlots[i] - if slot.used && slot.theirKeyId == theirKeyId && slot.myKeyId == myKeyId { - return - } - } - - // Find an empty slot to write into. - slot = nil - for i := range c.keySlots { - if !c.keySlots[i].used { - slot = &c.keySlots[i] - break - } - } - if slot == nil { - return nil, errors.New("otr: internal error: no more key slots") - } - - var myPriv, myPub, theirPub *big.Int - - if myKeyId == c.myKeyId { - myPriv = c.myCurrentDHPriv - myPub = c.myCurrentDHPub - } else if myKeyId == c.myKeyId-1 { - myPriv = c.myLastDHPriv - myPub = c.myLastDHPub - } else { - err = errors.New("otr: peer requested keyid " + strconv.FormatUint(uint64(myKeyId), 10) + " when I'm on " + strconv.FormatUint(uint64(c.myKeyId), 10)) - return - } - - if theirKeyId == c.theirKeyId { - theirPub = c.theirCurrentDHPub - } else if theirKeyId == c.theirKeyId-1 && c.theirLastDHPub != nil { - theirPub = c.theirLastDHPub - } else { - err = errors.New("otr: peer requested keyid " + strconv.FormatUint(uint64(myKeyId), 10) + " when they're on " + strconv.FormatUint(uint64(c.myKeyId), 10)) - return - } - - var sendPrefixByte, recvPrefixByte [1]byte - - if myPub.Cmp(theirPub) > 0 { - // we're the high end - sendPrefixByte[0], recvPrefixByte[0] = 1, 2 - } else { - // we're the low end - sendPrefixByte[0], recvPrefixByte[0] = 2, 1 - } - - s := new(big.Int).Exp(theirPub, myPriv, p) - sBytes := appendMPI(nil, s) - - h := sha1.New() - h.Write(sendPrefixByte[:]) - h.Write(sBytes) - slot.sendAESKey = h.Sum(slot.sendAESKey[:0])[:16] - - h.Reset() - h.Write(slot.sendAESKey) - slot.sendMACKey = h.Sum(slot.sendMACKey[:0]) - - h.Reset() - h.Write(recvPrefixByte[:]) - h.Write(sBytes) - slot.recvAESKey = h.Sum(slot.recvAESKey[:0])[:16] - - h.Reset() - h.Write(slot.recvAESKey) - slot.recvMACKey = h.Sum(slot.recvMACKey[:0]) - - slot.theirKeyId = theirKeyId - slot.myKeyId = myKeyId - slot.used = true - - zero(slot.theirLastCtr[:]) - return -} - -func (c *Conversation) calcAKEKeys(s *big.Int) { - mpi := appendMPI(nil, s) - h := sha256.New() - - var cBytes [32]byte - hashWithPrefix(c.SSID[:], 0, mpi, h) - - hashWithPrefix(cBytes[:], 1, mpi, h) - copy(c.revealKeys.c[:], cBytes[:16]) - copy(c.sigKeys.c[:], cBytes[16:]) - - hashWithPrefix(c.revealKeys.m1[:], 2, mpi, h) - hashWithPrefix(c.revealKeys.m2[:], 3, mpi, h) - hashWithPrefix(c.sigKeys.m1[:], 4, mpi, h) - hashWithPrefix(c.sigKeys.m2[:], 5, mpi, h) -} - -func hashWithPrefix(out []byte, prefix byte, in []byte, h hash.Hash) { - h.Reset() - var p [1]byte - p[0] = prefix - h.Write(p[:]) - h.Write(in) - if len(out) == h.Size() { - h.Sum(out[:0]) - } else { - digest := h.Sum(nil) - copy(out, digest) - } -} - -func (c *Conversation) encode(msg []byte) [][]byte { - b64 := make([]byte, base64.StdEncoding.EncodedLen(len(msg))+len(msgPrefix)+1) - base64.StdEncoding.Encode(b64[len(msgPrefix):], msg) - copy(b64, msgPrefix) - b64[len(b64)-1] = '.' - - if c.FragmentSize < minFragmentSize || len(b64) <= c.FragmentSize { - // We can encode this in a single fragment. - return [][]byte{b64} - } - - // We have to fragment this message. - var ret [][]byte - bytesPerFragment := c.FragmentSize - minFragmentSize - numFragments := (len(b64) + bytesPerFragment) / bytesPerFragment - - for i := 0; i < numFragments; i++ { - frag := []byte("?OTR," + strconv.Itoa(i+1) + "," + strconv.Itoa(numFragments) + ",") - todo := bytesPerFragment - if todo > len(b64) { - todo = len(b64) - } - frag = append(frag, b64[:todo]...) - b64 = b64[todo:] - frag = append(frag, ',') - ret = append(ret, frag) - } - - return ret -} - -func (c *Conversation) reset() { - c.myKeyId = 0 - - for i := range c.keySlots { - c.keySlots[i].used = false - } -} - -type PublicKey struct { - dsa.PublicKey -} - -func (pk *PublicKey) Parse(in []byte) ([]byte, bool) { - var ok bool - var pubKeyType uint16 - - if pubKeyType, in, ok = getU16(in); !ok || pubKeyType != 0 { - return nil, false - } - if pk.P, in, ok = getMPI(in); !ok { - return nil, false - } - if pk.Q, in, ok = getMPI(in); !ok { - return nil, false - } - if pk.G, in, ok = getMPI(in); !ok { - return nil, false - } - if pk.Y, in, ok = getMPI(in); !ok { - return nil, false - } - - return in, true -} - -func (pk *PublicKey) Serialize(in []byte) []byte { - in = appendU16(in, 0) - in = appendMPI(in, pk.P) - in = appendMPI(in, pk.Q) - in = appendMPI(in, pk.G) - in = appendMPI(in, pk.Y) - return in -} - -// Fingerprint returns the 20-byte, binary fingerprint of the PublicKey. -func (pk *PublicKey) Fingerprint() []byte { - b := pk.Serialize(nil) - h := sha1.New() - h.Write(b[2:]) - return h.Sum(nil) -} - -func (pk *PublicKey) Verify(hashed, sig []byte) ([]byte, bool) { - if len(sig) != 2*dsaSubgroupBytes { - return nil, false - } - r := new(big.Int).SetBytes(sig[:dsaSubgroupBytes]) - s := new(big.Int).SetBytes(sig[dsaSubgroupBytes:]) - ok := dsa.Verify(&pk.PublicKey, hashed, r, s) - return sig[dsaSubgroupBytes*2:], ok -} - -type PrivateKey struct { - PublicKey - dsa.PrivateKey -} - -func (priv *PrivateKey) Sign(rand io.Reader, hashed []byte) []byte { - r, s, err := dsa.Sign(rand, &priv.PrivateKey, hashed) - if err != nil { - panic(err.Error()) - } - rBytes := r.Bytes() - sBytes := s.Bytes() - if len(rBytes) > dsaSubgroupBytes || len(sBytes) > dsaSubgroupBytes { - panic("DSA signature too large") - } - - out := make([]byte, 2*dsaSubgroupBytes) - copy(out[dsaSubgroupBytes-len(rBytes):], rBytes) - copy(out[len(out)-len(sBytes):], sBytes) - return out -} - -func (priv *PrivateKey) Serialize(in []byte) []byte { - in = priv.PublicKey.Serialize(in) - in = appendMPI(in, priv.PrivateKey.X) - return in -} - -func (priv *PrivateKey) Parse(in []byte) ([]byte, bool) { - in, ok := priv.PublicKey.Parse(in) - if !ok { - return in, ok - } - priv.PrivateKey.PublicKey = priv.PublicKey.PublicKey - priv.PrivateKey.X, in, ok = getMPI(in) - return in, ok -} - -func (priv *PrivateKey) Generate(rand io.Reader) { - if err := dsa.GenerateParameters(&priv.PrivateKey.PublicKey.Parameters, rand, dsa.L1024N160); err != nil { - panic(err.Error()) - } - if err := dsa.GenerateKey(&priv.PrivateKey, rand); err != nil { - panic(err.Error()) - } - priv.PublicKey.PublicKey = priv.PrivateKey.PublicKey -} - -func notHex(r rune) bool { - if r >= '0' && r <= '9' || - r >= 'a' && r <= 'f' || - r >= 'A' && r <= 'F' { - return false - } - - return true -} - -// Import parses the contents of a libotr private key file. -func (priv *PrivateKey) Import(in []byte) bool { - mpiStart := []byte(" #") - - mpis := make([]*big.Int, 5) - - for i := 0; i < len(mpis); i++ { - start := bytes.Index(in, mpiStart) - if start == -1 { - return false - } - in = in[start+len(mpiStart):] - end := bytes.IndexFunc(in, notHex) - if end == -1 { - return false - } - hexBytes := in[:end] - in = in[end:] - - if len(hexBytes)&1 != 0 { - return false - } - - mpiBytes := make([]byte, len(hexBytes)/2) - if _, err := hex.Decode(mpiBytes, hexBytes); err != nil { - return false - } - - mpis[i] = new(big.Int).SetBytes(mpiBytes) - } - - priv.PrivateKey.P = mpis[0] - priv.PrivateKey.Q = mpis[1] - priv.PrivateKey.G = mpis[2] - priv.PrivateKey.Y = mpis[3] - priv.PrivateKey.X = mpis[4] - priv.PublicKey.PublicKey = priv.PrivateKey.PublicKey - - a := new(big.Int).Exp(priv.PrivateKey.G, priv.PrivateKey.X, priv.PrivateKey.P) - return a.Cmp(priv.PrivateKey.Y) == 0 -} - -func getU8(in []byte) (uint8, []byte, bool) { - if len(in) < 1 { - return 0, in, false - } - return in[0], in[1:], true -} - -func getU16(in []byte) (uint16, []byte, bool) { - if len(in) < 2 { - return 0, in, false - } - r := uint16(in[0])<<8 | uint16(in[1]) - return r, in[2:], true -} - -func getU32(in []byte) (uint32, []byte, bool) { - if len(in) < 4 { - return 0, in, false - } - r := uint32(in[0])<<24 | uint32(in[1])<<16 | uint32(in[2])<<8 | uint32(in[3]) - return r, in[4:], true -} - -func getMPI(in []byte) (*big.Int, []byte, bool) { - l, in, ok := getU32(in) - if !ok || uint32(len(in)) < l { - return nil, in, false - } - r := new(big.Int).SetBytes(in[:l]) - return r, in[l:], true -} - -func getData(in []byte) ([]byte, []byte, bool) { - l, in, ok := getU32(in) - if !ok || uint32(len(in)) < l { - return nil, in, false - } - return in[:l], in[l:], true -} - -func getNBytes(in []byte, n int) ([]byte, []byte, bool) { - if len(in) < n { - return nil, in, false - } - return in[:n], in[n:], true -} - -func appendU16(out []byte, v uint16) []byte { - out = append(out, byte(v>>8), byte(v)) - return out -} - -func appendU32(out []byte, v uint32) []byte { - out = append(out, byte(v>>24), byte(v>>16), byte(v>>8), byte(v)) - return out -} - -func appendData(out, v []byte) []byte { - out = appendU32(out, uint32(len(v))) - out = append(out, v...) - return out -} - -func appendMPI(out []byte, v *big.Int) []byte { - vBytes := v.Bytes() - out = appendU32(out, uint32(len(vBytes))) - out = append(out, vBytes...) - return out -} - -func appendMPIs(out []byte, mpis ...*big.Int) []byte { - for _, mpi := range mpis { - out = appendMPI(out, mpi) - } - return out -} - -func zero(b []byte) { - for i := range b { - b[i] = 0 - } -} diff --git a/vendor/golang.org/x/crypto/otr/otr_test.go b/vendor/golang.org/x/crypto/otr/otr_test.go deleted file mode 100644 index cfcd062..0000000 --- a/vendor/golang.org/x/crypto/otr/otr_test.go +++ /dev/null @@ -1,470 +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. - -package otr - -import ( - "bufio" - "bytes" - "crypto/rand" - "encoding/hex" - "math/big" - "os" - "os/exec" - "testing" -) - -var isQueryTests = []struct { - msg string - expectedVersion int -}{ - {"foo", 0}, - {"?OtR", 0}, - {"?OtR?", 0}, - {"?OTR?", 0}, - {"?OTRv?", 0}, - {"?OTRv1?", 0}, - {"?OTR?v1?", 0}, - {"?OTR?v?", 0}, - {"?OTR?v2?", 2}, - {"?OTRv2?", 2}, - {"?OTRv23?", 2}, - {"?OTRv23 ?", 0}, -} - -func TestIsQuery(t *testing.T) { - for i, test := range isQueryTests { - version := isQuery([]byte(test.msg)) - if version != test.expectedVersion { - t.Errorf("#%d: got %d, want %d", i, version, test.expectedVersion) - } - } -} - -var alicePrivateKeyHex = "000000000080c81c2cb2eb729b7e6fd48e975a932c638b3a9055478583afa46755683e30102447f6da2d8bec9f386bbb5da6403b0040fee8650b6ab2d7f32c55ab017ae9b6aec8c324ab5844784e9a80e194830d548fb7f09a0410df2c4d5c8bc2b3e9ad484e65412be689cf0834694e0839fb2954021521ffdffb8f5c32c14dbf2020b3ce7500000014da4591d58def96de61aea7b04a8405fe1609308d000000808ddd5cb0b9d66956e3dea5a915d9aba9d8a6e7053b74dadb2fc52f9fe4e5bcc487d2305485ed95fed026ad93f06ebb8c9e8baf693b7887132c7ffdd3b0f72f4002ff4ed56583ca7c54458f8c068ca3e8a4dfa309d1dd5d34e2a4b68e6f4338835e5e0fb4317c9e4c7e4806dafda3ef459cd563775a586dd91b1319f72621bf3f00000080b8147e74d8c45e6318c37731b8b33b984a795b3653c2cd1d65cc99efe097cb7eb2fa49569bab5aab6e8a1c261a27d0f7840a5e80b317e6683042b59b6dceca2879c6ffc877a465be690c15e4a42f9a7588e79b10faac11b1ce3741fcef7aba8ce05327a2c16d279ee1b3d77eb783fb10e3356caa25635331e26dd42b8396c4d00000001420bec691fea37ecea58a5c717142f0b804452f57" - -var aliceFingerprintHex = "0bb01c360424522e94ee9c346ce877a1a4288b2f" - -var bobPrivateKeyHex = "000000000080a5138eb3d3eb9c1d85716faecadb718f87d31aaed1157671d7fee7e488f95e8e0ba60ad449ec732710a7dec5190f7182af2e2f98312d98497221dff160fd68033dd4f3a33b7c078d0d9f66e26847e76ca7447d4bab35486045090572863d9e4454777f24d6706f63e02548dfec2d0a620af37bbc1d24f884708a212c343b480d00000014e9c58f0ea21a5e4dfd9f44b6a9f7f6a9961a8fa9000000803c4d111aebd62d3c50c2889d420a32cdf1e98b70affcc1fcf44d59cca2eb019f6b774ef88153fb9b9615441a5fe25ea2d11b74ce922ca0232bd81b3c0fcac2a95b20cb6e6c0c5c1ace2e26f65dc43c751af0edbb10d669890e8ab6beea91410b8b2187af1a8347627a06ecea7e0f772c28aae9461301e83884860c9b656c722f0000008065af8625a555ea0e008cd04743671a3cda21162e83af045725db2eb2bb52712708dc0cc1a84c08b3649b88a966974bde27d8612c2861792ec9f08786a246fcadd6d8d3a81a32287745f309238f47618c2bd7612cb8b02d940571e0f30b96420bcd462ff542901b46109b1e5ad6423744448d20a57818a8cbb1647d0fea3b664e0000001440f9f2eb554cb00d45a5826b54bfa419b6980e48" - -func TestKeySerialization(t *testing.T) { - var priv PrivateKey - alicePrivateKey, _ := hex.DecodeString(alicePrivateKeyHex) - rest, ok := priv.Parse(alicePrivateKey) - if !ok { - t.Error("failed to parse private key") - } - if len(rest) > 0 { - t.Error("data remaining after parsing private key") - } - - out := priv.Serialize(nil) - if !bytes.Equal(alicePrivateKey, out) { - t.Errorf("serialization (%x) is not equal to original (%x)", out, alicePrivateKey) - } - - aliceFingerprint, _ := hex.DecodeString(aliceFingerprintHex) - fingerprint := priv.PublicKey.Fingerprint() - if !bytes.Equal(aliceFingerprint, fingerprint) { - t.Errorf("fingerprint (%x) is not equal to expected value (%x)", fingerprint, aliceFingerprint) - } -} - -const libOTRPrivateKey = `(privkeys - (account -(name "foo@example.com") -(protocol prpl-jabber) -(private-key - (dsa - (p #00FC07ABCF0DC916AFF6E9AE47BEF60C7AB9B4D6B2469E436630E36F8A489BE812486A09F30B71224508654940A835301ACC525A4FF133FC152CC53DCC59D65C30A54F1993FE13FE63E5823D4C746DB21B90F9B9C00B49EC7404AB1D929BA7FBA12F2E45C6E0A651689750E8528AB8C031D3561FECEE72EBB4A090D450A9B7A857#) - (q #00997BD266EF7B1F60A5C23F3A741F2AEFD07A2081#) - (g #535E360E8A95EBA46A4F7DE50AD6E9B2A6DB785A66B64EB9F20338D2A3E8FB0E94725848F1AA6CC567CB83A1CC517EC806F2E92EAE71457E80B2210A189B91250779434B41FC8A8873F6DB94BEA7D177F5D59E7E114EE10A49CFD9CEF88AE43387023B672927BA74B04EB6BBB5E57597766A2F9CE3857D7ACE3E1E3BC1FC6F26#) - (y #0AC8670AD767D7A8D9D14CC1AC6744CD7D76F993B77FFD9E39DF01E5A6536EF65E775FCEF2A983E2A19BD6415500F6979715D9FD1257E1FE2B6F5E1E74B333079E7C880D39868462A93454B41877BE62E5EF0A041C2EE9C9E76BD1E12AE25D9628DECB097025DD625EF49C3258A1A3C0FF501E3DC673B76D7BABF349009B6ECF#) - (x #14D0345A3562C480A039E3C72764F72D79043216#) - ) - ) - ) -)` - -func TestParseLibOTRPrivateKey(t *testing.T) { - var priv PrivateKey - - if !priv.Import([]byte(libOTRPrivateKey)) { - t.Fatalf("Failed to import sample private key") - } -} - -func TestSignVerify(t *testing.T) { - var priv PrivateKey - alicePrivateKey, _ := hex.DecodeString(alicePrivateKeyHex) - _, ok := priv.Parse(alicePrivateKey) - if !ok { - t.Error("failed to parse private key") - } - - var msg [32]byte - rand.Reader.Read(msg[:]) - - sig := priv.Sign(rand.Reader, msg[:]) - rest, ok := priv.PublicKey.Verify(msg[:], sig) - if !ok { - t.Errorf("signature (%x) of %x failed to verify", sig, msg[:]) - } else if len(rest) > 0 { - t.Error("signature data remains after verification") - } - - sig[10] ^= 80 - _, ok = priv.PublicKey.Verify(msg[:], sig) - if ok { - t.Errorf("corrupted signature (%x) of %x verified", sig, msg[:]) - } -} - -func setupConversation(t *testing.T) (alice, bob *Conversation) { - alicePrivateKey, _ := hex.DecodeString(alicePrivateKeyHex) - bobPrivateKey, _ := hex.DecodeString(bobPrivateKeyHex) - - alice, bob = new(Conversation), new(Conversation) - - alice.PrivateKey = new(PrivateKey) - bob.PrivateKey = new(PrivateKey) - alice.PrivateKey.Parse(alicePrivateKey) - bob.PrivateKey.Parse(bobPrivateKey) - alice.FragmentSize = 100 - bob.FragmentSize = 100 - - if alice.IsEncrypted() { - t.Error("Alice believes that the conversation is secure before we've started") - } - if bob.IsEncrypted() { - t.Error("Bob believes that the conversation is secure before we've started") - } - - performHandshake(t, alice, bob) - return alice, bob -} - -func performHandshake(t *testing.T, alice, bob *Conversation) { - var alicesMessage, bobsMessage [][]byte - var out []byte - var aliceChange, bobChange SecurityChange - var err error - alicesMessage = append(alicesMessage, []byte(QueryMessage)) - - for round := 0; len(alicesMessage) > 0 || len(bobsMessage) > 0; round++ { - bobsMessage = nil - for i, msg := range alicesMessage { - out, _, bobChange, bobsMessage, err = bob.Receive(msg) - if len(out) > 0 { - t.Errorf("Bob generated output during key exchange, round %d, message %d", round, i) - } - if err != nil { - t.Fatalf("Bob returned an error, round %d, message %d (%x): %s", round, i, msg, err) - } - if len(bobsMessage) > 0 && i != len(alicesMessage)-1 { - t.Errorf("Bob produced output while processing a fragment, round %d, message %d", round, i) - } - } - - alicesMessage = nil - for i, msg := range bobsMessage { - out, _, aliceChange, alicesMessage, err = alice.Receive(msg) - if len(out) > 0 { - t.Errorf("Alice generated output during key exchange, round %d, message %d", round, i) - } - if err != nil { - t.Fatalf("Alice returned an error, round %d, message %d (%x): %s", round, i, msg, err) - } - if len(alicesMessage) > 0 && i != len(bobsMessage)-1 { - t.Errorf("Alice produced output while processing a fragment, round %d, message %d", round, i) - } - } - } - - if aliceChange != NewKeys { - t.Errorf("Alice terminated without signaling new keys") - } - if bobChange != NewKeys { - t.Errorf("Bob terminated without signaling new keys") - } - - if !bytes.Equal(alice.SSID[:], bob.SSID[:]) { - t.Errorf("Session identifiers don't match. Alice has %x, Bob has %x", alice.SSID[:], bob.SSID[:]) - } - - if !alice.IsEncrypted() { - t.Error("Alice doesn't believe that the conversation is secure") - } - if !bob.IsEncrypted() { - t.Error("Bob doesn't believe that the conversation is secure") - } -} - -const ( - firstRoundTrip = iota - subsequentRoundTrip - noMACKeyCheck -) - -func roundTrip(t *testing.T, alice, bob *Conversation, message []byte, macKeyCheck int) { - alicesMessage, err := alice.Send(message) - if err != nil { - t.Errorf("Error from Alice sending message: %s", err) - } - - if len(alice.oldMACs) != 0 { - t.Errorf("Alice has not revealed all MAC keys") - } - - for i, msg := range alicesMessage { - out, encrypted, _, _, err := bob.Receive(msg) - - if err != nil { - t.Errorf("Error generated while processing test message: %s", err.Error()) - } - if len(out) > 0 { - if i != len(alicesMessage)-1 { - t.Fatal("Bob produced a message while processing a fragment of Alice's") - } - if !encrypted { - t.Errorf("Message was not marked as encrypted") - } - if !bytes.Equal(out, message) { - t.Errorf("Message corrupted: got %x, want %x", out, message) - } - } - } - - switch macKeyCheck { - case firstRoundTrip: - if len(bob.oldMACs) != 0 { - t.Errorf("Bob should not have MAC keys to reveal") - } - case subsequentRoundTrip: - if len(bob.oldMACs) != 40 { - t.Errorf("Bob has %d bytes of MAC keys to reveal, but should have 40", len(bob.oldMACs)) - } - } - - bobsMessage, err := bob.Send(message) - if err != nil { - t.Errorf("Error from Bob sending message: %s", err) - } - - if len(bob.oldMACs) != 0 { - t.Errorf("Bob has not revealed all MAC keys") - } - - for i, msg := range bobsMessage { - out, encrypted, _, _, err := alice.Receive(msg) - - if err != nil { - t.Errorf("Error generated while processing test message: %s", err.Error()) - } - if len(out) > 0 { - if i != len(bobsMessage)-1 { - t.Fatal("Alice produced a message while processing a fragment of Bob's") - } - if !encrypted { - t.Errorf("Message was not marked as encrypted") - } - if !bytes.Equal(out, message) { - t.Errorf("Message corrupted: got %x, want %x", out, message) - } - } - } - - switch macKeyCheck { - case firstRoundTrip: - if len(alice.oldMACs) != 20 { - t.Errorf("Alice has %d bytes of MAC keys to reveal, but should have 20", len(alice.oldMACs)) - } - case subsequentRoundTrip: - if len(alice.oldMACs) != 40 { - t.Errorf("Alice has %d bytes of MAC keys to reveal, but should have 40", len(alice.oldMACs)) - } - } -} - -func TestConversation(t *testing.T) { - alice, bob := setupConversation(t) - - var testMessages = [][]byte{ - []byte("hello"), []byte("bye"), - } - - roundTripType := firstRoundTrip - - for _, testMessage := range testMessages { - roundTrip(t, alice, bob, testMessage, roundTripType) - roundTripType = subsequentRoundTrip - } -} - -func TestGoodSMP(t *testing.T) { - var alice, bob Conversation - - alice.smp.secret = new(big.Int).SetInt64(42) - bob.smp.secret = alice.smp.secret - - var alicesMessages, bobsMessages []tlv - var aliceComplete, bobComplete bool - var err error - var out tlv - - alicesMessages = alice.startSMP("") - for round := 0; len(alicesMessages) > 0 || len(bobsMessages) > 0; round++ { - bobsMessages = bobsMessages[:0] - for i, msg := range alicesMessages { - out, bobComplete, err = bob.processSMP(msg) - if err != nil { - t.Errorf("Error from Bob in round %d: %s", round, err) - } - if bobComplete && i != len(alicesMessages)-1 { - t.Errorf("Bob returned a completed signal before processing all of Alice's messages in round %d", round) - } - if out.typ != 0 { - bobsMessages = append(bobsMessages, out) - } - } - - alicesMessages = alicesMessages[:0] - for i, msg := range bobsMessages { - out, aliceComplete, err = alice.processSMP(msg) - if err != nil { - t.Errorf("Error from Alice in round %d: %s", round, err) - } - if aliceComplete && i != len(bobsMessages)-1 { - t.Errorf("Alice returned a completed signal before processing all of Bob's messages in round %d", round) - } - if out.typ != 0 { - alicesMessages = append(alicesMessages, out) - } - } - } - - if !aliceComplete || !bobComplete { - t.Errorf("SMP completed without both sides reporting success: alice: %v, bob: %v\n", aliceComplete, bobComplete) - } -} - -func TestBadSMP(t *testing.T) { - var alice, bob Conversation - - alice.smp.secret = new(big.Int).SetInt64(42) - bob.smp.secret = new(big.Int).SetInt64(43) - - var alicesMessages, bobsMessages []tlv - - alicesMessages = alice.startSMP("") - for round := 0; len(alicesMessages) > 0 || len(bobsMessages) > 0; round++ { - bobsMessages = bobsMessages[:0] - for _, msg := range alicesMessages { - out, complete, _ := bob.processSMP(msg) - if complete { - t.Errorf("Bob signaled completion in round %d", round) - } - if out.typ != 0 { - bobsMessages = append(bobsMessages, out) - } - } - - alicesMessages = alicesMessages[:0] - for _, msg := range bobsMessages { - out, complete, _ := alice.processSMP(msg) - if complete { - t.Errorf("Alice signaled completion in round %d", round) - } - if out.typ != 0 { - alicesMessages = append(alicesMessages, out) - } - } - } -} - -func TestRehandshaking(t *testing.T) { - alice, bob := setupConversation(t) - roundTrip(t, alice, bob, []byte("test"), firstRoundTrip) - roundTrip(t, alice, bob, []byte("test 2"), subsequentRoundTrip) - roundTrip(t, alice, bob, []byte("test 3"), subsequentRoundTrip) - roundTrip(t, alice, bob, []byte("test 4"), subsequentRoundTrip) - roundTrip(t, alice, bob, []byte("test 5"), subsequentRoundTrip) - roundTrip(t, alice, bob, []byte("test 6"), subsequentRoundTrip) - roundTrip(t, alice, bob, []byte("test 7"), subsequentRoundTrip) - roundTrip(t, alice, bob, []byte("test 8"), subsequentRoundTrip) - performHandshake(t, alice, bob) - roundTrip(t, alice, bob, []byte("test"), noMACKeyCheck) - roundTrip(t, alice, bob, []byte("test 2"), noMACKeyCheck) -} - -func TestAgainstLibOTR(t *testing.T) { - // This test requires otr.c.test to be built as /tmp/a.out. - // If enabled, this tests runs forever performing OTR handshakes in a - // loop. - return - - alicePrivateKey, _ := hex.DecodeString(alicePrivateKeyHex) - var alice Conversation - alice.PrivateKey = new(PrivateKey) - alice.PrivateKey.Parse(alicePrivateKey) - - cmd := exec.Command("/tmp/a.out") - cmd.Stderr = os.Stderr - - out, err := cmd.StdinPipe() - if err != nil { - t.Fatal(err) - } - defer out.Close() - stdout, err := cmd.StdoutPipe() - if err != nil { - t.Fatal(err) - } - in := bufio.NewReader(stdout) - - if err := cmd.Start(); err != nil { - t.Fatal(err) - } - - out.Write([]byte(QueryMessage)) - out.Write([]byte("\n")) - var expectedText = []byte("test message") - - for { - line, isPrefix, err := in.ReadLine() - if isPrefix { - t.Fatal("line from subprocess too long") - } - if err != nil { - t.Fatal(err) - } - text, encrypted, change, alicesMessage, err := alice.Receive(line) - if err != nil { - t.Fatal(err) - } - for _, msg := range alicesMessage { - out.Write(msg) - out.Write([]byte("\n")) - } - if change == NewKeys { - alicesMessage, err := alice.Send([]byte("Go -> libotr test message")) - if err != nil { - t.Fatalf("error sending message: %s", err.Error()) - } else { - for _, msg := range alicesMessage { - out.Write(msg) - out.Write([]byte("\n")) - } - } - } - if len(text) > 0 { - if !bytes.Equal(text, expectedText) { - t.Fatalf("expected %x, but got %x", expectedText, text) - } - if !encrypted { - t.Fatal("message wasn't encrypted") - } - } - } -} diff --git a/vendor/golang.org/x/crypto/otr/smp.go b/vendor/golang.org/x/crypto/otr/smp.go deleted file mode 100644 index dc6de4e..0000000 --- a/vendor/golang.org/x/crypto/otr/smp.go +++ /dev/null @@ -1,572 +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 file implements the Socialist Millionaires Protocol as described in -// http://www.cypherpunks.ca/otr/Protocol-v2-3.1.0.html. The protocol -// specification is required in order to understand this code and, where -// possible, the variable names in the code match up with the spec. - -package otr - -import ( - "bytes" - "crypto/sha256" - "errors" - "hash" - "math/big" -) - -type smpFailure string - -func (s smpFailure) Error() string { - return string(s) -} - -var smpFailureError = smpFailure("otr: SMP protocol failed") -var smpSecretMissingError = smpFailure("otr: mutual secret needed") - -const smpVersion = 1 - -const ( - smpState1 = iota - smpState2 - smpState3 - smpState4 -) - -type smpState struct { - state int - a2, a3, b2, b3, pb, qb *big.Int - g2a, g3a *big.Int - g2, g3 *big.Int - g3b, papb, qaqb, ra *big.Int - saved *tlv - secret *big.Int - question string -} - -func (c *Conversation) startSMP(question string) (tlvs []tlv) { - if c.smp.state != smpState1 { - tlvs = append(tlvs, c.generateSMPAbort()) - } - tlvs = append(tlvs, c.generateSMP1(question)) - c.smp.question = "" - c.smp.state = smpState2 - return -} - -func (c *Conversation) resetSMP() { - c.smp.state = smpState1 - c.smp.secret = nil - c.smp.question = "" -} - -func (c *Conversation) processSMP(in tlv) (out tlv, complete bool, err error) { - data := in.data - - switch in.typ { - case tlvTypeSMPAbort: - if c.smp.state != smpState1 { - err = smpFailureError - } - c.resetSMP() - return - case tlvTypeSMP1WithQuestion: - // We preprocess this into a SMP1 message. - nulPos := bytes.IndexByte(data, 0) - if nulPos == -1 { - err = errors.New("otr: SMP message with question didn't contain a NUL byte") - return - } - c.smp.question = string(data[:nulPos]) - data = data[nulPos+1:] - } - - numMPIs, data, ok := getU32(data) - if !ok || numMPIs > 20 { - err = errors.New("otr: corrupt SMP message") - return - } - - mpis := make([]*big.Int, numMPIs) - for i := range mpis { - var ok bool - mpis[i], data, ok = getMPI(data) - if !ok { - err = errors.New("otr: corrupt SMP message") - return - } - } - - switch in.typ { - case tlvTypeSMP1, tlvTypeSMP1WithQuestion: - if c.smp.state != smpState1 { - c.resetSMP() - out = c.generateSMPAbort() - return - } - if c.smp.secret == nil { - err = smpSecretMissingError - return - } - if err = c.processSMP1(mpis); err != nil { - return - } - c.smp.state = smpState3 - out = c.generateSMP2() - case tlvTypeSMP2: - if c.smp.state != smpState2 { - c.resetSMP() - out = c.generateSMPAbort() - return - } - if out, err = c.processSMP2(mpis); err != nil { - out = c.generateSMPAbort() - return - } - c.smp.state = smpState4 - case tlvTypeSMP3: - if c.smp.state != smpState3 { - c.resetSMP() - out = c.generateSMPAbort() - return - } - if out, err = c.processSMP3(mpis); err != nil { - return - } - c.smp.state = smpState1 - c.smp.secret = nil - complete = true - case tlvTypeSMP4: - if c.smp.state != smpState4 { - c.resetSMP() - out = c.generateSMPAbort() - return - } - if err = c.processSMP4(mpis); err != nil { - out = c.generateSMPAbort() - return - } - c.smp.state = smpState1 - c.smp.secret = nil - complete = true - default: - panic("unknown SMP message") - } - - return -} - -func (c *Conversation) calcSMPSecret(mutualSecret []byte, weStarted bool) { - h := sha256.New() - h.Write([]byte{smpVersion}) - if weStarted { - h.Write(c.PrivateKey.PublicKey.Fingerprint()) - h.Write(c.TheirPublicKey.Fingerprint()) - } else { - h.Write(c.TheirPublicKey.Fingerprint()) - h.Write(c.PrivateKey.PublicKey.Fingerprint()) - } - h.Write(c.SSID[:]) - h.Write(mutualSecret) - c.smp.secret = new(big.Int).SetBytes(h.Sum(nil)) -} - -func (c *Conversation) generateSMP1(question string) tlv { - var randBuf [16]byte - c.smp.a2 = c.randMPI(randBuf[:]) - c.smp.a3 = c.randMPI(randBuf[:]) - g2a := new(big.Int).Exp(g, c.smp.a2, p) - g3a := new(big.Int).Exp(g, c.smp.a3, p) - h := sha256.New() - - r2 := c.randMPI(randBuf[:]) - r := new(big.Int).Exp(g, r2, p) - c2 := new(big.Int).SetBytes(hashMPIs(h, 1, r)) - d2 := new(big.Int).Mul(c.smp.a2, c2) - d2.Sub(r2, d2) - d2.Mod(d2, q) - if d2.Sign() < 0 { - d2.Add(d2, q) - } - - r3 := c.randMPI(randBuf[:]) - r.Exp(g, r3, p) - c3 := new(big.Int).SetBytes(hashMPIs(h, 2, r)) - d3 := new(big.Int).Mul(c.smp.a3, c3) - d3.Sub(r3, d3) - d3.Mod(d3, q) - if d3.Sign() < 0 { - d3.Add(d3, q) - } - - var ret tlv - if len(question) > 0 { - ret.typ = tlvTypeSMP1WithQuestion - ret.data = append(ret.data, question...) - ret.data = append(ret.data, 0) - } else { - ret.typ = tlvTypeSMP1 - } - ret.data = appendU32(ret.data, 6) - ret.data = appendMPIs(ret.data, g2a, c2, d2, g3a, c3, d3) - return ret -} - -func (c *Conversation) processSMP1(mpis []*big.Int) error { - if len(mpis) != 6 { - return errors.New("otr: incorrect number of arguments in SMP1 message") - } - g2a := mpis[0] - c2 := mpis[1] - d2 := mpis[2] - g3a := mpis[3] - c3 := mpis[4] - d3 := mpis[5] - h := sha256.New() - - r := new(big.Int).Exp(g, d2, p) - s := new(big.Int).Exp(g2a, c2, p) - r.Mul(r, s) - r.Mod(r, p) - t := new(big.Int).SetBytes(hashMPIs(h, 1, r)) - if c2.Cmp(t) != 0 { - return errors.New("otr: ZKP c2 incorrect in SMP1 message") - } - r.Exp(g, d3, p) - s.Exp(g3a, c3, p) - r.Mul(r, s) - r.Mod(r, p) - t.SetBytes(hashMPIs(h, 2, r)) - if c3.Cmp(t) != 0 { - return errors.New("otr: ZKP c3 incorrect in SMP1 message") - } - - c.smp.g2a = g2a - c.smp.g3a = g3a - return nil -} - -func (c *Conversation) generateSMP2() tlv { - var randBuf [16]byte - b2 := c.randMPI(randBuf[:]) - c.smp.b3 = c.randMPI(randBuf[:]) - r2 := c.randMPI(randBuf[:]) - r3 := c.randMPI(randBuf[:]) - r4 := c.randMPI(randBuf[:]) - r5 := c.randMPI(randBuf[:]) - r6 := c.randMPI(randBuf[:]) - - g2b := new(big.Int).Exp(g, b2, p) - g3b := new(big.Int).Exp(g, c.smp.b3, p) - - r := new(big.Int).Exp(g, r2, p) - h := sha256.New() - c2 := new(big.Int).SetBytes(hashMPIs(h, 3, r)) - d2 := new(big.Int).Mul(b2, c2) - d2.Sub(r2, d2) - d2.Mod(d2, q) - if d2.Sign() < 0 { - d2.Add(d2, q) - } - - r.Exp(g, r3, p) - c3 := new(big.Int).SetBytes(hashMPIs(h, 4, r)) - d3 := new(big.Int).Mul(c.smp.b3, c3) - d3.Sub(r3, d3) - d3.Mod(d3, q) - if d3.Sign() < 0 { - d3.Add(d3, q) - } - - c.smp.g2 = new(big.Int).Exp(c.smp.g2a, b2, p) - c.smp.g3 = new(big.Int).Exp(c.smp.g3a, c.smp.b3, p) - c.smp.pb = new(big.Int).Exp(c.smp.g3, r4, p) - c.smp.qb = new(big.Int).Exp(g, r4, p) - r.Exp(c.smp.g2, c.smp.secret, p) - c.smp.qb.Mul(c.smp.qb, r) - c.smp.qb.Mod(c.smp.qb, p) - - s := new(big.Int) - s.Exp(c.smp.g2, r6, p) - r.Exp(g, r5, p) - s.Mul(r, s) - s.Mod(s, p) - r.Exp(c.smp.g3, r5, p) - cp := new(big.Int).SetBytes(hashMPIs(h, 5, r, s)) - - // D5 = r5 - r4 cP mod q and D6 = r6 - y cP mod q - - s.Mul(r4, cp) - r.Sub(r5, s) - d5 := new(big.Int).Mod(r, q) - if d5.Sign() < 0 { - d5.Add(d5, q) - } - - s.Mul(c.smp.secret, cp) - r.Sub(r6, s) - d6 := new(big.Int).Mod(r, q) - if d6.Sign() < 0 { - d6.Add(d6, q) - } - - var ret tlv - ret.typ = tlvTypeSMP2 - ret.data = appendU32(ret.data, 11) - ret.data = appendMPIs(ret.data, g2b, c2, d2, g3b, c3, d3, c.smp.pb, c.smp.qb, cp, d5, d6) - return ret -} - -func (c *Conversation) processSMP2(mpis []*big.Int) (out tlv, err error) { - if len(mpis) != 11 { - err = errors.New("otr: incorrect number of arguments in SMP2 message") - return - } - g2b := mpis[0] - c2 := mpis[1] - d2 := mpis[2] - g3b := mpis[3] - c3 := mpis[4] - d3 := mpis[5] - pb := mpis[6] - qb := mpis[7] - cp := mpis[8] - d5 := mpis[9] - d6 := mpis[10] - h := sha256.New() - - r := new(big.Int).Exp(g, d2, p) - s := new(big.Int).Exp(g2b, c2, p) - r.Mul(r, s) - r.Mod(r, p) - s.SetBytes(hashMPIs(h, 3, r)) - if c2.Cmp(s) != 0 { - err = errors.New("otr: ZKP c2 failed in SMP2 message") - return - } - - r.Exp(g, d3, p) - s.Exp(g3b, c3, p) - r.Mul(r, s) - r.Mod(r, p) - s.SetBytes(hashMPIs(h, 4, r)) - if c3.Cmp(s) != 0 { - err = errors.New("otr: ZKP c3 failed in SMP2 message") - return - } - - c.smp.g2 = new(big.Int).Exp(g2b, c.smp.a2, p) - c.smp.g3 = new(big.Int).Exp(g3b, c.smp.a3, p) - - r.Exp(g, d5, p) - s.Exp(c.smp.g2, d6, p) - r.Mul(r, s) - s.Exp(qb, cp, p) - r.Mul(r, s) - r.Mod(r, p) - - s.Exp(c.smp.g3, d5, p) - t := new(big.Int).Exp(pb, cp, p) - s.Mul(s, t) - s.Mod(s, p) - t.SetBytes(hashMPIs(h, 5, s, r)) - if cp.Cmp(t) != 0 { - err = errors.New("otr: ZKP cP failed in SMP2 message") - return - } - - var randBuf [16]byte - r4 := c.randMPI(randBuf[:]) - r5 := c.randMPI(randBuf[:]) - r6 := c.randMPI(randBuf[:]) - r7 := c.randMPI(randBuf[:]) - - pa := new(big.Int).Exp(c.smp.g3, r4, p) - r.Exp(c.smp.g2, c.smp.secret, p) - qa := new(big.Int).Exp(g, r4, p) - qa.Mul(qa, r) - qa.Mod(qa, p) - - r.Exp(g, r5, p) - s.Exp(c.smp.g2, r6, p) - r.Mul(r, s) - r.Mod(r, p) - - s.Exp(c.smp.g3, r5, p) - cp.SetBytes(hashMPIs(h, 6, s, r)) - - r.Mul(r4, cp) - d5 = new(big.Int).Sub(r5, r) - d5.Mod(d5, q) - if d5.Sign() < 0 { - d5.Add(d5, q) - } - - r.Mul(c.smp.secret, cp) - d6 = new(big.Int).Sub(r6, r) - d6.Mod(d6, q) - if d6.Sign() < 0 { - d6.Add(d6, q) - } - - r.ModInverse(qb, p) - qaqb := new(big.Int).Mul(qa, r) - qaqb.Mod(qaqb, p) - - ra := new(big.Int).Exp(qaqb, c.smp.a3, p) - r.Exp(qaqb, r7, p) - s.Exp(g, r7, p) - cr := new(big.Int).SetBytes(hashMPIs(h, 7, s, r)) - - r.Mul(c.smp.a3, cr) - d7 := new(big.Int).Sub(r7, r) - d7.Mod(d7, q) - if d7.Sign() < 0 { - d7.Add(d7, q) - } - - c.smp.g3b = g3b - c.smp.qaqb = qaqb - - r.ModInverse(pb, p) - c.smp.papb = new(big.Int).Mul(pa, r) - c.smp.papb.Mod(c.smp.papb, p) - c.smp.ra = ra - - out.typ = tlvTypeSMP3 - out.data = appendU32(out.data, 8) - out.data = appendMPIs(out.data, pa, qa, cp, d5, d6, ra, cr, d7) - return -} - -func (c *Conversation) processSMP3(mpis []*big.Int) (out tlv, err error) { - if len(mpis) != 8 { - err = errors.New("otr: incorrect number of arguments in SMP3 message") - return - } - pa := mpis[0] - qa := mpis[1] - cp := mpis[2] - d5 := mpis[3] - d6 := mpis[4] - ra := mpis[5] - cr := mpis[6] - d7 := mpis[7] - h := sha256.New() - - r := new(big.Int).Exp(g, d5, p) - s := new(big.Int).Exp(c.smp.g2, d6, p) - r.Mul(r, s) - s.Exp(qa, cp, p) - r.Mul(r, s) - r.Mod(r, p) - - s.Exp(c.smp.g3, d5, p) - t := new(big.Int).Exp(pa, cp, p) - s.Mul(s, t) - s.Mod(s, p) - t.SetBytes(hashMPIs(h, 6, s, r)) - if t.Cmp(cp) != 0 { - err = errors.New("otr: ZKP cP failed in SMP3 message") - return - } - - r.ModInverse(c.smp.qb, p) - qaqb := new(big.Int).Mul(qa, r) - qaqb.Mod(qaqb, p) - - r.Exp(qaqb, d7, p) - s.Exp(ra, cr, p) - r.Mul(r, s) - r.Mod(r, p) - - s.Exp(g, d7, p) - t.Exp(c.smp.g3a, cr, p) - s.Mul(s, t) - s.Mod(s, p) - t.SetBytes(hashMPIs(h, 7, s, r)) - if t.Cmp(cr) != 0 { - err = errors.New("otr: ZKP cR failed in SMP3 message") - return - } - - var randBuf [16]byte - r7 := c.randMPI(randBuf[:]) - rb := new(big.Int).Exp(qaqb, c.smp.b3, p) - - r.Exp(qaqb, r7, p) - s.Exp(g, r7, p) - cr = new(big.Int).SetBytes(hashMPIs(h, 8, s, r)) - - r.Mul(c.smp.b3, cr) - d7 = new(big.Int).Sub(r7, r) - d7.Mod(d7, q) - if d7.Sign() < 0 { - d7.Add(d7, q) - } - - out.typ = tlvTypeSMP4 - out.data = appendU32(out.data, 3) - out.data = appendMPIs(out.data, rb, cr, d7) - - r.ModInverse(c.smp.pb, p) - r.Mul(pa, r) - r.Mod(r, p) - s.Exp(ra, c.smp.b3, p) - if r.Cmp(s) != 0 { - err = smpFailureError - } - - return -} - -func (c *Conversation) processSMP4(mpis []*big.Int) error { - if len(mpis) != 3 { - return errors.New("otr: incorrect number of arguments in SMP4 message") - } - rb := mpis[0] - cr := mpis[1] - d7 := mpis[2] - h := sha256.New() - - r := new(big.Int).Exp(c.smp.qaqb, d7, p) - s := new(big.Int).Exp(rb, cr, p) - r.Mul(r, s) - r.Mod(r, p) - - s.Exp(g, d7, p) - t := new(big.Int).Exp(c.smp.g3b, cr, p) - s.Mul(s, t) - s.Mod(s, p) - t.SetBytes(hashMPIs(h, 8, s, r)) - if t.Cmp(cr) != 0 { - return errors.New("otr: ZKP cR failed in SMP4 message") - } - - r.Exp(rb, c.smp.a3, p) - if r.Cmp(c.smp.papb) != 0 { - return smpFailureError - } - - return nil -} - -func (c *Conversation) generateSMPAbort() tlv { - return tlv{typ: tlvTypeSMPAbort} -} - -func hashMPIs(h hash.Hash, magic byte, mpis ...*big.Int) []byte { - if h != nil { - h.Reset() - } else { - h = sha256.New() - } - - h.Write([]byte{magic}) - for _, mpi := range mpis { - h.Write(appendMPI(nil, mpi)) - } - return h.Sum(nil) -} diff --git a/vendor/golang.org/x/crypto/pbkdf2/pbkdf2.go b/vendor/golang.org/x/crypto/pbkdf2/pbkdf2.go deleted file mode 100644 index 593f653..0000000 --- a/vendor/golang.org/x/crypto/pbkdf2/pbkdf2.go +++ /dev/null @@ -1,77 +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. - -/* -Package pbkdf2 implements the key derivation function PBKDF2 as defined in RFC -2898 / PKCS #5 v2.0. - -A key derivation function is useful when encrypting data based on a password -or any other not-fully-random data. It uses a pseudorandom function to derive -a secure encryption key based on the password. - -While v2.0 of the standard defines only one pseudorandom function to use, -HMAC-SHA1, the drafted v2.1 specification allows use of all five FIPS Approved -Hash Functions SHA-1, SHA-224, SHA-256, SHA-384 and SHA-512 for HMAC. To -choose, you can pass the `New` functions from the different SHA packages to -pbkdf2.Key. -*/ -package pbkdf2 // import "golang.org/x/crypto/pbkdf2" - -import ( - "crypto/hmac" - "hash" -) - -// Key derives a key from the password, salt and iteration count, returning a -// []byte of length keylen that can be used as cryptographic key. The key is -// derived based on the method described as PBKDF2 with the HMAC variant using -// the supplied hash function. -// -// For example, to use a HMAC-SHA-1 based PBKDF2 key derivation function, you -// can get a derived key for e.g. AES-256 (which needs a 32-byte key) by -// doing: -// -// dk := pbkdf2.Key([]byte("some password"), salt, 4096, 32, sha1.New) -// -// Remember to get a good random salt. At least 8 bytes is recommended by the -// RFC. -// -// Using a higher iteration count will increase the cost of an exhaustive -// search but will also make derivation proportionally slower. -func Key(password, salt []byte, iter, keyLen int, h func() hash.Hash) []byte { - prf := hmac.New(h, password) - hashLen := prf.Size() - numBlocks := (keyLen + hashLen - 1) / hashLen - - var buf [4]byte - dk := make([]byte, 0, numBlocks*hashLen) - U := make([]byte, hashLen) - for block := 1; block <= numBlocks; block++ { - // N.B.: || means concatenation, ^ means XOR - // for each block T_i = U_1 ^ U_2 ^ ... ^ U_iter - // U_1 = PRF(password, salt || uint(i)) - prf.Reset() - prf.Write(salt) - buf[0] = byte(block >> 24) - buf[1] = byte(block >> 16) - buf[2] = byte(block >> 8) - buf[3] = byte(block) - prf.Write(buf[:4]) - dk = prf.Sum(dk) - T := dk[len(dk)-hashLen:] - copy(U, T) - - // U_n = PRF(password, U_(n-1)) - for n := 2; n <= iter; n++ { - prf.Reset() - prf.Write(U) - U = U[:0] - U = prf.Sum(U) - for x := range U { - T[x] ^= U[x] - } - } - } - return dk[:keyLen] -} diff --git a/vendor/golang.org/x/crypto/pbkdf2/pbkdf2_test.go b/vendor/golang.org/x/crypto/pbkdf2/pbkdf2_test.go deleted file mode 100644 index 1379240..0000000 --- a/vendor/golang.org/x/crypto/pbkdf2/pbkdf2_test.go +++ /dev/null @@ -1,157 +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. - -package pbkdf2 - -import ( - "bytes" - "crypto/sha1" - "crypto/sha256" - "hash" - "testing" -) - -type testVector struct { - password string - salt string - iter int - output []byte -} - -// Test vectors from RFC 6070, http://tools.ietf.org/html/rfc6070 -var sha1TestVectors = []testVector{ - { - "password", - "salt", - 1, - []byte{ - 0x0c, 0x60, 0xc8, 0x0f, 0x96, 0x1f, 0x0e, 0x71, - 0xf3, 0xa9, 0xb5, 0x24, 0xaf, 0x60, 0x12, 0x06, - 0x2f, 0xe0, 0x37, 0xa6, - }, - }, - { - "password", - "salt", - 2, - []byte{ - 0xea, 0x6c, 0x01, 0x4d, 0xc7, 0x2d, 0x6f, 0x8c, - 0xcd, 0x1e, 0xd9, 0x2a, 0xce, 0x1d, 0x41, 0xf0, - 0xd8, 0xde, 0x89, 0x57, - }, - }, - { - "password", - "salt", - 4096, - []byte{ - 0x4b, 0x00, 0x79, 0x01, 0xb7, 0x65, 0x48, 0x9a, - 0xbe, 0xad, 0x49, 0xd9, 0x26, 0xf7, 0x21, 0xd0, - 0x65, 0xa4, 0x29, 0xc1, - }, - }, - // // This one takes too long - // { - // "password", - // "salt", - // 16777216, - // []byte{ - // 0xee, 0xfe, 0x3d, 0x61, 0xcd, 0x4d, 0xa4, 0xe4, - // 0xe9, 0x94, 0x5b, 0x3d, 0x6b, 0xa2, 0x15, 0x8c, - // 0x26, 0x34, 0xe9, 0x84, - // }, - // }, - { - "passwordPASSWORDpassword", - "saltSALTsaltSALTsaltSALTsaltSALTsalt", - 4096, - []byte{ - 0x3d, 0x2e, 0xec, 0x4f, 0xe4, 0x1c, 0x84, 0x9b, - 0x80, 0xc8, 0xd8, 0x36, 0x62, 0xc0, 0xe4, 0x4a, - 0x8b, 0x29, 0x1a, 0x96, 0x4c, 0xf2, 0xf0, 0x70, - 0x38, - }, - }, - { - "pass\000word", - "sa\000lt", - 4096, - []byte{ - 0x56, 0xfa, 0x6a, 0xa7, 0x55, 0x48, 0x09, 0x9d, - 0xcc, 0x37, 0xd7, 0xf0, 0x34, 0x25, 0xe0, 0xc3, - }, - }, -} - -// Test vectors from -// http://stackoverflow.com/questions/5130513/pbkdf2-hmac-sha2-test-vectors -var sha256TestVectors = []testVector{ - { - "password", - "salt", - 1, - []byte{ - 0x12, 0x0f, 0xb6, 0xcf, 0xfc, 0xf8, 0xb3, 0x2c, - 0x43, 0xe7, 0x22, 0x52, 0x56, 0xc4, 0xf8, 0x37, - 0xa8, 0x65, 0x48, 0xc9, - }, - }, - { - "password", - "salt", - 2, - []byte{ - 0xae, 0x4d, 0x0c, 0x95, 0xaf, 0x6b, 0x46, 0xd3, - 0x2d, 0x0a, 0xdf, 0xf9, 0x28, 0xf0, 0x6d, 0xd0, - 0x2a, 0x30, 0x3f, 0x8e, - }, - }, - { - "password", - "salt", - 4096, - []byte{ - 0xc5, 0xe4, 0x78, 0xd5, 0x92, 0x88, 0xc8, 0x41, - 0xaa, 0x53, 0x0d, 0xb6, 0x84, 0x5c, 0x4c, 0x8d, - 0x96, 0x28, 0x93, 0xa0, - }, - }, - { - "passwordPASSWORDpassword", - "saltSALTsaltSALTsaltSALTsaltSALTsalt", - 4096, - []byte{ - 0x34, 0x8c, 0x89, 0xdb, 0xcb, 0xd3, 0x2b, 0x2f, - 0x32, 0xd8, 0x14, 0xb8, 0x11, 0x6e, 0x84, 0xcf, - 0x2b, 0x17, 0x34, 0x7e, 0xbc, 0x18, 0x00, 0x18, - 0x1c, - }, - }, - { - "pass\000word", - "sa\000lt", - 4096, - []byte{ - 0x89, 0xb6, 0x9d, 0x05, 0x16, 0xf8, 0x29, 0x89, - 0x3c, 0x69, 0x62, 0x26, 0x65, 0x0a, 0x86, 0x87, - }, - }, -} - -func testHash(t *testing.T, h func() hash.Hash, hashName string, vectors []testVector) { - for i, v := range vectors { - o := Key([]byte(v.password), []byte(v.salt), v.iter, len(v.output), h) - if !bytes.Equal(o, v.output) { - t.Errorf("%s %d: expected %x, got %x", hashName, i, v.output, o) - } - } -} - -func TestWithHMACSHA1(t *testing.T) { - testHash(t, sha1.New, "SHA1", sha1TestVectors) -} - -func TestWithHMACSHA256(t *testing.T) { - testHash(t, sha256.New, "SHA256", sha256TestVectors) -} diff --git a/vendor/golang.org/x/crypto/pkcs12/bmp-string.go b/vendor/golang.org/x/crypto/pkcs12/bmp-string.go deleted file mode 100644 index 284d2a6..0000000 --- a/vendor/golang.org/x/crypto/pkcs12/bmp-string.go +++ /dev/null @@ -1,50 +0,0 @@ -// 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 pkcs12 - -import ( - "errors" - "unicode/utf16" -) - -// bmpString returns s encoded in UCS-2 with a zero terminator. -func bmpString(s string) ([]byte, error) { - // References: - // https://tools.ietf.org/html/rfc7292#appendix-B.1 - // http://en.wikipedia.org/wiki/Plane_(Unicode)#Basic_Multilingual_Plane - // - non-BMP characters are encoded in UTF 16 by using a surrogate pair of 16-bit codes - // EncodeRune returns 0xfffd if the rune does not need special encoding - // - the above RFC provides the info that BMPStrings are NULL terminated. - - ret := make([]byte, 0, 2*len(s)+2) - - for _, r := range s { - if t, _ := utf16.EncodeRune(r); t != 0xfffd { - return nil, errors.New("pkcs12: string contains characters that cannot be encoded in UCS-2") - } - ret = append(ret, byte(r/256), byte(r%256)) - } - - return append(ret, 0, 0), nil -} - -func decodeBMPString(bmpString []byte) (string, error) { - if len(bmpString)%2 != 0 { - return "", errors.New("pkcs12: odd-length BMP string") - } - - // strip terminator if present - if l := len(bmpString); l >= 2 && bmpString[l-1] == 0 && bmpString[l-2] == 0 { - bmpString = bmpString[:l-2] - } - - s := make([]uint16, 0, len(bmpString)/2) - for len(bmpString) > 0 { - s = append(s, uint16(bmpString[0])<<8+uint16(bmpString[1])) - bmpString = bmpString[2:] - } - - return string(utf16.Decode(s)), nil -} diff --git a/vendor/golang.org/x/crypto/pkcs12/bmp-string_test.go b/vendor/golang.org/x/crypto/pkcs12/bmp-string_test.go deleted file mode 100644 index 7fca55f..0000000 --- a/vendor/golang.org/x/crypto/pkcs12/bmp-string_test.go +++ /dev/null @@ -1,63 +0,0 @@ -// 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 pkcs12 - -import ( - "bytes" - "encoding/hex" - "testing" -) - -var bmpStringTests = []struct { - in string - expectedHex string - shouldFail bool -}{ - {"", "0000", false}, - // Example from https://tools.ietf.org/html/rfc7292#appendix-B. - {"Beavis", "0042006500610076006900730000", false}, - // Some characters from the "Letterlike Symbols Unicode block". - {"\u2115 - Double-struck N", "21150020002d00200044006f00750062006c0065002d00730074007200750063006b0020004e0000", false}, - // any character outside the BMP should trigger an error. - {"\U0001f000 East wind (Mahjong)", "", true}, -} - -func TestBMPString(t *testing.T) { - for i, test := range bmpStringTests { - expected, err := hex.DecodeString(test.expectedHex) - if err != nil { - t.Fatalf("#%d: failed to decode expectation", i) - } - - out, err := bmpString(test.in) - if err == nil && test.shouldFail { - t.Errorf("#%d: expected to fail, but produced %x", i, out) - continue - } - - if err != nil && !test.shouldFail { - t.Errorf("#%d: failed unexpectedly: %s", i, err) - continue - } - - if !test.shouldFail { - if !bytes.Equal(out, expected) { - t.Errorf("#%d: expected %s, got %x", i, test.expectedHex, out) - continue - } - - roundTrip, err := decodeBMPString(out) - if err != nil { - t.Errorf("#%d: decoding output gave an error: %s", i, err) - continue - } - - if roundTrip != test.in { - t.Errorf("#%d: decoding output resulted in %q, but it should have been %q", i, roundTrip, test.in) - continue - } - } - } -} diff --git a/vendor/golang.org/x/crypto/pkcs12/crypto.go b/vendor/golang.org/x/crypto/pkcs12/crypto.go deleted file mode 100644 index 4bd4470..0000000 --- a/vendor/golang.org/x/crypto/pkcs12/crypto.go +++ /dev/null @@ -1,131 +0,0 @@ -// 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 pkcs12 - -import ( - "bytes" - "crypto/cipher" - "crypto/des" - "crypto/x509/pkix" - "encoding/asn1" - "errors" - - "golang.org/x/crypto/pkcs12/internal/rc2" -) - -var ( - oidPBEWithSHAAnd3KeyTripleDESCBC = asn1.ObjectIdentifier([]int{1, 2, 840, 113549, 1, 12, 1, 3}) - oidPBEWithSHAAnd40BitRC2CBC = asn1.ObjectIdentifier([]int{1, 2, 840, 113549, 1, 12, 1, 6}) -) - -// pbeCipher is an abstraction of a PKCS#12 cipher. -type pbeCipher interface { - // create returns a cipher.Block given a key. - create(key []byte) (cipher.Block, error) - // deriveKey returns a key derived from the given password and salt. - deriveKey(salt, password []byte, iterations int) []byte - // deriveKey returns an IV derived from the given password and salt. - deriveIV(salt, password []byte, iterations int) []byte -} - -type shaWithTripleDESCBC struct{} - -func (shaWithTripleDESCBC) create(key []byte) (cipher.Block, error) { - return des.NewTripleDESCipher(key) -} - -func (shaWithTripleDESCBC) deriveKey(salt, password []byte, iterations int) []byte { - return pbkdf(sha1Sum, 20, 64, salt, password, iterations, 1, 24) -} - -func (shaWithTripleDESCBC) deriveIV(salt, password []byte, iterations int) []byte { - return pbkdf(sha1Sum, 20, 64, salt, password, iterations, 2, 8) -} - -type shaWith40BitRC2CBC struct{} - -func (shaWith40BitRC2CBC) create(key []byte) (cipher.Block, error) { - return rc2.New(key, len(key)*8) -} - -func (shaWith40BitRC2CBC) deriveKey(salt, password []byte, iterations int) []byte { - return pbkdf(sha1Sum, 20, 64, salt, password, iterations, 1, 5) -} - -func (shaWith40BitRC2CBC) deriveIV(salt, password []byte, iterations int) []byte { - return pbkdf(sha1Sum, 20, 64, salt, password, iterations, 2, 8) -} - -type pbeParams struct { - Salt []byte - Iterations int -} - -func pbDecrypterFor(algorithm pkix.AlgorithmIdentifier, password []byte) (cipher.BlockMode, int, error) { - var cipherType pbeCipher - - switch { - case algorithm.Algorithm.Equal(oidPBEWithSHAAnd3KeyTripleDESCBC): - cipherType = shaWithTripleDESCBC{} - case algorithm.Algorithm.Equal(oidPBEWithSHAAnd40BitRC2CBC): - cipherType = shaWith40BitRC2CBC{} - default: - return nil, 0, NotImplementedError("algorithm " + algorithm.Algorithm.String() + " is not supported") - } - - var params pbeParams - if err := unmarshal(algorithm.Parameters.FullBytes, ¶ms); err != nil { - return nil, 0, err - } - - key := cipherType.deriveKey(params.Salt, password, params.Iterations) - iv := cipherType.deriveIV(params.Salt, password, params.Iterations) - - block, err := cipherType.create(key) - if err != nil { - return nil, 0, err - } - - return cipher.NewCBCDecrypter(block, iv), block.BlockSize(), nil -} - -func pbDecrypt(info decryptable, password []byte) (decrypted []byte, err error) { - cbc, blockSize, err := pbDecrypterFor(info.Algorithm(), password) - if err != nil { - return nil, err - } - - encrypted := info.Data() - if len(encrypted) == 0 { - return nil, errors.New("pkcs12: empty encrypted data") - } - if len(encrypted)%blockSize != 0 { - return nil, errors.New("pkcs12: input is not a multiple of the block size") - } - decrypted = make([]byte, len(encrypted)) - cbc.CryptBlocks(decrypted, encrypted) - - psLen := int(decrypted[len(decrypted)-1]) - if psLen == 0 || psLen > blockSize { - return nil, ErrDecryption - } - - if len(decrypted) < psLen { - return nil, ErrDecryption - } - ps := decrypted[len(decrypted)-psLen:] - decrypted = decrypted[:len(decrypted)-psLen] - if bytes.Compare(ps, bytes.Repeat([]byte{byte(psLen)}, psLen)) != 0 { - return nil, ErrDecryption - } - - return -} - -// decryptable abstracts a object that contains ciphertext. -type decryptable interface { - Algorithm() pkix.AlgorithmIdentifier - Data() []byte -} diff --git a/vendor/golang.org/x/crypto/pkcs12/crypto_test.go b/vendor/golang.org/x/crypto/pkcs12/crypto_test.go deleted file mode 100644 index eb4dae8..0000000 --- a/vendor/golang.org/x/crypto/pkcs12/crypto_test.go +++ /dev/null @@ -1,125 +0,0 @@ -// 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 pkcs12 - -import ( - "bytes" - "crypto/x509/pkix" - "encoding/asn1" - "testing" -) - -var sha1WithTripleDES = asn1.ObjectIdentifier([]int{1, 2, 840, 113549, 1, 12, 1, 3}) - -func TestPbDecrypterFor(t *testing.T) { - params, _ := asn1.Marshal(pbeParams{ - Salt: []byte{1, 2, 3, 4, 5, 6, 7, 8}, - Iterations: 2048, - }) - alg := pkix.AlgorithmIdentifier{ - Algorithm: asn1.ObjectIdentifier([]int{1, 2, 3}), - Parameters: asn1.RawValue{ - FullBytes: params, - }, - } - - pass, _ := bmpString("Sesame open") - - _, _, err := pbDecrypterFor(alg, pass) - if _, ok := err.(NotImplementedError); !ok { - t.Errorf("expected not implemented error, got: %T %s", err, err) - } - - alg.Algorithm = sha1WithTripleDES - cbc, blockSize, err := pbDecrypterFor(alg, pass) - if err != nil { - t.Errorf("unexpected error from pbDecrypterFor %v", err) - } - if blockSize != 8 { - t.Errorf("unexpected block size %d, wanted 8", blockSize) - } - - plaintext := []byte{1, 2, 3, 4, 5, 6, 7, 8} - expectedCiphertext := []byte{185, 73, 135, 249, 137, 1, 122, 247} - ciphertext := make([]byte, len(plaintext)) - cbc.CryptBlocks(ciphertext, plaintext) - - if bytes.Compare(ciphertext, expectedCiphertext) != 0 { - t.Errorf("bad ciphertext, got %x but wanted %x", ciphertext, expectedCiphertext) - } -} - -var pbDecryptTests = []struct { - in []byte - expected []byte - expectedError error -}{ - { - []byte("\x33\x73\xf3\x9f\xda\x49\xae\xfc\xa0\x9a\xdf\x5a\x58\xa0\xea\x46"), // 7 padding bytes - []byte("A secret!"), - nil, - }, - { - []byte("\x33\x73\xf3\x9f\xda\x49\xae\xfc\x96\x24\x2f\x71\x7e\x32\x3f\xe7"), // 8 padding bytes - []byte("A secret"), - nil, - }, - { - []byte("\x35\x0c\xc0\x8d\xab\xa9\x5d\x30\x7f\x9a\xec\x6a\xd8\x9b\x9c\xd9"), // 9 padding bytes, incorrect - nil, - ErrDecryption, - }, - { - []byte("\xb2\xf9\x6e\x06\x60\xae\x20\xcf\x08\xa0\x7b\xd9\x6b\x20\xef\x41"), // incorrect padding bytes: [ ... 0x04 0x02 ] - nil, - ErrDecryption, - }, -} - -func TestPbDecrypt(t *testing.T) { - for i, test := range pbDecryptTests { - decryptable := testDecryptable{ - data: test.in, - algorithm: pkix.AlgorithmIdentifier{ - Algorithm: sha1WithTripleDES, - Parameters: pbeParams{ - Salt: []byte("\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8"), - Iterations: 4096, - }.RawASN1(), - }, - } - password, _ := bmpString("sesame") - - plaintext, err := pbDecrypt(decryptable, password) - if err != test.expectedError { - t.Errorf("#%d: got error %q, but wanted %q", i, err, test.expectedError) - continue - } - - if !bytes.Equal(plaintext, test.expected) { - t.Errorf("#%d: got %x, but wanted %x", i, plaintext, test.expected) - } - } -} - -type testDecryptable struct { - data []byte - algorithm pkix.AlgorithmIdentifier -} - -func (d testDecryptable) Algorithm() pkix.AlgorithmIdentifier { return d.algorithm } -func (d testDecryptable) Data() []byte { return d.data } - -func (params pbeParams) RawASN1() (raw asn1.RawValue) { - asn1Bytes, err := asn1.Marshal(params) - if err != nil { - panic(err) - } - _, err = asn1.Unmarshal(asn1Bytes, &raw) - if err != nil { - panic(err) - } - return -} diff --git a/vendor/golang.org/x/crypto/pkcs12/errors.go b/vendor/golang.org/x/crypto/pkcs12/errors.go deleted file mode 100644 index 7377ce6..0000000 --- a/vendor/golang.org/x/crypto/pkcs12/errors.go +++ /dev/null @@ -1,23 +0,0 @@ -// 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 pkcs12 - -import "errors" - -var ( - // ErrDecryption represents a failure to decrypt the input. - ErrDecryption = errors.New("pkcs12: decryption error, incorrect padding") - - // ErrIncorrectPassword is returned when an incorrect password is detected. - // Usually, P12/PFX data is signed to be able to verify the password. - ErrIncorrectPassword = errors.New("pkcs12: decryption password incorrect") -) - -// NotImplementedError indicates that the input is not currently supported. -type NotImplementedError string - -func (e NotImplementedError) Error() string { - return "pkcs12: " + string(e) -} diff --git a/vendor/golang.org/x/crypto/pkcs12/internal/rc2/bench_test.go b/vendor/golang.org/x/crypto/pkcs12/internal/rc2/bench_test.go deleted file mode 100644 index 3347f33..0000000 --- a/vendor/golang.org/x/crypto/pkcs12/internal/rc2/bench_test.go +++ /dev/null @@ -1,27 +0,0 @@ -// 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 rc2 - -import ( - "testing" -) - -func BenchmarkEncrypt(b *testing.B) { - r, _ := New([]byte{0, 0, 0, 0, 0, 0, 0, 0}, 64) - b.ResetTimer() - var src [8]byte - for i := 0; i < b.N; i++ { - r.Encrypt(src[:], src[:]) - } -} - -func BenchmarkDecrypt(b *testing.B) { - r, _ := New([]byte{0, 0, 0, 0, 0, 0, 0, 0}, 64) - b.ResetTimer() - var src [8]byte - for i := 0; i < b.N; i++ { - r.Decrypt(src[:], src[:]) - } -} diff --git a/vendor/golang.org/x/crypto/pkcs12/internal/rc2/rc2.go b/vendor/golang.org/x/crypto/pkcs12/internal/rc2/rc2.go deleted file mode 100644 index 8c70902..0000000 --- a/vendor/golang.org/x/crypto/pkcs12/internal/rc2/rc2.go +++ /dev/null @@ -1,274 +0,0 @@ -// 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 rc2 implements the RC2 cipher -/* -https://www.ietf.org/rfc/rfc2268.txt -http://people.csail.mit.edu/rivest/pubs/KRRR98.pdf - -This code is licensed under the MIT license. -*/ -package rc2 - -import ( - "crypto/cipher" - "encoding/binary" -) - -// The rc2 block size in bytes -const BlockSize = 8 - -type rc2Cipher struct { - k [64]uint16 -} - -// New returns a new rc2 cipher with the given key and effective key length t1 -func New(key []byte, t1 int) (cipher.Block, error) { - // TODO(dgryski): error checking for key length - return &rc2Cipher{ - k: expandKey(key, t1), - }, nil -} - -func (*rc2Cipher) BlockSize() int { return BlockSize } - -var piTable = [256]byte{ - 0xd9, 0x78, 0xf9, 0xc4, 0x19, 0xdd, 0xb5, 0xed, 0x28, 0xe9, 0xfd, 0x79, 0x4a, 0xa0, 0xd8, 0x9d, - 0xc6, 0x7e, 0x37, 0x83, 0x2b, 0x76, 0x53, 0x8e, 0x62, 0x4c, 0x64, 0x88, 0x44, 0x8b, 0xfb, 0xa2, - 0x17, 0x9a, 0x59, 0xf5, 0x87, 0xb3, 0x4f, 0x13, 0x61, 0x45, 0x6d, 0x8d, 0x09, 0x81, 0x7d, 0x32, - 0xbd, 0x8f, 0x40, 0xeb, 0x86, 0xb7, 0x7b, 0x0b, 0xf0, 0x95, 0x21, 0x22, 0x5c, 0x6b, 0x4e, 0x82, - 0x54, 0xd6, 0x65, 0x93, 0xce, 0x60, 0xb2, 0x1c, 0x73, 0x56, 0xc0, 0x14, 0xa7, 0x8c, 0xf1, 0xdc, - 0x12, 0x75, 0xca, 0x1f, 0x3b, 0xbe, 0xe4, 0xd1, 0x42, 0x3d, 0xd4, 0x30, 0xa3, 0x3c, 0xb6, 0x26, - 0x6f, 0xbf, 0x0e, 0xda, 0x46, 0x69, 0x07, 0x57, 0x27, 0xf2, 0x1d, 0x9b, 0xbc, 0x94, 0x43, 0x03, - 0xf8, 0x11, 0xc7, 0xf6, 0x90, 0xef, 0x3e, 0xe7, 0x06, 0xc3, 0xd5, 0x2f, 0xc8, 0x66, 0x1e, 0xd7, - 0x08, 0xe8, 0xea, 0xde, 0x80, 0x52, 0xee, 0xf7, 0x84, 0xaa, 0x72, 0xac, 0x35, 0x4d, 0x6a, 0x2a, - 0x96, 0x1a, 0xd2, 0x71, 0x5a, 0x15, 0x49, 0x74, 0x4b, 0x9f, 0xd0, 0x5e, 0x04, 0x18, 0xa4, 0xec, - 0xc2, 0xe0, 0x41, 0x6e, 0x0f, 0x51, 0xcb, 0xcc, 0x24, 0x91, 0xaf, 0x50, 0xa1, 0xf4, 0x70, 0x39, - 0x99, 0x7c, 0x3a, 0x85, 0x23, 0xb8, 0xb4, 0x7a, 0xfc, 0x02, 0x36, 0x5b, 0x25, 0x55, 0x97, 0x31, - 0x2d, 0x5d, 0xfa, 0x98, 0xe3, 0x8a, 0x92, 0xae, 0x05, 0xdf, 0x29, 0x10, 0x67, 0x6c, 0xba, 0xc9, - 0xd3, 0x00, 0xe6, 0xcf, 0xe1, 0x9e, 0xa8, 0x2c, 0x63, 0x16, 0x01, 0x3f, 0x58, 0xe2, 0x89, 0xa9, - 0x0d, 0x38, 0x34, 0x1b, 0xab, 0x33, 0xff, 0xb0, 0xbb, 0x48, 0x0c, 0x5f, 0xb9, 0xb1, 0xcd, 0x2e, - 0xc5, 0xf3, 0xdb, 0x47, 0xe5, 0xa5, 0x9c, 0x77, 0x0a, 0xa6, 0x20, 0x68, 0xfe, 0x7f, 0xc1, 0xad, -} - -func expandKey(key []byte, t1 int) [64]uint16 { - - l := make([]byte, 128) - copy(l, key) - - var t = len(key) - var t8 = (t1 + 7) / 8 - var tm = byte(255 % uint(1<<(8+uint(t1)-8*uint(t8)))) - - for i := len(key); i < 128; i++ { - l[i] = piTable[l[i-1]+l[uint8(i-t)]] - } - - l[128-t8] = piTable[l[128-t8]&tm] - - for i := 127 - t8; i >= 0; i-- { - l[i] = piTable[l[i+1]^l[i+t8]] - } - - var k [64]uint16 - - for i := range k { - k[i] = uint16(l[2*i]) + uint16(l[2*i+1])*256 - } - - return k -} - -func rotl16(x uint16, b uint) uint16 { - return (x >> (16 - b)) | (x << b) -} - -func (c *rc2Cipher) Encrypt(dst, src []byte) { - - r0 := binary.LittleEndian.Uint16(src[0:]) - r1 := binary.LittleEndian.Uint16(src[2:]) - r2 := binary.LittleEndian.Uint16(src[4:]) - r3 := binary.LittleEndian.Uint16(src[6:]) - - var j int - - for j <= 16 { - // mix r0 - r0 = r0 + c.k[j] + (r3 & r2) + ((^r3) & r1) - r0 = rotl16(r0, 1) - j++ - - // mix r1 - r1 = r1 + c.k[j] + (r0 & r3) + ((^r0) & r2) - r1 = rotl16(r1, 2) - j++ - - // mix r2 - r2 = r2 + c.k[j] + (r1 & r0) + ((^r1) & r3) - r2 = rotl16(r2, 3) - j++ - - // mix r3 - r3 = r3 + c.k[j] + (r2 & r1) + ((^r2) & r0) - r3 = rotl16(r3, 5) - j++ - - } - - r0 = r0 + c.k[r3&63] - r1 = r1 + c.k[r0&63] - r2 = r2 + c.k[r1&63] - r3 = r3 + c.k[r2&63] - - for j <= 40 { - - // mix r0 - r0 = r0 + c.k[j] + (r3 & r2) + ((^r3) & r1) - r0 = rotl16(r0, 1) - j++ - - // mix r1 - r1 = r1 + c.k[j] + (r0 & r3) + ((^r0) & r2) - r1 = rotl16(r1, 2) - j++ - - // mix r2 - r2 = r2 + c.k[j] + (r1 & r0) + ((^r1) & r3) - r2 = rotl16(r2, 3) - j++ - - // mix r3 - r3 = r3 + c.k[j] + (r2 & r1) + ((^r2) & r0) - r3 = rotl16(r3, 5) - j++ - - } - - r0 = r0 + c.k[r3&63] - r1 = r1 + c.k[r0&63] - r2 = r2 + c.k[r1&63] - r3 = r3 + c.k[r2&63] - - for j <= 60 { - - // mix r0 - r0 = r0 + c.k[j] + (r3 & r2) + ((^r3) & r1) - r0 = rotl16(r0, 1) - j++ - - // mix r1 - r1 = r1 + c.k[j] + (r0 & r3) + ((^r0) & r2) - r1 = rotl16(r1, 2) - j++ - - // mix r2 - r2 = r2 + c.k[j] + (r1 & r0) + ((^r1) & r3) - r2 = rotl16(r2, 3) - j++ - - // mix r3 - r3 = r3 + c.k[j] + (r2 & r1) + ((^r2) & r0) - r3 = rotl16(r3, 5) - j++ - } - - binary.LittleEndian.PutUint16(dst[0:], r0) - binary.LittleEndian.PutUint16(dst[2:], r1) - binary.LittleEndian.PutUint16(dst[4:], r2) - binary.LittleEndian.PutUint16(dst[6:], r3) -} - -func (c *rc2Cipher) Decrypt(dst, src []byte) { - - r0 := binary.LittleEndian.Uint16(src[0:]) - r1 := binary.LittleEndian.Uint16(src[2:]) - r2 := binary.LittleEndian.Uint16(src[4:]) - r3 := binary.LittleEndian.Uint16(src[6:]) - - j := 63 - - for j >= 44 { - // unmix r3 - r3 = rotl16(r3, 16-5) - r3 = r3 - c.k[j] - (r2 & r1) - ((^r2) & r0) - j-- - - // unmix r2 - r2 = rotl16(r2, 16-3) - r2 = r2 - c.k[j] - (r1 & r0) - ((^r1) & r3) - j-- - - // unmix r1 - r1 = rotl16(r1, 16-2) - r1 = r1 - c.k[j] - (r0 & r3) - ((^r0) & r2) - j-- - - // unmix r0 - r0 = rotl16(r0, 16-1) - r0 = r0 - c.k[j] - (r3 & r2) - ((^r3) & r1) - j-- - } - - r3 = r3 - c.k[r2&63] - r2 = r2 - c.k[r1&63] - r1 = r1 - c.k[r0&63] - r0 = r0 - c.k[r3&63] - - for j >= 20 { - // unmix r3 - r3 = rotl16(r3, 16-5) - r3 = r3 - c.k[j] - (r2 & r1) - ((^r2) & r0) - j-- - - // unmix r2 - r2 = rotl16(r2, 16-3) - r2 = r2 - c.k[j] - (r1 & r0) - ((^r1) & r3) - j-- - - // unmix r1 - r1 = rotl16(r1, 16-2) - r1 = r1 - c.k[j] - (r0 & r3) - ((^r0) & r2) - j-- - - // unmix r0 - r0 = rotl16(r0, 16-1) - r0 = r0 - c.k[j] - (r3 & r2) - ((^r3) & r1) - j-- - - } - - r3 = r3 - c.k[r2&63] - r2 = r2 - c.k[r1&63] - r1 = r1 - c.k[r0&63] - r0 = r0 - c.k[r3&63] - - for j >= 0 { - - // unmix r3 - r3 = rotl16(r3, 16-5) - r3 = r3 - c.k[j] - (r2 & r1) - ((^r2) & r0) - j-- - - // unmix r2 - r2 = rotl16(r2, 16-3) - r2 = r2 - c.k[j] - (r1 & r0) - ((^r1) & r3) - j-- - - // unmix r1 - r1 = rotl16(r1, 16-2) - r1 = r1 - c.k[j] - (r0 & r3) - ((^r0) & r2) - j-- - - // unmix r0 - r0 = rotl16(r0, 16-1) - r0 = r0 - c.k[j] - (r3 & r2) - ((^r3) & r1) - j-- - - } - - binary.LittleEndian.PutUint16(dst[0:], r0) - binary.LittleEndian.PutUint16(dst[2:], r1) - binary.LittleEndian.PutUint16(dst[4:], r2) - binary.LittleEndian.PutUint16(dst[6:], r3) -} diff --git a/vendor/golang.org/x/crypto/pkcs12/internal/rc2/rc2_test.go b/vendor/golang.org/x/crypto/pkcs12/internal/rc2/rc2_test.go deleted file mode 100644 index 8a49dfa..0000000 --- a/vendor/golang.org/x/crypto/pkcs12/internal/rc2/rc2_test.go +++ /dev/null @@ -1,93 +0,0 @@ -// 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 rc2 - -import ( - "bytes" - "encoding/hex" - "testing" -) - -func TestEncryptDecrypt(t *testing.T) { - - // TODO(dgryski): add the rest of the test vectors from the RFC - var tests = []struct { - key string - plain string - cipher string - t1 int - }{ - { - "0000000000000000", - "0000000000000000", - "ebb773f993278eff", - 63, - }, - { - "ffffffffffffffff", - "ffffffffffffffff", - "278b27e42e2f0d49", - 64, - }, - { - "3000000000000000", - "1000000000000001", - "30649edf9be7d2c2", - 64, - }, - { - "88", - "0000000000000000", - "61a8a244adacccf0", - 64, - }, - { - "88bca90e90875a", - "0000000000000000", - "6ccf4308974c267f", - 64, - }, - { - "88bca90e90875a7f0f79c384627bafb2", - "0000000000000000", - "1a807d272bbe5db1", - 64, - }, - { - "88bca90e90875a7f0f79c384627bafb2", - "0000000000000000", - "2269552ab0f85ca6", - 128, - }, - { - "88bca90e90875a7f0f79c384627bafb216f80a6f85920584c42fceb0be255daf1e", - "0000000000000000", - "5b78d3a43dfff1f1", - 129, - }, - } - - for _, tt := range tests { - k, _ := hex.DecodeString(tt.key) - p, _ := hex.DecodeString(tt.plain) - c, _ := hex.DecodeString(tt.cipher) - - b, _ := New(k, tt.t1) - - var dst [8]byte - - b.Encrypt(dst[:], p) - - if !bytes.Equal(dst[:], c) { - t.Errorf("encrypt failed: got % 2x wanted % 2x\n", dst, c) - } - - b.Decrypt(dst[:], c) - - if !bytes.Equal(dst[:], p) { - t.Errorf("decrypt failed: got % 2x wanted % 2x\n", dst, p) - } - } -} diff --git a/vendor/golang.org/x/crypto/pkcs12/mac.go b/vendor/golang.org/x/crypto/pkcs12/mac.go deleted file mode 100644 index 5f38aa7..0000000 --- a/vendor/golang.org/x/crypto/pkcs12/mac.go +++ /dev/null @@ -1,45 +0,0 @@ -// 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 pkcs12 - -import ( - "crypto/hmac" - "crypto/sha1" - "crypto/x509/pkix" - "encoding/asn1" -) - -type macData struct { - Mac digestInfo - MacSalt []byte - Iterations int `asn1:"optional,default:1"` -} - -// from PKCS#7: -type digestInfo struct { - Algorithm pkix.AlgorithmIdentifier - Digest []byte -} - -var ( - oidSHA1 = asn1.ObjectIdentifier([]int{1, 3, 14, 3, 2, 26}) -) - -func verifyMac(macData *macData, message, password []byte) error { - if !macData.Mac.Algorithm.Algorithm.Equal(oidSHA1) { - return NotImplementedError("unknown digest algorithm: " + macData.Mac.Algorithm.Algorithm.String()) - } - - key := pbkdf(sha1Sum, 20, 64, macData.MacSalt, password, macData.Iterations, 3, 20) - - mac := hmac.New(sha1.New, key) - mac.Write(message) - expectedMAC := mac.Sum(nil) - - if !hmac.Equal(macData.Mac.Digest, expectedMAC) { - return ErrIncorrectPassword - } - return nil -} diff --git a/vendor/golang.org/x/crypto/pkcs12/mac_test.go b/vendor/golang.org/x/crypto/pkcs12/mac_test.go deleted file mode 100644 index 1ed4ff2..0000000 --- a/vendor/golang.org/x/crypto/pkcs12/mac_test.go +++ /dev/null @@ -1,42 +0,0 @@ -// 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 pkcs12 - -import ( - "encoding/asn1" - "testing" -) - -func TestVerifyMac(t *testing.T) { - td := macData{ - Mac: digestInfo{ - Digest: []byte{0x18, 0x20, 0x3d, 0xff, 0x1e, 0x16, 0xf4, 0x92, 0xf2, 0xaf, 0xc8, 0x91, 0xa9, 0xba, 0xd6, 0xca, 0x9d, 0xee, 0x51, 0x93}, - }, - MacSalt: []byte{1, 2, 3, 4, 5, 6, 7, 8}, - Iterations: 2048, - } - - message := []byte{11, 12, 13, 14, 15} - password, _ := bmpString("") - - td.Mac.Algorithm.Algorithm = asn1.ObjectIdentifier([]int{1, 2, 3}) - err := verifyMac(&td, message, password) - if _, ok := err.(NotImplementedError); !ok { - t.Errorf("err: %v", err) - } - - td.Mac.Algorithm.Algorithm = asn1.ObjectIdentifier([]int{1, 3, 14, 3, 2, 26}) - err = verifyMac(&td, message, password) - if err != ErrIncorrectPassword { - t.Errorf("Expected incorrect password, got err: %v", err) - } - - password, _ = bmpString("Sesame open") - err = verifyMac(&td, message, password) - if err != nil { - t.Errorf("err: %v", err) - } - -} diff --git a/vendor/golang.org/x/crypto/pkcs12/pbkdf.go b/vendor/golang.org/x/crypto/pkcs12/pbkdf.go deleted file mode 100644 index 5c419d4..0000000 --- a/vendor/golang.org/x/crypto/pkcs12/pbkdf.go +++ /dev/null @@ -1,170 +0,0 @@ -// 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 pkcs12 - -import ( - "bytes" - "crypto/sha1" - "math/big" -) - -var ( - one = big.NewInt(1) -) - -// sha1Sum returns the SHA-1 hash of in. -func sha1Sum(in []byte) []byte { - sum := sha1.Sum(in) - return sum[:] -} - -// fillWithRepeats returns v*ceiling(len(pattern) / v) bytes consisting of -// repeats of pattern. -func fillWithRepeats(pattern []byte, v int) []byte { - if len(pattern) == 0 { - return nil - } - outputLen := v * ((len(pattern) + v - 1) / v) - return bytes.Repeat(pattern, (outputLen+len(pattern)-1)/len(pattern))[:outputLen] -} - -func pbkdf(hash func([]byte) []byte, u, v int, salt, password []byte, r int, ID byte, size int) (key []byte) { - // implementation of https://tools.ietf.org/html/rfc7292#appendix-B.2 , RFC text verbatim in comments - - // Let H be a hash function built around a compression function f: - - // Z_2^u x Z_2^v -> Z_2^u - - // (that is, H has a chaining variable and output of length u bits, and - // the message input to the compression function of H is v bits). The - // values for u and v are as follows: - - // HASH FUNCTION VALUE u VALUE v - // MD2, MD5 128 512 - // SHA-1 160 512 - // SHA-224 224 512 - // SHA-256 256 512 - // SHA-384 384 1024 - // SHA-512 512 1024 - // SHA-512/224 224 1024 - // SHA-512/256 256 1024 - - // Furthermore, let r be the iteration count. - - // We assume here that u and v are both multiples of 8, as are the - // lengths of the password and salt strings (which we denote by p and s, - // respectively) and the number n of pseudorandom bits required. In - // addition, u and v are of course non-zero. - - // For information on security considerations for MD5 [19], see [25] and - // [1], and on those for MD2, see [18]. - - // The following procedure can be used to produce pseudorandom bits for - // a particular "purpose" that is identified by a byte called "ID". - // This standard specifies 3 different values for the ID byte: - - // 1. If ID=1, then the pseudorandom bits being produced are to be used - // as key material for performing encryption or decryption. - - // 2. If ID=2, then the pseudorandom bits being produced are to be used - // as an IV (Initial Value) for encryption or decryption. - - // 3. If ID=3, then the pseudorandom bits being produced are to be used - // as an integrity key for MACing. - - // 1. Construct a string, D (the "diversifier"), by concatenating v/8 - // copies of ID. - var D []byte - for i := 0; i < v; i++ { - D = append(D, ID) - } - - // 2. Concatenate copies of the salt together to create a string S of - // length v(ceiling(s/v)) bits (the final copy of the salt may be - // truncated to create S). Note that if the salt is the empty - // string, then so is S. - - S := fillWithRepeats(salt, v) - - // 3. Concatenate copies of the password together to create a string P - // of length v(ceiling(p/v)) bits (the final copy of the password - // may be truncated to create P). Note that if the password is the - // empty string, then so is P. - - P := fillWithRepeats(password, v) - - // 4. Set I=S||P to be the concatenation of S and P. - I := append(S, P...) - - // 5. Set c=ceiling(n/u). - c := (size + u - 1) / u - - // 6. For i=1, 2, ..., c, do the following: - A := make([]byte, c*20) - var IjBuf []byte - for i := 0; i < c; i++ { - // A. Set A2=H^r(D||I). (i.e., the r-th hash of D||1, - // H(H(H(... H(D||I)))) - Ai := hash(append(D, I...)) - for j := 1; j < r; j++ { - Ai = hash(Ai) - } - copy(A[i*20:], Ai[:]) - - if i < c-1 { // skip on last iteration - // B. Concatenate copies of Ai to create a string B of length v - // bits (the final copy of Ai may be truncated to create B). - var B []byte - for len(B) < v { - B = append(B, Ai[:]...) - } - B = B[:v] - - // C. Treating I as a concatenation I_0, I_1, ..., I_(k-1) of v-bit - // blocks, where k=ceiling(s/v)+ceiling(p/v), modify I by - // setting I_j=(I_j+B+1) mod 2^v for each j. - { - Bbi := new(big.Int).SetBytes(B) - Ij := new(big.Int) - - for j := 0; j < len(I)/v; j++ { - Ij.SetBytes(I[j*v : (j+1)*v]) - Ij.Add(Ij, Bbi) - Ij.Add(Ij, one) - Ijb := Ij.Bytes() - // We expect Ijb to be exactly v bytes, - // if it is longer or shorter we must - // adjust it accordingly. - if len(Ijb) > v { - Ijb = Ijb[len(Ijb)-v:] - } - if len(Ijb) < v { - if IjBuf == nil { - IjBuf = make([]byte, v) - } - bytesShort := v - len(Ijb) - for i := 0; i < bytesShort; i++ { - IjBuf[i] = 0 - } - copy(IjBuf[bytesShort:], Ijb) - Ijb = IjBuf - } - copy(I[j*v:(j+1)*v], Ijb) - } - } - } - } - // 7. Concatenate A_1, A_2, ..., A_c together to form a pseudorandom - // bit string, A. - - // 8. Use the first n bits of A as the output of this entire process. - return A[:size] - - // If the above process is being used to generate a DES key, the process - // should be used to create 64 random bits, and the key's parity bits - // should be set after the 64 bits have been produced. Similar concerns - // hold for 2-key and 3-key triple-DES keys, for CDMF keys, and for any - // similar keys with parity bits "built into them". -} diff --git a/vendor/golang.org/x/crypto/pkcs12/pbkdf_test.go b/vendor/golang.org/x/crypto/pkcs12/pbkdf_test.go deleted file mode 100644 index 262037d..0000000 --- a/vendor/golang.org/x/crypto/pkcs12/pbkdf_test.go +++ /dev/null @@ -1,34 +0,0 @@ -// 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 pkcs12 - -import ( - "bytes" - "testing" -) - -func TestThatPBKDFWorksCorrectlyForLongKeys(t *testing.T) { - cipherInfo := shaWithTripleDESCBC{} - - salt := []byte("\xff\xff\xff\xff\xff\xff\xff\xff") - password, _ := bmpString("sesame") - key := cipherInfo.deriveKey(salt, password, 2048) - - if expected := []byte("\x7c\xd9\xfd\x3e\x2b\x3b\xe7\x69\x1a\x44\xe3\xbe\xf0\xf9\xea\x0f\xb9\xb8\x97\xd4\xe3\x25\xd9\xd1"); bytes.Compare(key, expected) != 0 { - t.Fatalf("expected key '%x', but found '%x'", expected, key) - } -} - -func TestThatPBKDFHandlesLeadingZeros(t *testing.T) { - // This test triggers a case where I_j (in step 6C) ends up with leading zero - // byte, meaning that len(Ijb) < v (leading zeros get stripped by big.Int). - // This was previously causing bug whereby certain inputs would break the - // derivation and produce the wrong output. - key := pbkdf(sha1Sum, 20, 64, []byte("\xf3\x7e\x05\xb5\x18\x32\x4b\x4b"), []byte("\x00\x00"), 2048, 1, 24) - expected := []byte("\x00\xf7\x59\xff\x47\xd1\x4d\xd0\x36\x65\xd5\x94\x3c\xb3\xc4\xa3\x9a\x25\x55\xc0\x2a\xed\x66\xe1") - if bytes.Compare(key, expected) != 0 { - t.Fatalf("expected key '%x', but found '%x'", expected, key) - } -} diff --git a/vendor/golang.org/x/crypto/pkcs12/pkcs12.go b/vendor/golang.org/x/crypto/pkcs12/pkcs12.go deleted file mode 100644 index ad6341e..0000000 --- a/vendor/golang.org/x/crypto/pkcs12/pkcs12.go +++ /dev/null @@ -1,342 +0,0 @@ -// 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 pkcs12 implements some of PKCS#12. -// -// This implementation is distilled from https://tools.ietf.org/html/rfc7292 -// and referenced documents. It is intended for decoding P12/PFX-stored -// certificates and keys for use with the crypto/tls package. -package pkcs12 - -import ( - "crypto/ecdsa" - "crypto/rsa" - "crypto/x509" - "crypto/x509/pkix" - "encoding/asn1" - "encoding/hex" - "encoding/pem" - "errors" -) - -var ( - oidDataContentType = asn1.ObjectIdentifier([]int{1, 2, 840, 113549, 1, 7, 1}) - oidEncryptedDataContentType = asn1.ObjectIdentifier([]int{1, 2, 840, 113549, 1, 7, 6}) - - oidFriendlyName = asn1.ObjectIdentifier([]int{1, 2, 840, 113549, 1, 9, 20}) - oidLocalKeyID = asn1.ObjectIdentifier([]int{1, 2, 840, 113549, 1, 9, 21}) - oidMicrosoftCSPName = asn1.ObjectIdentifier([]int{1, 3, 6, 1, 4, 1, 311, 17, 1}) -) - -type pfxPdu struct { - Version int - AuthSafe contentInfo - MacData macData `asn1:"optional"` -} - -type contentInfo struct { - ContentType asn1.ObjectIdentifier - Content asn1.RawValue `asn1:"tag:0,explicit,optional"` -} - -type encryptedData struct { - Version int - EncryptedContentInfo encryptedContentInfo -} - -type encryptedContentInfo struct { - ContentType asn1.ObjectIdentifier - ContentEncryptionAlgorithm pkix.AlgorithmIdentifier - EncryptedContent []byte `asn1:"tag:0,optional"` -} - -func (i encryptedContentInfo) Algorithm() pkix.AlgorithmIdentifier { - return i.ContentEncryptionAlgorithm -} - -func (i encryptedContentInfo) Data() []byte { return i.EncryptedContent } - -type safeBag struct { - Id asn1.ObjectIdentifier - Value asn1.RawValue `asn1:"tag:0,explicit"` - Attributes []pkcs12Attribute `asn1:"set,optional"` -} - -type pkcs12Attribute struct { - Id asn1.ObjectIdentifier - Value asn1.RawValue `asn1:"set"` -} - -type encryptedPrivateKeyInfo struct { - AlgorithmIdentifier pkix.AlgorithmIdentifier - EncryptedData []byte -} - -func (i encryptedPrivateKeyInfo) Algorithm() pkix.AlgorithmIdentifier { - return i.AlgorithmIdentifier -} - -func (i encryptedPrivateKeyInfo) Data() []byte { - return i.EncryptedData -} - -// PEM block types -const ( - certificateType = "CERTIFICATE" - privateKeyType = "PRIVATE KEY" -) - -// unmarshal calls asn1.Unmarshal, but also returns an error if there is any -// trailing data after unmarshaling. -func unmarshal(in []byte, out interface{}) error { - trailing, err := asn1.Unmarshal(in, out) - if err != nil { - return err - } - if len(trailing) != 0 { - return errors.New("pkcs12: trailing data found") - } - return nil -} - -// ConvertToPEM converts all "safe bags" contained in pfxData to PEM blocks. -func ToPEM(pfxData []byte, password string) ([]*pem.Block, error) { - encodedPassword, err := bmpString(password) - if err != nil { - return nil, ErrIncorrectPassword - } - - bags, encodedPassword, err := getSafeContents(pfxData, encodedPassword) - - blocks := make([]*pem.Block, 0, len(bags)) - for _, bag := range bags { - block, err := convertBag(&bag, encodedPassword) - if err != nil { - return nil, err - } - blocks = append(blocks, block) - } - - return blocks, nil -} - -func convertBag(bag *safeBag, password []byte) (*pem.Block, error) { - block := &pem.Block{ - Headers: make(map[string]string), - } - - for _, attribute := range bag.Attributes { - k, v, err := convertAttribute(&attribute) - if err != nil { - return nil, err - } - block.Headers[k] = v - } - - switch { - case bag.Id.Equal(oidCertBag): - block.Type = certificateType - certsData, err := decodeCertBag(bag.Value.Bytes) - if err != nil { - return nil, err - } - block.Bytes = certsData - case bag.Id.Equal(oidPKCS8ShroundedKeyBag): - block.Type = privateKeyType - - key, err := decodePkcs8ShroudedKeyBag(bag.Value.Bytes, password) - if err != nil { - return nil, err - } - - switch key := key.(type) { - case *rsa.PrivateKey: - block.Bytes = x509.MarshalPKCS1PrivateKey(key) - case *ecdsa.PrivateKey: - block.Bytes, err = x509.MarshalECPrivateKey(key) - if err != nil { - return nil, err - } - default: - return nil, errors.New("found unknown private key type in PKCS#8 wrapping") - } - default: - return nil, errors.New("don't know how to convert a safe bag of type " + bag.Id.String()) - } - return block, nil -} - -func convertAttribute(attribute *pkcs12Attribute) (key, value string, err error) { - isString := false - - switch { - case attribute.Id.Equal(oidFriendlyName): - key = "friendlyName" - isString = true - case attribute.Id.Equal(oidLocalKeyID): - key = "localKeyId" - case attribute.Id.Equal(oidMicrosoftCSPName): - // This key is chosen to match OpenSSL. - key = "Microsoft CSP Name" - isString = true - default: - return "", "", errors.New("pkcs12: unknown attribute with OID " + attribute.Id.String()) - } - - if isString { - if err := unmarshal(attribute.Value.Bytes, &attribute.Value); err != nil { - return "", "", err - } - if value, err = decodeBMPString(attribute.Value.Bytes); err != nil { - return "", "", err - } - } else { - var id []byte - if err := unmarshal(attribute.Value.Bytes, &id); err != nil { - return "", "", err - } - value = hex.EncodeToString(id) - } - - return key, value, nil -} - -// Decode extracts a certificate and private key from pfxData. This function -// assumes that there is only one certificate and only one private key in the -// pfxData. -func Decode(pfxData []byte, password string) (privateKey interface{}, certificate *x509.Certificate, err error) { - encodedPassword, err := bmpString(password) - if err != nil { - return nil, nil, err - } - - bags, encodedPassword, err := getSafeContents(pfxData, encodedPassword) - if err != nil { - return nil, nil, err - } - - if len(bags) != 2 { - err = errors.New("pkcs12: expected exactly two safe bags in the PFX PDU") - return - } - - for _, bag := range bags { - switch { - case bag.Id.Equal(oidCertBag): - if certificate != nil { - err = errors.New("pkcs12: expected exactly one certificate bag") - } - - certsData, err := decodeCertBag(bag.Value.Bytes) - if err != nil { - return nil, nil, err - } - certs, err := x509.ParseCertificates(certsData) - if err != nil { - return nil, nil, err - } - if len(certs) != 1 { - err = errors.New("pkcs12: expected exactly one certificate in the certBag") - return nil, nil, err - } - certificate = certs[0] - - case bag.Id.Equal(oidPKCS8ShroundedKeyBag): - if privateKey != nil { - err = errors.New("pkcs12: expected exactly one key bag") - } - - if privateKey, err = decodePkcs8ShroudedKeyBag(bag.Value.Bytes, encodedPassword); err != nil { - return nil, nil, err - } - } - } - - if certificate == nil { - return nil, nil, errors.New("pkcs12: certificate missing") - } - if privateKey == nil { - return nil, nil, errors.New("pkcs12: private key missing") - } - - return -} - -func getSafeContents(p12Data, password []byte) (bags []safeBag, updatedPassword []byte, err error) { - pfx := new(pfxPdu) - if err := unmarshal(p12Data, pfx); err != nil { - return nil, nil, errors.New("pkcs12: error reading P12 data: " + err.Error()) - } - - if pfx.Version != 3 { - return nil, nil, NotImplementedError("can only decode v3 PFX PDU's") - } - - if !pfx.AuthSafe.ContentType.Equal(oidDataContentType) { - return nil, nil, NotImplementedError("only password-protected PFX is implemented") - } - - // unmarshal the explicit bytes in the content for type 'data' - if err := unmarshal(pfx.AuthSafe.Content.Bytes, &pfx.AuthSafe.Content); err != nil { - return nil, nil, err - } - - if len(pfx.MacData.Mac.Algorithm.Algorithm) == 0 { - return nil, nil, errors.New("pkcs12: no MAC in data") - } - - if err := verifyMac(&pfx.MacData, pfx.AuthSafe.Content.Bytes, password); err != nil { - if err == ErrIncorrectPassword && len(password) == 2 && password[0] == 0 && password[1] == 0 { - // some implementations use an empty byte array - // for the empty string password try one more - // time with empty-empty password - password = nil - err = verifyMac(&pfx.MacData, pfx.AuthSafe.Content.Bytes, password) - } - if err != nil { - return nil, nil, err - } - } - - var authenticatedSafe []contentInfo - if err := unmarshal(pfx.AuthSafe.Content.Bytes, &authenticatedSafe); err != nil { - return nil, nil, err - } - - if len(authenticatedSafe) != 2 { - return nil, nil, NotImplementedError("expected exactly two items in the authenticated safe") - } - - for _, ci := range authenticatedSafe { - var data []byte - - switch { - case ci.ContentType.Equal(oidDataContentType): - if err := unmarshal(ci.Content.Bytes, &data); err != nil { - return nil, nil, err - } - case ci.ContentType.Equal(oidEncryptedDataContentType): - var encryptedData encryptedData - if err := unmarshal(ci.Content.Bytes, &encryptedData); err != nil { - return nil, nil, err - } - if encryptedData.Version != 0 { - return nil, nil, NotImplementedError("only version 0 of EncryptedData is supported") - } - if data, err = pbDecrypt(encryptedData.EncryptedContentInfo, password); err != nil { - return nil, nil, err - } - default: - return nil, nil, NotImplementedError("only data and encryptedData content types are supported in authenticated safe") - } - - var safeContents []safeBag - if err := unmarshal(data, &safeContents); err != nil { - return nil, nil, err - } - bags = append(bags, safeContents...) - } - - return bags, password, nil -} diff --git a/vendor/golang.org/x/crypto/pkcs12/pkcs12_test.go b/vendor/golang.org/x/crypto/pkcs12/pkcs12_test.go deleted file mode 100644 index 14dd2a6..0000000 --- a/vendor/golang.org/x/crypto/pkcs12/pkcs12_test.go +++ /dev/null @@ -1,138 +0,0 @@ -// 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 pkcs12 - -import ( - "crypto/rsa" - "crypto/tls" - "encoding/base64" - "encoding/pem" - "testing" -) - -func TestPfx(t *testing.T) { - for commonName, base64P12 := range testdata { - p12, _ := base64.StdEncoding.DecodeString(base64P12) - - priv, cert, err := Decode(p12, "") - if err != nil { - t.Fatal(err) - } - - if err := priv.(*rsa.PrivateKey).Validate(); err != nil { - t.Errorf("error while validating private key: %v", err) - } - - if cert.Subject.CommonName != commonName { - t.Errorf("expected common name to be %q, but found %q", commonName, cert.Subject.CommonName) - } - } -} - -func TestPEM(t *testing.T) { - for commonName, base64P12 := range testdata { - p12, _ := base64.StdEncoding.DecodeString(base64P12) - - blocks, err := ToPEM(p12, "") - if err != nil { - t.Fatalf("error while converting to PEM: %s", err) - } - - var pemData []byte - for _, b := range blocks { - pemData = append(pemData, pem.EncodeToMemory(b)...) - } - - cert, err := tls.X509KeyPair(pemData, pemData) - if err != nil { - t.Errorf("err while converting to key pair: %v", err) - } - config := tls.Config{ - Certificates: []tls.Certificate{cert}, - } - config.BuildNameToCertificate() - - if _, exists := config.NameToCertificate[commonName]; !exists { - t.Errorf("did not find our cert in PEM?: %v", config.NameToCertificate) - } - } -} - -func ExampleToPEM() { - p12, _ := base64.StdEncoding.DecodeString(`MIIJzgIBAzCCCZQGCS ... CA+gwggPk==`) - - blocks, err := ToPEM(p12, "password") - if err != nil { - panic(err) - } - - var pemData []byte - for _, b := range blocks { - pemData = append(pemData, pem.EncodeToMemory(b)...) - } - - // then use PEM data for tls to construct tls certificate: - cert, err := tls.X509KeyPair(pemData, pemData) - if err != nil { - panic(err) - } - - config := &tls.Config{ - Certificates: []tls.Certificate{cert}, - } - - _ = config -} - -var testdata = map[string]string{ - // 'null' password test case - "Windows Azure Tools": `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`, - // empty string password test case - "testing@example.com": `MIIJzgIBAzCCCZQGCSqGSIb3DQEHAaCCCYUEggmBMIIJfTCCA/cGCSqGSIb3DQEHBqCCA+gwggPk -AgEAMIID3QYJKoZIhvcNAQcBMBwGCiqGSIb3DQEMAQYwDgQIIszfRGqcmPcCAggAgIIDsOZ9Eg1L -s5Wx8JhYoV3HAL4aRnkAWvTYB5NISZOgSgIQTssmt/3A7134dibTmaT/93LikkL3cTKLnQzJ4wDf -YZ1bprpVJvUqz+HFT79m27bP9zYXFrvxWBJbxjYKTSjQMgz+h8LAEpXXGajCmxMJ1oCOtdXkhhzc -LdZN6SAYgtmtyFnCdMEDskSggGuLb3fw84QEJ/Sj6FAULXunW/CPaS7Ce0TMsKmNU/jfFWj3yXXw -ro0kwjKiVLpVFlnBlHo2OoVU7hmkm59YpGhLgS7nxLD3n7nBroQ0ID1+8R01NnV9XLGoGzxMm1te -6UyTCkr5mj+kEQ8EP1Ys7g/TC411uhVWySMt/rcpkx7Vz1r9kYEAzJpONAfr6cuEVkPKrxpq4Fh0 -2fzlKBky0i/hrfIEUmngh+ERHUb/Mtv/fkv1j5w9suESbhsMLLiCXAlsP1UWMX+3bNizi3WVMEts -FM2k9byn+p8IUD/A8ULlE4kEaWeoc+2idkCNQkLGuIdGUXUFVm58se0auUkVRoRJx8x4CkMesT8j -b1H831W66YRWoEwwDQp2kK1lA2vQXxdVHWlFevMNxJeromLzj3ayiaFrfByeUXhR2S+Hpm+c0yNR -4UVU9WED2kacsZcpRm9nlEa5sr28mri5JdBrNa/K02OOhvKCxr5ZGmbOVzUQKla2z4w+Ku9k8POm -dfDNU/fGx1b5hcFWtghXe3msWVsSJrQihnN6q1ughzNiYZlJUGcHdZDRtiWwCFI0bR8h/Dmg9uO9 -4rawQQrjIRT7B8yF3UbkZyAqs8Ppb1TsMeNPHh1rxEfGVQknh/48ouJYsmtbnzugTUt3mJCXXiL+ -XcPMV6bBVAUu4aaVKSmg9+yJtY4/VKv10iw88ktv29fViIdBe3t6l/oPuvQgbQ8dqf4T8w0l/uKZ -9lS1Na9jfT1vCoS7F5TRi+tmyj1vL5kr/amEIW6xKEP6oeAMvCMtbPAzVEj38zdJ1R22FfuIBxkh -f0Zl7pdVbmzRxl/SBx9iIBJSqAvcXItiT0FIj8HxQ+0iZKqMQMiBuNWJf5pYOLWGrIyntCWwHuaQ -wrx0sTGuEL9YXLEAsBDrsvzLkx/56E4INGZFrH8G7HBdW6iGqb22IMI4GHltYSyBRKbB0gadYTyv -abPEoqww8o7/85aPSzOTJ/53ozD438Q+d0u9SyDuOb60SzCD/zPuCEd78YgtXJwBYTuUNRT27FaM -3LGMX8Hz+6yPNRnmnA2XKPn7dx/IlaqAjIs8MIIFfgYJKoZIhvcNAQcBoIIFbwSCBWswggVnMIIF -YwYLKoZIhvcNAQwKAQKgggTuMIIE6jAcBgoqhkiG9w0BDAEDMA4ECJr0cClYqOlcAgIIAASCBMhe -OQSiP2s0/46ONXcNeVAkz2ksW3u/+qorhSiskGZ0b3dFa1hhgBU2Q7JVIkc4Hf7OXaT1eVQ8oqND -uhqsNz83/kqYo70+LS8Hocj49jFgWAKrf/yQkdyP1daHa2yzlEw4mkpqOfnIORQHvYCa8nEApspZ -wVu8y6WVuLHKU67mel7db2xwstQp7PRuSAYqGjTfAylElog8ASdaqqYbYIrCXucF8iF9oVgmb/Qo -xrXshJ9aSLO4MuXlTPELmWgj07AXKSb90FKNihE+y0bWb9LPVFY1Sly3AX9PfrtkSXIZwqW3phpv -MxGxQl/R6mr1z+hlTfY9Wdpb5vlKXPKA0L0Rt8d2pOesylFi6esJoS01QgP1kJILjbrV731kvDc0 -Jsd+Oxv4BMwA7ClG8w1EAOInc/GrV1MWFGw/HeEqj3CZ/l/0jv9bwkbVeVCiIhoL6P6lVx9pXq4t -KZ0uKg/tk5TVJmG2vLcMLvezD0Yk3G2ZOMrywtmskrwoF7oAUpO9e87szoH6fEvUZlkDkPVW1NV4 -cZk3DBSQiuA3VOOg8qbo/tx/EE3H59P0axZWno2GSB0wFPWd1aj+b//tJEJHaaNR6qPRj4IWj9ru -Qbc8eRAcVWleHg8uAehSvUXlFpyMQREyrnpvMGddpiTC8N4UMrrBRhV7+UbCOWhxPCbItnInBqgl -1JpSZIP7iUtsIMdu3fEC2cdbXMTRul+4rdzUR7F9OaezV3jjvcAbDvgbK1CpyC+MJ1Mxm/iTgk9V -iUArydhlR8OniN84GyGYoYCW9O/KUwb6ASmeFOu/msx8x6kAsSQHIkKqMKv0TUR3kZnkxUvdpBGP -KTl4YCTvNGX4dYALBqrAETRDhua2KVBD/kEttDHwBNVbN2xi81+Mc7ml461aADfk0c66R/m2sjHB -2tN9+wG12OIWFQjL6wF/UfJMYamxx2zOOExiId29Opt57uYiNVLOO4ourPewHPeH0u8Gz35aero7 -lkt7cZAe1Q0038JUuE/QGlnK4lESK9UkSIQAjSaAlTsrcfwtQxB2EjoOoLhwH5mvxUEmcNGNnXUc -9xj3M5BD3zBz3Ft7G3YMMDwB1+zC2l+0UG0MGVjMVaeoy32VVNvxgX7jk22OXG1iaOB+PY9kdk+O -X+52BGSf/rD6X0EnqY7XuRPkMGgjtpZeAYxRQnFtCZgDY4wYheuxqSSpdF49yNczSPLkgB3CeCfS -+9NTKN7aC6hBbmW/8yYh6OvSiCEwY0lFS/T+7iaVxr1loE4zI1y/FFp4Pe1qfLlLttVlkygga2UU -SCunTQ8UB/M5IXWKkhMOO11dP4niWwb39Y7pCWpau7mwbXOKfRPX96cgHnQJK5uG+BesDD1oYnX0 -6frN7FOnTSHKruRIwuI8KnOQ/I+owmyz71wiv5LMQt+yM47UrEjB/EZa5X8dpEwOZvkdqL7utcyo -l0XH5kWMXdW856LL/FYftAqJIDAmtX1TXF/rbP6mPyN/IlDC0gjP84Uzd/a2UyTIWr+wk49Ek3vQ -/uDamq6QrwAxVmNh5Tset5Vhpc1e1kb7mRMZIzxSP8JcTuYd45oFKi98I8YjvueHVZce1g7OudQP -SbFQoJvdT46iBg1TTatlltpOiH2mFaxWVS0xYjAjBgkqhkiG9w0BCRUxFgQUdA9eVqvETX4an/c8 -p8SsTugkit8wOwYJKoZIhvcNAQkUMS4eLABGAHIAaQBlAG4AZABsAHkAIABuAGEAbQBlACAAZgBv -AHIAIABjAGUAcgB0MDEwITAJBgUrDgMCGgUABBRFsNz3Zd1O1GI8GTuFwCWuDOjEEwQIuBEfIcAy -HQ8CAggA`, -} diff --git a/vendor/golang.org/x/crypto/pkcs12/safebags.go b/vendor/golang.org/x/crypto/pkcs12/safebags.go deleted file mode 100644 index def1f7b..0000000 --- a/vendor/golang.org/x/crypto/pkcs12/safebags.go +++ /dev/null @@ -1,57 +0,0 @@ -// 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 pkcs12 - -import ( - "crypto/x509" - "encoding/asn1" - "errors" -) - -var ( - // see https://tools.ietf.org/html/rfc7292#appendix-D - oidCertTypeX509Certificate = asn1.ObjectIdentifier([]int{1, 2, 840, 113549, 1, 9, 22, 1}) - oidPKCS8ShroundedKeyBag = asn1.ObjectIdentifier([]int{1, 2, 840, 113549, 1, 12, 10, 1, 2}) - oidCertBag = asn1.ObjectIdentifier([]int{1, 2, 840, 113549, 1, 12, 10, 1, 3}) -) - -type certBag struct { - Id asn1.ObjectIdentifier - Data []byte `asn1:"tag:0,explicit"` -} - -func decodePkcs8ShroudedKeyBag(asn1Data, password []byte) (privateKey interface{}, err error) { - pkinfo := new(encryptedPrivateKeyInfo) - if err = unmarshal(asn1Data, pkinfo); err != nil { - return nil, errors.New("pkcs12: error decoding PKCS#8 shrouded key bag: " + err.Error()) - } - - pkData, err := pbDecrypt(pkinfo, password) - if err != nil { - return nil, errors.New("pkcs12: error decrypting PKCS#8 shrouded key bag: " + err.Error()) - } - - ret := new(asn1.RawValue) - if err = unmarshal(pkData, ret); err != nil { - return nil, errors.New("pkcs12: error unmarshaling decrypted private key: " + err.Error()) - } - - if privateKey, err = x509.ParsePKCS8PrivateKey(pkData); err != nil { - return nil, errors.New("pkcs12: error parsing PKCS#8 private key: " + err.Error()) - } - - return privateKey, nil -} - -func decodeCertBag(asn1Data []byte) (x509Certificates []byte, err error) { - bag := new(certBag) - if err := unmarshal(asn1Data, bag); err != nil { - return nil, errors.New("pkcs12: error decoding cert bag: " + err.Error()) - } - if !bag.Id.Equal(oidCertTypeX509Certificate) { - return nil, NotImplementedError("only X509 certificates are supported") - } - return bag.Data, nil -} diff --git a/vendor/golang.org/x/crypto/poly1305/const_amd64.s b/vendor/golang.org/x/crypto/poly1305/const_amd64.s deleted file mode 100644 index 8e861f3..0000000 --- a/vendor/golang.org/x/crypto/poly1305/const_amd64.s +++ /dev/null @@ -1,45 +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: http://bench.cr.yp.to/supercop.html - -// +build amd64,!gccgo,!appengine - -DATA ·SCALE(SB)/8, $0x37F4000000000000 -GLOBL ·SCALE(SB), 8, $8 -DATA ·TWO32(SB)/8, $0x41F0000000000000 -GLOBL ·TWO32(SB), 8, $8 -DATA ·TWO64(SB)/8, $0x43F0000000000000 -GLOBL ·TWO64(SB), 8, $8 -DATA ·TWO96(SB)/8, $0x45F0000000000000 -GLOBL ·TWO96(SB), 8, $8 -DATA ·ALPHA32(SB)/8, $0x45E8000000000000 -GLOBL ·ALPHA32(SB), 8, $8 -DATA ·ALPHA64(SB)/8, $0x47E8000000000000 -GLOBL ·ALPHA64(SB), 8, $8 -DATA ·ALPHA96(SB)/8, $0x49E8000000000000 -GLOBL ·ALPHA96(SB), 8, $8 -DATA ·ALPHA130(SB)/8, $0x4C08000000000000 -GLOBL ·ALPHA130(SB), 8, $8 -DATA ·DOFFSET0(SB)/8, $0x4330000000000000 -GLOBL ·DOFFSET0(SB), 8, $8 -DATA ·DOFFSET1(SB)/8, $0x4530000000000000 -GLOBL ·DOFFSET1(SB), 8, $8 -DATA ·DOFFSET2(SB)/8, $0x4730000000000000 -GLOBL ·DOFFSET2(SB), 8, $8 -DATA ·DOFFSET3(SB)/8, $0x4930000000000000 -GLOBL ·DOFFSET3(SB), 8, $8 -DATA ·DOFFSET3MINUSTWO128(SB)/8, $0x492FFFFE00000000 -GLOBL ·DOFFSET3MINUSTWO128(SB), 8, $8 -DATA ·HOFFSET0(SB)/8, $0x43300001FFFFFFFB -GLOBL ·HOFFSET0(SB), 8, $8 -DATA ·HOFFSET1(SB)/8, $0x45300001FFFFFFFE -GLOBL ·HOFFSET1(SB), 8, $8 -DATA ·HOFFSET2(SB)/8, $0x47300001FFFFFFFE -GLOBL ·HOFFSET2(SB), 8, $8 -DATA ·HOFFSET3(SB)/8, $0x49300003FFFFFFFE -GLOBL ·HOFFSET3(SB), 8, $8 -DATA ·ROUNDING(SB)/2, $0x137f -GLOBL ·ROUNDING(SB), 8, $2 diff --git a/vendor/golang.org/x/crypto/poly1305/poly1305.go b/vendor/golang.org/x/crypto/poly1305/poly1305.go deleted file mode 100644 index 4a5f826..0000000 --- a/vendor/golang.org/x/crypto/poly1305/poly1305.go +++ /dev/null @@ -1,32 +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. - -/* -Package poly1305 implements Poly1305 one-time message authentication code as specified in http://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. -*/ -package poly1305 // import "golang.org/x/crypto/poly1305" - -import "crypto/subtle" - -// TagSize is the size, in bytes, of a poly1305 authenticator. -const TagSize = 16 - -// 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 { - var tmp [16]byte - Sum(&tmp, m, key) - return subtle.ConstantTimeCompare(tmp[:], mac[:]) == 1 -} diff --git a/vendor/golang.org/x/crypto/poly1305/poly1305_amd64.s b/vendor/golang.org/x/crypto/poly1305/poly1305_amd64.s deleted file mode 100644 index f8d4ee9..0000000 --- a/vendor/golang.org/x/crypto/poly1305/poly1305_amd64.s +++ /dev/null @@ -1,497 +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: http://bench.cr.yp.to/supercop.html - -// +build amd64,!gccgo,!appengine - -// func poly1305(out *[16]byte, m *byte, mlen uint64, key *[32]key) -TEXT ·poly1305(SB),0,$224-32 - MOVQ out+0(FP),DI - MOVQ m+8(FP),SI - MOVQ mlen+16(FP),DX - MOVQ key+24(FP),CX - - MOVQ SP,R11 - MOVQ $31,R9 - NOTQ R9 - ANDQ R9,SP - ADDQ $32,SP - - MOVQ R11,32(SP) - MOVQ R12,40(SP) - MOVQ R13,48(SP) - MOVQ R14,56(SP) - MOVQ R15,64(SP) - MOVQ BX,72(SP) - MOVQ BP,80(SP) - FLDCW ·ROUNDING(SB) - MOVL 0(CX),R8 - MOVL 4(CX),R9 - MOVL 8(CX),AX - MOVL 12(CX),R10 - MOVQ DI,88(SP) - MOVQ CX,96(SP) - MOVL $0X43300000,108(SP) - MOVL $0X45300000,116(SP) - MOVL $0X47300000,124(SP) - MOVL $0X49300000,132(SP) - ANDL $0X0FFFFFFF,R8 - ANDL $0X0FFFFFFC,R9 - ANDL $0X0FFFFFFC,AX - ANDL $0X0FFFFFFC,R10 - MOVL R8,104(SP) - MOVL R9,112(SP) - MOVL AX,120(SP) - MOVL R10,128(SP) - FMOVD 104(SP), F0 - FSUBD ·DOFFSET0(SB), F0 - FMOVD 112(SP), F0 - FSUBD ·DOFFSET1(SB), F0 - FMOVD 120(SP), F0 - FSUBD ·DOFFSET2(SB), F0 - FMOVD 128(SP), F0 - FSUBD ·DOFFSET3(SB), F0 - FXCHD F0, F3 - FMOVDP F0, 136(SP) - FXCHD F0, F1 - FMOVD F0, 144(SP) - FMULD ·SCALE(SB), F0 - FMOVDP F0, 152(SP) - FMOVD F0, 160(SP) - FMULD ·SCALE(SB), F0 - FMOVDP F0, 168(SP) - FMOVD F0, 176(SP) - FMULD ·SCALE(SB), F0 - FMOVDP F0, 184(SP) - FLDZ - FLDZ - FLDZ - FLDZ - CMPQ DX,$16 - JB ADDATMOST15BYTES - INITIALATLEAST16BYTES: - MOVL 12(SI),DI - MOVL 8(SI),CX - MOVL 4(SI),R8 - MOVL 0(SI),R9 - MOVL DI,128(SP) - MOVL CX,120(SP) - MOVL R8,112(SP) - MOVL R9,104(SP) - ADDQ $16,SI - SUBQ $16,DX - FXCHD F0, F3 - FADDD 128(SP), F0 - FSUBD ·DOFFSET3MINUSTWO128(SB), F0 - FXCHD F0, F1 - FADDD 112(SP), F0 - FSUBD ·DOFFSET1(SB), F0 - FXCHD F0, F2 - FADDD 120(SP), F0 - FSUBD ·DOFFSET2(SB), F0 - FXCHD F0, F3 - FADDD 104(SP), F0 - FSUBD ·DOFFSET0(SB), F0 - CMPQ DX,$16 - JB MULTIPLYADDATMOST15BYTES - MULTIPLYADDATLEAST16BYTES: - MOVL 12(SI),DI - MOVL 8(SI),CX - MOVL 4(SI),R8 - MOVL 0(SI),R9 - MOVL DI,128(SP) - MOVL CX,120(SP) - MOVL R8,112(SP) - MOVL R9,104(SP) - ADDQ $16,SI - SUBQ $16,DX - FMOVD ·ALPHA130(SB), F0 - FADDD F2,F0 - FSUBD ·ALPHA130(SB), F0 - FSUBD F0,F2 - FMULD ·SCALE(SB), F0 - FMOVD ·ALPHA32(SB), F0 - FADDD F2,F0 - FSUBD ·ALPHA32(SB), F0 - FSUBD F0,F2 - FXCHD F0, F2 - FADDDP F0,F1 - FMOVD ·ALPHA64(SB), F0 - FADDD F4,F0 - FSUBD ·ALPHA64(SB), F0 - FSUBD F0,F4 - FMOVD ·ALPHA96(SB), F0 - FADDD F6,F0 - FSUBD ·ALPHA96(SB), F0 - FSUBD F0,F6 - FXCHD F0, F6 - FADDDP F0,F1 - FXCHD F0, F3 - FADDDP F0,F5 - FXCHD F0, F3 - FADDDP F0,F1 - FMOVD 176(SP), F0 - FMULD F3,F0 - FMOVD 160(SP), F0 - FMULD F4,F0 - FMOVD 144(SP), F0 - FMULD F5,F0 - FMOVD 136(SP), F0 - FMULDP F0,F6 - FMOVD 160(SP), F0 - FMULD F4,F0 - FADDDP F0,F3 - FMOVD 144(SP), F0 - FMULD F4,F0 - FADDDP F0,F2 - FMOVD 136(SP), F0 - FMULD F4,F0 - FADDDP F0,F1 - FMOVD 184(SP), F0 - FMULDP F0,F4 - FXCHD F0, F3 - FADDDP F0,F5 - FMOVD 144(SP), F0 - FMULD F4,F0 - FADDDP F0,F2 - FMOVD 136(SP), F0 - FMULD F4,F0 - FADDDP F0,F1 - FMOVD 184(SP), F0 - FMULD F4,F0 - FADDDP F0,F3 - FMOVD 168(SP), F0 - FMULDP F0,F4 - FXCHD F0, F3 - FADDDP F0,F4 - FMOVD 136(SP), F0 - FMULD F5,F0 - FADDDP F0,F1 - FXCHD F0, F3 - FMOVD 184(SP), F0 - FMULD F5,F0 - FADDDP F0,F3 - FXCHD F0, F1 - FMOVD 168(SP), F0 - FMULD F5,F0 - FADDDP F0,F1 - FMOVD 152(SP), F0 - FMULDP F0,F5 - FXCHD F0, F4 - FADDDP F0,F1 - CMPQ DX,$16 - FXCHD F0, F2 - FMOVD 128(SP), F0 - FSUBD ·DOFFSET3MINUSTWO128(SB), F0 - FADDDP F0,F1 - FXCHD F0, F1 - FMOVD 120(SP), F0 - FSUBD ·DOFFSET2(SB), F0 - FADDDP F0,F1 - FXCHD F0, F3 - FMOVD 112(SP), F0 - FSUBD ·DOFFSET1(SB), F0 - FADDDP F0,F1 - FXCHD F0, F2 - FMOVD 104(SP), F0 - FSUBD ·DOFFSET0(SB), F0 - FADDDP F0,F1 - JAE MULTIPLYADDATLEAST16BYTES - MULTIPLYADDATMOST15BYTES: - FMOVD ·ALPHA130(SB), F0 - FADDD F2,F0 - FSUBD ·ALPHA130(SB), F0 - FSUBD F0,F2 - FMULD ·SCALE(SB), F0 - FMOVD ·ALPHA32(SB), F0 - FADDD F2,F0 - FSUBD ·ALPHA32(SB), F0 - FSUBD F0,F2 - FMOVD ·ALPHA64(SB), F0 - FADDD F5,F0 - FSUBD ·ALPHA64(SB), F0 - FSUBD F0,F5 - FMOVD ·ALPHA96(SB), F0 - FADDD F7,F0 - FSUBD ·ALPHA96(SB), F0 - FSUBD F0,F7 - FXCHD F0, F7 - FADDDP F0,F1 - FXCHD F0, F5 - FADDDP F0,F1 - FXCHD F0, F3 - FADDDP F0,F5 - FADDDP F0,F1 - FMOVD 176(SP), F0 - FMULD F1,F0 - FMOVD 160(SP), F0 - FMULD F2,F0 - FMOVD 144(SP), F0 - FMULD F3,F0 - FMOVD 136(SP), F0 - FMULDP F0,F4 - FMOVD 160(SP), F0 - FMULD F5,F0 - FADDDP F0,F3 - FMOVD 144(SP), F0 - FMULD F5,F0 - FADDDP F0,F2 - FMOVD 136(SP), F0 - FMULD F5,F0 - FADDDP F0,F1 - FMOVD 184(SP), F0 - FMULDP F0,F5 - FXCHD F0, F4 - FADDDP F0,F3 - FMOVD 144(SP), F0 - FMULD F5,F0 - FADDDP F0,F2 - FMOVD 136(SP), F0 - FMULD F5,F0 - FADDDP F0,F1 - FMOVD 184(SP), F0 - FMULD F5,F0 - FADDDP F0,F4 - FMOVD 168(SP), F0 - FMULDP F0,F5 - FXCHD F0, F4 - FADDDP F0,F2 - FMOVD 136(SP), F0 - FMULD F5,F0 - FADDDP F0,F1 - FMOVD 184(SP), F0 - FMULD F5,F0 - FADDDP F0,F4 - FMOVD 168(SP), F0 - FMULD F5,F0 - FADDDP F0,F3 - FMOVD 152(SP), F0 - FMULDP F0,F5 - FXCHD F0, F4 - FADDDP F0,F1 - ADDATMOST15BYTES: - CMPQ DX,$0 - JE NOMOREBYTES - MOVL $0,0(SP) - MOVL $0, 4 (SP) - MOVL $0, 8 (SP) - MOVL $0, 12 (SP) - LEAQ 0(SP),DI - MOVQ DX,CX - REP; MOVSB - MOVB $1,0(DI) - MOVL 12 (SP),DI - MOVL 8 (SP),SI - MOVL 4 (SP),DX - MOVL 0(SP),CX - MOVL DI,128(SP) - MOVL SI,120(SP) - MOVL DX,112(SP) - MOVL CX,104(SP) - FXCHD F0, F3 - FADDD 128(SP), F0 - FSUBD ·DOFFSET3(SB), F0 - FXCHD F0, F2 - FADDD 120(SP), F0 - FSUBD ·DOFFSET2(SB), F0 - FXCHD F0, F1 - FADDD 112(SP), F0 - FSUBD ·DOFFSET1(SB), F0 - FXCHD F0, F3 - FADDD 104(SP), F0 - FSUBD ·DOFFSET0(SB), F0 - FMOVD ·ALPHA130(SB), F0 - FADDD F3,F0 - FSUBD ·ALPHA130(SB), F0 - FSUBD F0,F3 - FMULD ·SCALE(SB), F0 - FMOVD ·ALPHA32(SB), F0 - FADDD F2,F0 - FSUBD ·ALPHA32(SB), F0 - FSUBD F0,F2 - FMOVD ·ALPHA64(SB), F0 - FADDD F6,F0 - FSUBD ·ALPHA64(SB), F0 - FSUBD F0,F6 - FMOVD ·ALPHA96(SB), F0 - FADDD F5,F0 - FSUBD ·ALPHA96(SB), F0 - FSUBD F0,F5 - FXCHD F0, F4 - FADDDP F0,F3 - FXCHD F0, F6 - FADDDP F0,F1 - FXCHD F0, F3 - FADDDP F0,F5 - FXCHD F0, F3 - FADDDP F0,F1 - FMOVD 176(SP), F0 - FMULD F3,F0 - FMOVD 160(SP), F0 - FMULD F4,F0 - FMOVD 144(SP), F0 - FMULD F5,F0 - FMOVD 136(SP), F0 - FMULDP F0,F6 - FMOVD 160(SP), F0 - FMULD F5,F0 - FADDDP F0,F3 - FMOVD 144(SP), F0 - FMULD F5,F0 - FADDDP F0,F2 - FMOVD 136(SP), F0 - FMULD F5,F0 - FADDDP F0,F1 - FMOVD 184(SP), F0 - FMULDP F0,F5 - FXCHD F0, F4 - FADDDP F0,F5 - FMOVD 144(SP), F0 - FMULD F6,F0 - FADDDP F0,F2 - FMOVD 136(SP), F0 - FMULD F6,F0 - FADDDP F0,F1 - FMOVD 184(SP), F0 - FMULD F6,F0 - FADDDP F0,F4 - FMOVD 168(SP), F0 - FMULDP F0,F6 - FXCHD F0, F5 - FADDDP F0,F4 - FMOVD 136(SP), F0 - FMULD F2,F0 - FADDDP F0,F1 - FMOVD 184(SP), F0 - FMULD F2,F0 - FADDDP F0,F5 - FMOVD 168(SP), F0 - FMULD F2,F0 - FADDDP F0,F3 - FMOVD 152(SP), F0 - FMULDP F0,F2 - FXCHD F0, F1 - FADDDP F0,F3 - FXCHD F0, F3 - FXCHD F0, F2 - NOMOREBYTES: - MOVL $0,R10 - FMOVD ·ALPHA130(SB), F0 - FADDD F4,F0 - FSUBD ·ALPHA130(SB), F0 - FSUBD F0,F4 - FMULD ·SCALE(SB), F0 - FMOVD ·ALPHA32(SB), F0 - FADDD F2,F0 - FSUBD ·ALPHA32(SB), F0 - FSUBD F0,F2 - FMOVD ·ALPHA64(SB), F0 - FADDD F4,F0 - FSUBD ·ALPHA64(SB), F0 - FSUBD F0,F4 - FMOVD ·ALPHA96(SB), F0 - FADDD F6,F0 - FSUBD ·ALPHA96(SB), F0 - FXCHD F0, F6 - FSUBD F6,F0 - FXCHD F0, F4 - FADDDP F0,F3 - FXCHD F0, F4 - FADDDP F0,F1 - FXCHD F0, F2 - FADDDP F0,F3 - FXCHD F0, F4 - FADDDP F0,F3 - FXCHD F0, F3 - FADDD ·HOFFSET0(SB), F0 - FXCHD F0, F3 - FADDD ·HOFFSET1(SB), F0 - FXCHD F0, F1 - FADDD ·HOFFSET2(SB), F0 - FXCHD F0, F2 - FADDD ·HOFFSET3(SB), F0 - FXCHD F0, F3 - FMOVDP F0, 104(SP) - FMOVDP F0, 112(SP) - FMOVDP F0, 120(SP) - FMOVDP F0, 128(SP) - MOVL 108(SP),DI - ANDL $63,DI - MOVL 116(SP),SI - ANDL $63,SI - MOVL 124(SP),DX - ANDL $63,DX - MOVL 132(SP),CX - ANDL $63,CX - MOVL 112(SP),R8 - ADDL DI,R8 - MOVQ R8,112(SP) - MOVL 120(SP),DI - ADCL SI,DI - MOVQ DI,120(SP) - MOVL 128(SP),DI - ADCL DX,DI - MOVQ DI,128(SP) - MOVL R10,DI - ADCL CX,DI - MOVQ DI,136(SP) - MOVQ $5,DI - MOVL 104(SP),SI - ADDL SI,DI - MOVQ DI,104(SP) - MOVL R10,DI - MOVQ 112(SP),DX - ADCL DX,DI - MOVQ DI,112(SP) - MOVL R10,DI - MOVQ 120(SP),CX - ADCL CX,DI - MOVQ DI,120(SP) - MOVL R10,DI - MOVQ 128(SP),R8 - ADCL R8,DI - MOVQ DI,128(SP) - MOVQ $0XFFFFFFFC,DI - MOVQ 136(SP),R9 - ADCL R9,DI - SARL $16,DI - MOVQ DI,R9 - XORL $0XFFFFFFFF,R9 - ANDQ DI,SI - MOVQ 104(SP),AX - ANDQ R9,AX - ORQ AX,SI - ANDQ DI,DX - MOVQ 112(SP),AX - ANDQ R9,AX - ORQ AX,DX - ANDQ DI,CX - MOVQ 120(SP),AX - ANDQ R9,AX - ORQ AX,CX - ANDQ DI,R8 - MOVQ 128(SP),DI - ANDQ R9,DI - ORQ DI,R8 - MOVQ 88(SP),DI - MOVQ 96(SP),R9 - ADDL 16(R9),SI - ADCL 20(R9),DX - ADCL 24(R9),CX - ADCL 28(R9),R8 - MOVL SI,0(DI) - MOVL DX,4(DI) - MOVL CX,8(DI) - MOVL R8,12(DI) - MOVQ 32(SP),R11 - MOVQ 40(SP),R12 - MOVQ 48(SP),R13 - MOVQ 56(SP),R14 - MOVQ 64(SP),R15 - MOVQ 72(SP),BX - MOVQ 80(SP),BP - MOVQ R11,SP - RET diff --git a/vendor/golang.org/x/crypto/poly1305/poly1305_arm.s b/vendor/golang.org/x/crypto/poly1305/poly1305_arm.s deleted file mode 100644 index c153867..0000000 --- a/vendor/golang.org/x/crypto/poly1305/poly1305_arm.s +++ /dev/null @@ -1,379 +0,0 @@ -// 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. - -// This code was translated into a form compatible with 5a from the public -// domain source by Andrew Moon: github.com/floodyberry/poly1305-opt/blob/master/app/extensions/poly1305. - -// +build arm,!gccgo,!appengine - -DATA poly1305_init_constants_armv6<>+0x00(SB)/4, $0x3ffffff -DATA poly1305_init_constants_armv6<>+0x04(SB)/4, $0x3ffff03 -DATA poly1305_init_constants_armv6<>+0x08(SB)/4, $0x3ffc0ff -DATA poly1305_init_constants_armv6<>+0x0c(SB)/4, $0x3f03fff -DATA poly1305_init_constants_armv6<>+0x10(SB)/4, $0x00fffff -GLOBL poly1305_init_constants_armv6<>(SB), 8, $20 - -// Warning: the linker may use R11 to synthesize certain instructions. Please -// take care and verify that no synthetic instructions use it. - -TEXT poly1305_init_ext_armv6<>(SB),4,$-4 - MOVM.DB.W [R4-R11], (R13) - MOVM.IA.W (R1), [R2-R5] - MOVW $poly1305_init_constants_armv6<>(SB), R7 - MOVW R2, R8 - MOVW R2>>26, R9 - MOVW R3>>20, g - MOVW R4>>14, R11 - MOVW R5>>8, R12 - ORR R3<<6, R9, R9 - ORR R4<<12, g, g - ORR R5<<18, R11, R11 - MOVM.IA (R7), [R2-R6] - AND R8, R2, R2 - AND R9, R3, R3 - AND g, R4, R4 - AND R11, R5, R5 - AND R12, R6, R6 - MOVM.IA.W [R2-R6], (R0) - EOR R2, R2, R2 - EOR R3, R3, R3 - EOR R4, R4, R4 - EOR R5, R5, R5 - EOR R6, R6, R6 - MOVM.IA.W [R2-R6], (R0) - MOVM.IA.W (R1), [R2-R5] - MOVM.IA [R2-R6], (R0) - MOVM.IA.W (R13), [R4-R11] - RET - -#define MOVW_UNALIGNED(Rsrc, Rdst, Rtmp, offset) \ - MOVBU (offset+0)(Rsrc), Rtmp; \ - MOVBU Rtmp, (offset+0)(Rdst); \ - MOVBU (offset+1)(Rsrc), Rtmp; \ - MOVBU Rtmp, (offset+1)(Rdst); \ - MOVBU (offset+2)(Rsrc), Rtmp; \ - MOVBU Rtmp, (offset+2)(Rdst); \ - MOVBU (offset+3)(Rsrc), Rtmp; \ - MOVBU Rtmp, (offset+3)(Rdst) - -TEXT poly1305_blocks_armv6<>(SB),4,$-4 - MOVM.DB.W [R4, R5, R6, R7, R8, R9, g, R11, R14], (R13) - SUB $128, R13 - MOVW R0, 36(R13) - MOVW R1, 40(R13) - MOVW R2, 44(R13) - MOVW R1, R14 - MOVW R2, R12 - MOVW 56(R0), R8 - WORD $0xe1180008 // TST R8, R8 not working see issue 5921 - EOR R6, R6, R6 - MOVW.EQ $(1<<24), R6 - MOVW R6, 32(R13) - ADD $64, R13, g - MOVM.IA (R0), [R0-R9] - MOVM.IA [R0-R4], (g) - CMP $16, R12 - BLO poly1305_blocks_armv6_done -poly1305_blocks_armv6_mainloop: - WORD $0xe31e0003 // TST R14, #3 not working see issue 5921 - BEQ poly1305_blocks_armv6_mainloop_aligned - ADD $48, R13, g - MOVW_UNALIGNED(R14, g, R0, 0) - MOVW_UNALIGNED(R14, g, R0, 4) - MOVW_UNALIGNED(R14, g, R0, 8) - MOVW_UNALIGNED(R14, g, R0, 12) - MOVM.IA (g), [R0-R3] - ADD $16, R14 - B poly1305_blocks_armv6_mainloop_loaded -poly1305_blocks_armv6_mainloop_aligned: - MOVM.IA.W (R14), [R0-R3] -poly1305_blocks_armv6_mainloop_loaded: - MOVW R0>>26, g - MOVW R1>>20, R11 - MOVW R2>>14, R12 - MOVW R14, 40(R13) - MOVW R3>>8, R4 - ORR R1<<6, g, g - ORR R2<<12, R11, R11 - ORR R3<<18, R12, R12 - BIC $0xfc000000, R0, R0 - BIC $0xfc000000, g, g - MOVW 32(R13), R3 - BIC $0xfc000000, R11, R11 - BIC $0xfc000000, R12, R12 - ADD R0, R5, R5 - ADD g, R6, R6 - ORR R3, R4, R4 - ADD R11, R7, R7 - ADD $64, R13, R14 - ADD R12, R8, R8 - ADD R4, R9, R9 - MOVM.IA (R14), [R0-R4] - MULLU R4, R5, (R11, g) - MULLU R3, R5, (R14, R12) - MULALU R3, R6, (R11, g) - MULALU R2, R6, (R14, R12) - MULALU R2, R7, (R11, g) - MULALU R1, R7, (R14, R12) - ADD R4<<2, R4, R4 - ADD R3<<2, R3, R3 - MULALU R1, R8, (R11, g) - MULALU R0, R8, (R14, R12) - MULALU R0, R9, (R11, g) - MULALU R4, R9, (R14, R12) - MOVW g, 24(R13) - MOVW R11, 28(R13) - MOVW R12, 16(R13) - MOVW R14, 20(R13) - MULLU R2, R5, (R11, g) - MULLU R1, R5, (R14, R12) - MULALU R1, R6, (R11, g) - MULALU R0, R6, (R14, R12) - MULALU R0, R7, (R11, g) - MULALU R4, R7, (R14, R12) - ADD R2<<2, R2, R2 - ADD R1<<2, R1, R1 - MULALU R4, R8, (R11, g) - MULALU R3, R8, (R14, R12) - MULALU R3, R9, (R11, g) - MULALU R2, R9, (R14, R12) - MOVW g, 8(R13) - MOVW R11, 12(R13) - MOVW R12, 0(R13) - MOVW R14, w+4(SP) - MULLU R0, R5, (R11, g) - MULALU R4, R6, (R11, g) - MULALU R3, R7, (R11, g) - MULALU R2, R8, (R11, g) - MULALU R1, R9, (R11, g) - MOVM.IA (R13), [R0-R7] - MOVW g>>26, R12 - MOVW R4>>26, R14 - ORR R11<<6, R12, R12 - ORR R5<<6, R14, R14 - BIC $0xfc000000, g, g - BIC $0xfc000000, R4, R4 - ADD.S R12, R0, R0 - ADC $0, R1, R1 - ADD.S R14, R6, R6 - ADC $0, R7, R7 - MOVW R0>>26, R12 - MOVW R6>>26, R14 - ORR R1<<6, R12, R12 - ORR R7<<6, R14, R14 - BIC $0xfc000000, R0, R0 - BIC $0xfc000000, R6, R6 - ADD R14<<2, R14, R14 - ADD.S R12, R2, R2 - ADC $0, R3, R3 - ADD R14, g, g - MOVW R2>>26, R12 - MOVW g>>26, R14 - ORR R3<<6, R12, R12 - BIC $0xfc000000, g, R5 - BIC $0xfc000000, R2, R7 - ADD R12, R4, R4 - ADD R14, R0, R0 - MOVW R4>>26, R12 - BIC $0xfc000000, R4, R8 - ADD R12, R6, R9 - MOVW w+44(SP), R12 - MOVW w+40(SP), R14 - MOVW R0, R6 - CMP $32, R12 - SUB $16, R12, R12 - MOVW R12, 44(R13) - BHS poly1305_blocks_armv6_mainloop -poly1305_blocks_armv6_done: - MOVW 36(R13), R12 - MOVW R5, 20(R12) - MOVW R6, 24(R12) - MOVW R7, 28(R12) - MOVW R8, 32(R12) - MOVW R9, 36(R12) - ADD $128, R13, R13 - MOVM.IA.W (R13), [R4, R5, R6, R7, R8, R9, g, R11, R14] - RET - -#define MOVHUP_UNALIGNED(Rsrc, Rdst, Rtmp) \ - MOVBU.P 1(Rsrc), Rtmp; \ - MOVBU.P Rtmp, 1(Rdst); \ - MOVBU.P 1(Rsrc), Rtmp; \ - MOVBU.P Rtmp, 1(Rdst) - -#define MOVWP_UNALIGNED(Rsrc, Rdst, Rtmp) \ - MOVHUP_UNALIGNED(Rsrc, Rdst, Rtmp); \ - MOVHUP_UNALIGNED(Rsrc, Rdst, Rtmp) - -TEXT poly1305_finish_ext_armv6<>(SB),4,$-4 - MOVM.DB.W [R4, R5, R6, R7, R8, R9, g, R11, R14], (R13) - SUB $16, R13, R13 - MOVW R0, R5 - MOVW R1, R6 - MOVW R2, R7 - MOVW R3, R8 - AND.S R2, R2, R2 - BEQ poly1305_finish_ext_armv6_noremaining - EOR R0, R0 - MOVW R13, R9 - MOVW R0, 0(R13) - MOVW R0, 4(R13) - MOVW R0, 8(R13) - MOVW R0, 12(R13) - WORD $0xe3110003 // TST R1, #3 not working see issue 5921 - BEQ poly1305_finish_ext_armv6_aligned - WORD $0xe3120008 // TST R2, #8 not working see issue 5921 - BEQ poly1305_finish_ext_armv6_skip8 - MOVWP_UNALIGNED(R1, R9, g) - MOVWP_UNALIGNED(R1, R9, g) -poly1305_finish_ext_armv6_skip8: - WORD $0xe3120004 // TST $4, R2 not working see issue 5921 - BEQ poly1305_finish_ext_armv6_skip4 - MOVWP_UNALIGNED(R1, R9, g) -poly1305_finish_ext_armv6_skip4: - WORD $0xe3120002 // TST $2, R2 not working see issue 5921 - BEQ poly1305_finish_ext_armv6_skip2 - MOVHUP_UNALIGNED(R1, R9, g) - B poly1305_finish_ext_armv6_skip2 -poly1305_finish_ext_armv6_aligned: - WORD $0xe3120008 // TST R2, #8 not working see issue 5921 - BEQ poly1305_finish_ext_armv6_skip8_aligned - MOVM.IA.W (R1), [g-R11] - MOVM.IA.W [g-R11], (R9) -poly1305_finish_ext_armv6_skip8_aligned: - WORD $0xe3120004 // TST $4, R2 not working see issue 5921 - BEQ poly1305_finish_ext_armv6_skip4_aligned - MOVW.P 4(R1), g - MOVW.P g, 4(R9) -poly1305_finish_ext_armv6_skip4_aligned: - WORD $0xe3120002 // TST $2, R2 not working see issue 5921 - BEQ poly1305_finish_ext_armv6_skip2 - MOVHU.P 2(R1), g - MOVH.P g, 2(R9) -poly1305_finish_ext_armv6_skip2: - WORD $0xe3120001 // TST $1, R2 not working see issue 5921 - BEQ poly1305_finish_ext_armv6_skip1 - MOVBU.P 1(R1), g - MOVBU.P g, 1(R9) -poly1305_finish_ext_armv6_skip1: - MOVW $1, R11 - MOVBU R11, 0(R9) - MOVW R11, 56(R5) - MOVW R5, R0 - MOVW R13, R1 - MOVW $16, R2 - BL poly1305_blocks_armv6<>(SB) -poly1305_finish_ext_armv6_noremaining: - MOVW 20(R5), R0 - MOVW 24(R5), R1 - MOVW 28(R5), R2 - MOVW 32(R5), R3 - MOVW 36(R5), R4 - MOVW R4>>26, R12 - BIC $0xfc000000, R4, R4 - ADD R12<<2, R12, R12 - ADD R12, R0, R0 - MOVW R0>>26, R12 - BIC $0xfc000000, R0, R0 - ADD R12, R1, R1 - MOVW R1>>26, R12 - BIC $0xfc000000, R1, R1 - ADD R12, R2, R2 - MOVW R2>>26, R12 - BIC $0xfc000000, R2, R2 - ADD R12, R3, R3 - MOVW R3>>26, R12 - BIC $0xfc000000, R3, R3 - ADD R12, R4, R4 - ADD $5, R0, R6 - MOVW R6>>26, R12 - BIC $0xfc000000, R6, R6 - ADD R12, R1, R7 - MOVW R7>>26, R12 - BIC $0xfc000000, R7, R7 - ADD R12, R2, g - MOVW g>>26, R12 - BIC $0xfc000000, g, g - ADD R12, R3, R11 - MOVW $-(1<<26), R12 - ADD R11>>26, R12, R12 - BIC $0xfc000000, R11, R11 - ADD R12, R4, R14 - MOVW R14>>31, R12 - SUB $1, R12 - AND R12, R6, R6 - AND R12, R7, R7 - AND R12, g, g - AND R12, R11, R11 - AND R12, R14, R14 - MVN R12, R12 - AND R12, R0, R0 - AND R12, R1, R1 - AND R12, R2, R2 - AND R12, R3, R3 - AND R12, R4, R4 - ORR R6, R0, R0 - ORR R7, R1, R1 - ORR g, R2, R2 - ORR R11, R3, R3 - ORR R14, R4, R4 - ORR R1<<26, R0, R0 - MOVW R1>>6, R1 - ORR R2<<20, R1, R1 - MOVW R2>>12, R2 - ORR R3<<14, R2, R2 - MOVW R3>>18, R3 - ORR R4<<8, R3, R3 - MOVW 40(R5), R6 - MOVW 44(R5), R7 - MOVW 48(R5), g - MOVW 52(R5), R11 - ADD.S R6, R0, R0 - ADC.S R7, R1, R1 - ADC.S g, R2, R2 - ADC.S R11, R3, R3 - MOVM.IA [R0-R3], (R8) - MOVW R5, R12 - EOR R0, R0, R0 - EOR R1, R1, R1 - EOR R2, R2, R2 - EOR R3, R3, R3 - EOR R4, R4, R4 - EOR R5, R5, R5 - EOR R6, R6, R6 - EOR R7, R7, R7 - MOVM.IA.W [R0-R7], (R12) - MOVM.IA [R0-R7], (R12) - ADD $16, R13, R13 - MOVM.IA.W (R13), [R4, R5, R6, R7, R8, R9, g, R11, R14] - RET - -// func poly1305_auth_armv6(out *[16]byte, m *byte, mlen uint32, key *[32]key) -TEXT ·poly1305_auth_armv6(SB),0,$280-16 - MOVW out+0(FP), R4 - MOVW m+4(FP), R5 - MOVW mlen+8(FP), R6 - MOVW key+12(FP), R7 - - MOVW R13, R8 - BIC $63, R13 - SUB $64, R13, R13 - MOVW R13, R0 - MOVW R7, R1 - BL poly1305_init_ext_armv6<>(SB) - BIC.S $15, R6, R2 - BEQ poly1305_auth_armv6_noblocks - MOVW R13, R0 - MOVW R5, R1 - ADD R2, R5, R5 - SUB R2, R6, R6 - BL poly1305_blocks_armv6<>(SB) -poly1305_auth_armv6_noblocks: - MOVW R13, R0 - MOVW R5, R1 - MOVW R6, R2 - MOVW R4, R3 - BL poly1305_finish_ext_armv6<>(SB) - MOVW R8, R13 - RET diff --git a/vendor/golang.org/x/crypto/poly1305/poly1305_test.go b/vendor/golang.org/x/crypto/poly1305/poly1305_test.go deleted file mode 100644 index b3e9231..0000000 --- a/vendor/golang.org/x/crypto/poly1305/poly1305_test.go +++ /dev/null @@ -1,86 +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. - -package poly1305 - -import ( - "bytes" - "testing" - "unsafe" -) - -var testData = []struct { - in, k, correct []byte -}{ - { - []byte("Hello world!"), - []byte("this is 32-byte key for Poly1305"), - []byte{0xa6, 0xf7, 0x45, 0x00, 0x8f, 0x81, 0xc9, 0x16, 0xa2, 0x0d, 0xcc, 0x74, 0xee, 0xf2, 0xb2, 0xf0}, - }, - { - make([]byte, 32), - []byte("this is 32-byte key for Poly1305"), - []byte{0x49, 0xec, 0x78, 0x09, 0x0e, 0x48, 0x1e, 0xc6, 0xc2, 0x6b, 0x33, 0xb9, 0x1c, 0xcc, 0x03, 0x07}, - }, - { - make([]byte, 2007), - []byte("this is 32-byte key for Poly1305"), - []byte{0xda, 0x84, 0xbc, 0xab, 0x02, 0x67, 0x6c, 0x38, 0xcd, 0xb0, 0x15, 0x60, 0x42, 0x74, 0xc2, 0xaa}, - }, - { - make([]byte, 2007), - make([]byte, 32), - make([]byte, 16), - }, -} - -func testSum(t *testing.T, unaligned bool) { - var out [16]byte - var key [32]byte - - for i, v := range testData { - in := v.in - if unaligned { - in = unalignBytes(in) - } - copy(key[:], v.k) - Sum(&out, in, &key) - if !bytes.Equal(out[:], v.correct) { - t.Errorf("%d: expected %x, got %x", i, v.correct, out[:]) - } - } -} - -func TestSum(t *testing.T) { testSum(t, false) } -func TestSumUnaligned(t *testing.T) { testSum(t, true) } - -func benchmark(b *testing.B, size int, unaligned bool) { - var out [16]byte - var key [32]byte - in := make([]byte, size) - if unaligned { - in = unalignBytes(in) - } - b.SetBytes(int64(len(in))) - b.ResetTimer() - for i := 0; i < b.N; i++ { - Sum(&out, in, &key) - } -} - -func Benchmark64(b *testing.B) { benchmark(b, 64, false) } -func Benchmark1K(b *testing.B) { benchmark(b, 1024, false) } -func Benchmark64Unaligned(b *testing.B) { benchmark(b, 64, true) } -func Benchmark1KUnaligned(b *testing.B) { benchmark(b, 1024, true) } - -func unalignBytes(in []byte) []byte { - out := make([]byte, len(in)+1) - if uintptr(unsafe.Pointer(&out[0]))&(unsafe.Alignof(uint32(0))-1) == 0 { - out = out[1:] - } else { - out = out[:len(in)] - } - copy(out, in) - return out -} diff --git a/vendor/golang.org/x/crypto/poly1305/sum_amd64.go b/vendor/golang.org/x/crypto/poly1305/sum_amd64.go deleted file mode 100644 index 6775c70..0000000 --- a/vendor/golang.org/x/crypto/poly1305/sum_amd64.go +++ /dev/null @@ -1,24 +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 - -package poly1305 - -// This function is implemented in poly1305_amd64.s - -//go:noescape - -func poly1305(out *[16]byte, m *byte, mlen uint64, key *[32]byte) - -// Sum generates an authenticator for m 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) { - var mPtr *byte - if len(m) > 0 { - mPtr = &m[0] - } - poly1305(out, mPtr, uint64(len(m)), key) -} diff --git a/vendor/golang.org/x/crypto/poly1305/sum_arm.go b/vendor/golang.org/x/crypto/poly1305/sum_arm.go deleted file mode 100644 index 50b979c..0000000 --- a/vendor/golang.org/x/crypto/poly1305/sum_arm.go +++ /dev/null @@ -1,24 +0,0 @@ -// 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. - -// +build arm,!gccgo,!appengine - -package poly1305 - -// This function is implemented in poly1305_arm.s - -//go:noescape - -func poly1305_auth_armv6(out *[16]byte, m *byte, mlen uint32, key *[32]byte) - -// Sum generates an authenticator for m 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) { - var mPtr *byte - if len(m) > 0 { - mPtr = &m[0] - } - poly1305_auth_armv6(out, mPtr, uint32(len(m)), key) -} diff --git a/vendor/golang.org/x/crypto/poly1305/sum_ref.go b/vendor/golang.org/x/crypto/poly1305/sum_ref.go deleted file mode 100644 index 0b24fc7..0000000 --- a/vendor/golang.org/x/crypto/poly1305/sum_ref.go +++ /dev/null @@ -1,1531 +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,!arm gccgo appengine - -package poly1305 - -// Based on original, public domain implementation from NaCl by D. J. -// Bernstein. - -import "math" - -const ( - alpham80 = 0.00000000558793544769287109375 - alpham48 = 24.0 - alpham16 = 103079215104.0 - alpha0 = 6755399441055744.0 - alpha18 = 1770887431076116955136.0 - alpha32 = 29014219670751100192948224.0 - alpha50 = 7605903601369376408980219232256.0 - alpha64 = 124615124604835863084731911901282304.0 - alpha82 = 32667107224410092492483962313449748299776.0 - alpha96 = 535217884764734955396857238543560676143529984.0 - alpha112 = 35076039295941670036888435985190792471742381031424.0 - alpha130 = 9194973245195333150150082162901855101712434733101613056.0 - scale = 0.0000000000000000000000000000000000000036734198463196484624023016788195177431833298649127735047148490821200539357960224151611328125 - offset0 = 6755408030990331.0 - offset1 = 29014256564239239022116864.0 - offset2 = 124615283061160854719918951570079744.0 - offset3 = 535219245894202480694386063513315216128475136.0 -) - -// Sum generates an authenticator for m 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) { - r := key - s := key[16:] - var ( - y7 float64 - y6 float64 - y1 float64 - y0 float64 - y5 float64 - y4 float64 - x7 float64 - x6 float64 - x1 float64 - x0 float64 - y3 float64 - y2 float64 - x5 float64 - r3lowx0 float64 - x4 float64 - r0lowx6 float64 - x3 float64 - r3highx0 float64 - x2 float64 - r0highx6 float64 - r0lowx0 float64 - sr1lowx6 float64 - r0highx0 float64 - sr1highx6 float64 - sr3low float64 - r1lowx0 float64 - sr2lowx6 float64 - r1highx0 float64 - sr2highx6 float64 - r2lowx0 float64 - sr3lowx6 float64 - r2highx0 float64 - sr3highx6 float64 - r1highx4 float64 - r1lowx4 float64 - r0highx4 float64 - r0lowx4 float64 - sr3highx4 float64 - sr3lowx4 float64 - sr2highx4 float64 - sr2lowx4 float64 - r0lowx2 float64 - r0highx2 float64 - r1lowx2 float64 - r1highx2 float64 - r2lowx2 float64 - r2highx2 float64 - sr3lowx2 float64 - sr3highx2 float64 - z0 float64 - z1 float64 - z2 float64 - z3 float64 - m0 int64 - m1 int64 - m2 int64 - m3 int64 - m00 uint32 - m01 uint32 - m02 uint32 - m03 uint32 - m10 uint32 - m11 uint32 - m12 uint32 - m13 uint32 - m20 uint32 - m21 uint32 - m22 uint32 - m23 uint32 - m30 uint32 - m31 uint32 - m32 uint32 - m33 uint64 - lbelow2 int32 - lbelow3 int32 - lbelow4 int32 - lbelow5 int32 - lbelow6 int32 - lbelow7 int32 - lbelow8 int32 - lbelow9 int32 - lbelow10 int32 - lbelow11 int32 - lbelow12 int32 - lbelow13 int32 - lbelow14 int32 - lbelow15 int32 - s00 uint32 - s01 uint32 - s02 uint32 - s03 uint32 - s10 uint32 - s11 uint32 - s12 uint32 - s13 uint32 - s20 uint32 - s21 uint32 - s22 uint32 - s23 uint32 - s30 uint32 - s31 uint32 - s32 uint32 - s33 uint32 - bits32 uint64 - f uint64 - f0 uint64 - f1 uint64 - f2 uint64 - f3 uint64 - f4 uint64 - g uint64 - g0 uint64 - g1 uint64 - g2 uint64 - g3 uint64 - g4 uint64 - ) - - var p int32 - - l := int32(len(m)) - - r00 := uint32(r[0]) - - r01 := uint32(r[1]) - - r02 := uint32(r[2]) - r0 := int64(2151) - - r03 := uint32(r[3]) - r03 &= 15 - r0 <<= 51 - - r10 := uint32(r[4]) - r10 &= 252 - r01 <<= 8 - r0 += int64(r00) - - r11 := uint32(r[5]) - r02 <<= 16 - r0 += int64(r01) - - r12 := uint32(r[6]) - r03 <<= 24 - r0 += int64(r02) - - r13 := uint32(r[7]) - r13 &= 15 - r1 := int64(2215) - r0 += int64(r03) - - d0 := r0 - r1 <<= 51 - r2 := int64(2279) - - r20 := uint32(r[8]) - r20 &= 252 - r11 <<= 8 - r1 += int64(r10) - - r21 := uint32(r[9]) - r12 <<= 16 - r1 += int64(r11) - - r22 := uint32(r[10]) - r13 <<= 24 - r1 += int64(r12) - - r23 := uint32(r[11]) - r23 &= 15 - r2 <<= 51 - r1 += int64(r13) - - d1 := r1 - r21 <<= 8 - r2 += int64(r20) - - r30 := uint32(r[12]) - r30 &= 252 - r22 <<= 16 - r2 += int64(r21) - - r31 := uint32(r[13]) - r23 <<= 24 - r2 += int64(r22) - - r32 := uint32(r[14]) - r2 += int64(r23) - r3 := int64(2343) - - d2 := r2 - r3 <<= 51 - - r33 := uint32(r[15]) - r33 &= 15 - r31 <<= 8 - r3 += int64(r30) - - r32 <<= 16 - r3 += int64(r31) - - r33 <<= 24 - r3 += int64(r32) - - r3 += int64(r33) - h0 := alpha32 - alpha32 - - d3 := r3 - h1 := alpha32 - alpha32 - - h2 := alpha32 - alpha32 - - h3 := alpha32 - alpha32 - - h4 := alpha32 - alpha32 - - r0low := math.Float64frombits(uint64(d0)) - h5 := alpha32 - alpha32 - - r1low := math.Float64frombits(uint64(d1)) - h6 := alpha32 - alpha32 - - r2low := math.Float64frombits(uint64(d2)) - h7 := alpha32 - alpha32 - - r0low -= alpha0 - - r1low -= alpha32 - - r2low -= alpha64 - - r0high := r0low + alpha18 - - r3low := math.Float64frombits(uint64(d3)) - - r1high := r1low + alpha50 - sr1low := scale * r1low - - r2high := r2low + alpha82 - sr2low := scale * r2low - - r0high -= alpha18 - r0high_stack := r0high - - r3low -= alpha96 - - r1high -= alpha50 - r1high_stack := r1high - - sr1high := sr1low + alpham80 - - r0low -= r0high - - r2high -= alpha82 - sr3low = scale * r3low - - sr2high := sr2low + alpham48 - - r1low -= r1high - r1low_stack := r1low - - sr1high -= alpham80 - sr1high_stack := sr1high - - r2low -= r2high - r2low_stack := r2low - - sr2high -= alpham48 - sr2high_stack := sr2high - - r3high := r3low + alpha112 - r0low_stack := r0low - - sr1low -= sr1high - sr1low_stack := sr1low - - sr3high := sr3low + alpham16 - r2high_stack := r2high - - sr2low -= sr2high - sr2low_stack := sr2low - - r3high -= alpha112 - r3high_stack := r3high - - sr3high -= alpham16 - sr3high_stack := sr3high - - r3low -= r3high - r3low_stack := r3low - - sr3low -= sr3high - sr3low_stack := sr3low - - if l < 16 { - goto addatmost15bytes - } - - m00 = uint32(m[p+0]) - m0 = 2151 - - m0 <<= 51 - m1 = 2215 - m01 = uint32(m[p+1]) - - m1 <<= 51 - m2 = 2279 - m02 = uint32(m[p+2]) - - m2 <<= 51 - m3 = 2343 - m03 = uint32(m[p+3]) - - m10 = uint32(m[p+4]) - m01 <<= 8 - m0 += int64(m00) - - m11 = uint32(m[p+5]) - m02 <<= 16 - m0 += int64(m01) - - m12 = uint32(m[p+6]) - m03 <<= 24 - m0 += int64(m02) - - m13 = uint32(m[p+7]) - m3 <<= 51 - m0 += int64(m03) - - m20 = uint32(m[p+8]) - m11 <<= 8 - m1 += int64(m10) - - m21 = uint32(m[p+9]) - m12 <<= 16 - m1 += int64(m11) - - m22 = uint32(m[p+10]) - m13 <<= 24 - m1 += int64(m12) - - m23 = uint32(m[p+11]) - m1 += int64(m13) - - m30 = uint32(m[p+12]) - m21 <<= 8 - m2 += int64(m20) - - m31 = uint32(m[p+13]) - m22 <<= 16 - m2 += int64(m21) - - m32 = uint32(m[p+14]) - m23 <<= 24 - m2 += int64(m22) - - m33 = uint64(m[p+15]) - m2 += int64(m23) - - d0 = m0 - m31 <<= 8 - m3 += int64(m30) - - d1 = m1 - m32 <<= 16 - m3 += int64(m31) - - d2 = m2 - m33 += 256 - - m33 <<= 24 - m3 += int64(m32) - - m3 += int64(m33) - d3 = m3 - - p += 16 - l -= 16 - - z0 = math.Float64frombits(uint64(d0)) - - z1 = math.Float64frombits(uint64(d1)) - - z2 = math.Float64frombits(uint64(d2)) - - z3 = math.Float64frombits(uint64(d3)) - - z0 -= alpha0 - - z1 -= alpha32 - - z2 -= alpha64 - - z3 -= alpha96 - - h0 += z0 - - h1 += z1 - - h3 += z2 - - h5 += z3 - - if l < 16 { - goto multiplyaddatmost15bytes - } - -multiplyaddatleast16bytes: - - m2 = 2279 - m20 = uint32(m[p+8]) - y7 = h7 + alpha130 - - m2 <<= 51 - m3 = 2343 - m21 = uint32(m[p+9]) - y6 = h6 + alpha130 - - m3 <<= 51 - m0 = 2151 - m22 = uint32(m[p+10]) - y1 = h1 + alpha32 - - m0 <<= 51 - m1 = 2215 - m23 = uint32(m[p+11]) - y0 = h0 + alpha32 - - m1 <<= 51 - m30 = uint32(m[p+12]) - y7 -= alpha130 - - m21 <<= 8 - m2 += int64(m20) - m31 = uint32(m[p+13]) - y6 -= alpha130 - - m22 <<= 16 - m2 += int64(m21) - m32 = uint32(m[p+14]) - y1 -= alpha32 - - m23 <<= 24 - m2 += int64(m22) - m33 = uint64(m[p+15]) - y0 -= alpha32 - - m2 += int64(m23) - m00 = uint32(m[p+0]) - y5 = h5 + alpha96 - - m31 <<= 8 - m3 += int64(m30) - m01 = uint32(m[p+1]) - y4 = h4 + alpha96 - - m32 <<= 16 - m02 = uint32(m[p+2]) - x7 = h7 - y7 - y7 *= scale - - m33 += 256 - m03 = uint32(m[p+3]) - x6 = h6 - y6 - y6 *= scale - - m33 <<= 24 - m3 += int64(m31) - m10 = uint32(m[p+4]) - x1 = h1 - y1 - - m01 <<= 8 - m3 += int64(m32) - m11 = uint32(m[p+5]) - x0 = h0 - y0 - - m3 += int64(m33) - m0 += int64(m00) - m12 = uint32(m[p+6]) - y5 -= alpha96 - - m02 <<= 16 - m0 += int64(m01) - m13 = uint32(m[p+7]) - y4 -= alpha96 - - m03 <<= 24 - m0 += int64(m02) - d2 = m2 - x1 += y7 - - m0 += int64(m03) - d3 = m3 - x0 += y6 - - m11 <<= 8 - m1 += int64(m10) - d0 = m0 - x7 += y5 - - m12 <<= 16 - m1 += int64(m11) - x6 += y4 - - m13 <<= 24 - m1 += int64(m12) - y3 = h3 + alpha64 - - m1 += int64(m13) - d1 = m1 - y2 = h2 + alpha64 - - x0 += x1 - - x6 += x7 - - y3 -= alpha64 - r3low = r3low_stack - - y2 -= alpha64 - r0low = r0low_stack - - x5 = h5 - y5 - r3lowx0 = r3low * x0 - r3high = r3high_stack - - x4 = h4 - y4 - r0lowx6 = r0low * x6 - r0high = r0high_stack - - x3 = h3 - y3 - r3highx0 = r3high * x0 - sr1low = sr1low_stack - - x2 = h2 - y2 - r0highx6 = r0high * x6 - sr1high = sr1high_stack - - x5 += y3 - r0lowx0 = r0low * x0 - r1low = r1low_stack - - h6 = r3lowx0 + r0lowx6 - sr1lowx6 = sr1low * x6 - r1high = r1high_stack - - x4 += y2 - r0highx0 = r0high * x0 - sr2low = sr2low_stack - - h7 = r3highx0 + r0highx6 - sr1highx6 = sr1high * x6 - sr2high = sr2high_stack - - x3 += y1 - r1lowx0 = r1low * x0 - r2low = r2low_stack - - h0 = r0lowx0 + sr1lowx6 - sr2lowx6 = sr2low * x6 - r2high = r2high_stack - - x2 += y0 - r1highx0 = r1high * x0 - sr3low = sr3low_stack - - h1 = r0highx0 + sr1highx6 - sr2highx6 = sr2high * x6 - sr3high = sr3high_stack - - x4 += x5 - r2lowx0 = r2low * x0 - z2 = math.Float64frombits(uint64(d2)) - - h2 = r1lowx0 + sr2lowx6 - sr3lowx6 = sr3low * x6 - - x2 += x3 - r2highx0 = r2high * x0 - z3 = math.Float64frombits(uint64(d3)) - - h3 = r1highx0 + sr2highx6 - sr3highx6 = sr3high * x6 - - r1highx4 = r1high * x4 - z2 -= alpha64 - - h4 = r2lowx0 + sr3lowx6 - r1lowx4 = r1low * x4 - - r0highx4 = r0high * x4 - z3 -= alpha96 - - h5 = r2highx0 + sr3highx6 - r0lowx4 = r0low * x4 - - h7 += r1highx4 - sr3highx4 = sr3high * x4 - - h6 += r1lowx4 - sr3lowx4 = sr3low * x4 - - h5 += r0highx4 - sr2highx4 = sr2high * x4 - - h4 += r0lowx4 - sr2lowx4 = sr2low * x4 - - h3 += sr3highx4 - r0lowx2 = r0low * x2 - - h2 += sr3lowx4 - r0highx2 = r0high * x2 - - h1 += sr2highx4 - r1lowx2 = r1low * x2 - - h0 += sr2lowx4 - r1highx2 = r1high * x2 - - h2 += r0lowx2 - r2lowx2 = r2low * x2 - - h3 += r0highx2 - r2highx2 = r2high * x2 - - h4 += r1lowx2 - sr3lowx2 = sr3low * x2 - - h5 += r1highx2 - sr3highx2 = sr3high * x2 - - p += 16 - l -= 16 - h6 += r2lowx2 - - h7 += r2highx2 - - z1 = math.Float64frombits(uint64(d1)) - h0 += sr3lowx2 - - z0 = math.Float64frombits(uint64(d0)) - h1 += sr3highx2 - - z1 -= alpha32 - - z0 -= alpha0 - - h5 += z3 - - h3 += z2 - - h1 += z1 - - h0 += z0 - - if l >= 16 { - goto multiplyaddatleast16bytes - } - -multiplyaddatmost15bytes: - - y7 = h7 + alpha130 - - y6 = h6 + alpha130 - - y1 = h1 + alpha32 - - y0 = h0 + alpha32 - - y7 -= alpha130 - - y6 -= alpha130 - - y1 -= alpha32 - - y0 -= alpha32 - - y5 = h5 + alpha96 - - y4 = h4 + alpha96 - - x7 = h7 - y7 - y7 *= scale - - x6 = h6 - y6 - y6 *= scale - - x1 = h1 - y1 - - x0 = h0 - y0 - - y5 -= alpha96 - - y4 -= alpha96 - - x1 += y7 - - x0 += y6 - - x7 += y5 - - x6 += y4 - - y3 = h3 + alpha64 - - y2 = h2 + alpha64 - - x0 += x1 - - x6 += x7 - - y3 -= alpha64 - r3low = r3low_stack - - y2 -= alpha64 - r0low = r0low_stack - - x5 = h5 - y5 - r3lowx0 = r3low * x0 - r3high = r3high_stack - - x4 = h4 - y4 - r0lowx6 = r0low * x6 - r0high = r0high_stack - - x3 = h3 - y3 - r3highx0 = r3high * x0 - sr1low = sr1low_stack - - x2 = h2 - y2 - r0highx6 = r0high * x6 - sr1high = sr1high_stack - - x5 += y3 - r0lowx0 = r0low * x0 - r1low = r1low_stack - - h6 = r3lowx0 + r0lowx6 - sr1lowx6 = sr1low * x6 - r1high = r1high_stack - - x4 += y2 - r0highx0 = r0high * x0 - sr2low = sr2low_stack - - h7 = r3highx0 + r0highx6 - sr1highx6 = sr1high * x6 - sr2high = sr2high_stack - - x3 += y1 - r1lowx0 = r1low * x0 - r2low = r2low_stack - - h0 = r0lowx0 + sr1lowx6 - sr2lowx6 = sr2low * x6 - r2high = r2high_stack - - x2 += y0 - r1highx0 = r1high * x0 - sr3low = sr3low_stack - - h1 = r0highx0 + sr1highx6 - sr2highx6 = sr2high * x6 - sr3high = sr3high_stack - - x4 += x5 - r2lowx0 = r2low * x0 - - h2 = r1lowx0 + sr2lowx6 - sr3lowx6 = sr3low * x6 - - x2 += x3 - r2highx0 = r2high * x0 - - h3 = r1highx0 + sr2highx6 - sr3highx6 = sr3high * x6 - - r1highx4 = r1high * x4 - - h4 = r2lowx0 + sr3lowx6 - r1lowx4 = r1low * x4 - - r0highx4 = r0high * x4 - - h5 = r2highx0 + sr3highx6 - r0lowx4 = r0low * x4 - - h7 += r1highx4 - sr3highx4 = sr3high * x4 - - h6 += r1lowx4 - sr3lowx4 = sr3low * x4 - - h5 += r0highx4 - sr2highx4 = sr2high * x4 - - h4 += r0lowx4 - sr2lowx4 = sr2low * x4 - - h3 += sr3highx4 - r0lowx2 = r0low * x2 - - h2 += sr3lowx4 - r0highx2 = r0high * x2 - - h1 += sr2highx4 - r1lowx2 = r1low * x2 - - h0 += sr2lowx4 - r1highx2 = r1high * x2 - - h2 += r0lowx2 - r2lowx2 = r2low * x2 - - h3 += r0highx2 - r2highx2 = r2high * x2 - - h4 += r1lowx2 - sr3lowx2 = sr3low * x2 - - h5 += r1highx2 - sr3highx2 = sr3high * x2 - - h6 += r2lowx2 - - h7 += r2highx2 - - h0 += sr3lowx2 - - h1 += sr3highx2 - -addatmost15bytes: - - if l == 0 { - goto nomorebytes - } - - lbelow2 = l - 2 - - lbelow3 = l - 3 - - lbelow2 >>= 31 - lbelow4 = l - 4 - - m00 = uint32(m[p+0]) - lbelow3 >>= 31 - p += lbelow2 - - m01 = uint32(m[p+1]) - lbelow4 >>= 31 - p += lbelow3 - - m02 = uint32(m[p+2]) - p += lbelow4 - m0 = 2151 - - m03 = uint32(m[p+3]) - m0 <<= 51 - m1 = 2215 - - m0 += int64(m00) - m01 &^= uint32(lbelow2) - - m02 &^= uint32(lbelow3) - m01 -= uint32(lbelow2) - - m01 <<= 8 - m03 &^= uint32(lbelow4) - - m0 += int64(m01) - lbelow2 -= lbelow3 - - m02 += uint32(lbelow2) - lbelow3 -= lbelow4 - - m02 <<= 16 - m03 += uint32(lbelow3) - - m03 <<= 24 - m0 += int64(m02) - - m0 += int64(m03) - lbelow5 = l - 5 - - lbelow6 = l - 6 - lbelow7 = l - 7 - - lbelow5 >>= 31 - lbelow8 = l - 8 - - lbelow6 >>= 31 - p += lbelow5 - - m10 = uint32(m[p+4]) - lbelow7 >>= 31 - p += lbelow6 - - m11 = uint32(m[p+5]) - lbelow8 >>= 31 - p += lbelow7 - - m12 = uint32(m[p+6]) - m1 <<= 51 - p += lbelow8 - - m13 = uint32(m[p+7]) - m10 &^= uint32(lbelow5) - lbelow4 -= lbelow5 - - m10 += uint32(lbelow4) - lbelow5 -= lbelow6 - - m11 &^= uint32(lbelow6) - m11 += uint32(lbelow5) - - m11 <<= 8 - m1 += int64(m10) - - m1 += int64(m11) - m12 &^= uint32(lbelow7) - - lbelow6 -= lbelow7 - m13 &^= uint32(lbelow8) - - m12 += uint32(lbelow6) - lbelow7 -= lbelow8 - - m12 <<= 16 - m13 += uint32(lbelow7) - - m13 <<= 24 - m1 += int64(m12) - - m1 += int64(m13) - m2 = 2279 - - lbelow9 = l - 9 - m3 = 2343 - - lbelow10 = l - 10 - lbelow11 = l - 11 - - lbelow9 >>= 31 - lbelow12 = l - 12 - - lbelow10 >>= 31 - p += lbelow9 - - m20 = uint32(m[p+8]) - lbelow11 >>= 31 - p += lbelow10 - - m21 = uint32(m[p+9]) - lbelow12 >>= 31 - p += lbelow11 - - m22 = uint32(m[p+10]) - m2 <<= 51 - p += lbelow12 - - m23 = uint32(m[p+11]) - m20 &^= uint32(lbelow9) - lbelow8 -= lbelow9 - - m20 += uint32(lbelow8) - lbelow9 -= lbelow10 - - m21 &^= uint32(lbelow10) - m21 += uint32(lbelow9) - - m21 <<= 8 - m2 += int64(m20) - - m2 += int64(m21) - m22 &^= uint32(lbelow11) - - lbelow10 -= lbelow11 - m23 &^= uint32(lbelow12) - - m22 += uint32(lbelow10) - lbelow11 -= lbelow12 - - m22 <<= 16 - m23 += uint32(lbelow11) - - m23 <<= 24 - m2 += int64(m22) - - m3 <<= 51 - lbelow13 = l - 13 - - lbelow13 >>= 31 - lbelow14 = l - 14 - - lbelow14 >>= 31 - p += lbelow13 - lbelow15 = l - 15 - - m30 = uint32(m[p+12]) - lbelow15 >>= 31 - p += lbelow14 - - m31 = uint32(m[p+13]) - p += lbelow15 - m2 += int64(m23) - - m32 = uint32(m[p+14]) - m30 &^= uint32(lbelow13) - lbelow12 -= lbelow13 - - m30 += uint32(lbelow12) - lbelow13 -= lbelow14 - - m3 += int64(m30) - m31 &^= uint32(lbelow14) - - m31 += uint32(lbelow13) - m32 &^= uint32(lbelow15) - - m31 <<= 8 - lbelow14 -= lbelow15 - - m3 += int64(m31) - m32 += uint32(lbelow14) - d0 = m0 - - m32 <<= 16 - m33 = uint64(lbelow15 + 1) - d1 = m1 - - m33 <<= 24 - m3 += int64(m32) - d2 = m2 - - m3 += int64(m33) - d3 = m3 - - z3 = math.Float64frombits(uint64(d3)) - - z2 = math.Float64frombits(uint64(d2)) - - z1 = math.Float64frombits(uint64(d1)) - - z0 = math.Float64frombits(uint64(d0)) - - z3 -= alpha96 - - z2 -= alpha64 - - z1 -= alpha32 - - z0 -= alpha0 - - h5 += z3 - - h3 += z2 - - h1 += z1 - - h0 += z0 - - y7 = h7 + alpha130 - - y6 = h6 + alpha130 - - y1 = h1 + alpha32 - - y0 = h0 + alpha32 - - y7 -= alpha130 - - y6 -= alpha130 - - y1 -= alpha32 - - y0 -= alpha32 - - y5 = h5 + alpha96 - - y4 = h4 + alpha96 - - x7 = h7 - y7 - y7 *= scale - - x6 = h6 - y6 - y6 *= scale - - x1 = h1 - y1 - - x0 = h0 - y0 - - y5 -= alpha96 - - y4 -= alpha96 - - x1 += y7 - - x0 += y6 - - x7 += y5 - - x6 += y4 - - y3 = h3 + alpha64 - - y2 = h2 + alpha64 - - x0 += x1 - - x6 += x7 - - y3 -= alpha64 - r3low = r3low_stack - - y2 -= alpha64 - r0low = r0low_stack - - x5 = h5 - y5 - r3lowx0 = r3low * x0 - r3high = r3high_stack - - x4 = h4 - y4 - r0lowx6 = r0low * x6 - r0high = r0high_stack - - x3 = h3 - y3 - r3highx0 = r3high * x0 - sr1low = sr1low_stack - - x2 = h2 - y2 - r0highx6 = r0high * x6 - sr1high = sr1high_stack - - x5 += y3 - r0lowx0 = r0low * x0 - r1low = r1low_stack - - h6 = r3lowx0 + r0lowx6 - sr1lowx6 = sr1low * x6 - r1high = r1high_stack - - x4 += y2 - r0highx0 = r0high * x0 - sr2low = sr2low_stack - - h7 = r3highx0 + r0highx6 - sr1highx6 = sr1high * x6 - sr2high = sr2high_stack - - x3 += y1 - r1lowx0 = r1low * x0 - r2low = r2low_stack - - h0 = r0lowx0 + sr1lowx6 - sr2lowx6 = sr2low * x6 - r2high = r2high_stack - - x2 += y0 - r1highx0 = r1high * x0 - sr3low = sr3low_stack - - h1 = r0highx0 + sr1highx6 - sr2highx6 = sr2high * x6 - sr3high = sr3high_stack - - x4 += x5 - r2lowx0 = r2low * x0 - - h2 = r1lowx0 + sr2lowx6 - sr3lowx6 = sr3low * x6 - - x2 += x3 - r2highx0 = r2high * x0 - - h3 = r1highx0 + sr2highx6 - sr3highx6 = sr3high * x6 - - r1highx4 = r1high * x4 - - h4 = r2lowx0 + sr3lowx6 - r1lowx4 = r1low * x4 - - r0highx4 = r0high * x4 - - h5 = r2highx0 + sr3highx6 - r0lowx4 = r0low * x4 - - h7 += r1highx4 - sr3highx4 = sr3high * x4 - - h6 += r1lowx4 - sr3lowx4 = sr3low * x4 - - h5 += r0highx4 - sr2highx4 = sr2high * x4 - - h4 += r0lowx4 - sr2lowx4 = sr2low * x4 - - h3 += sr3highx4 - r0lowx2 = r0low * x2 - - h2 += sr3lowx4 - r0highx2 = r0high * x2 - - h1 += sr2highx4 - r1lowx2 = r1low * x2 - - h0 += sr2lowx4 - r1highx2 = r1high * x2 - - h2 += r0lowx2 - r2lowx2 = r2low * x2 - - h3 += r0highx2 - r2highx2 = r2high * x2 - - h4 += r1lowx2 - sr3lowx2 = sr3low * x2 - - h5 += r1highx2 - sr3highx2 = sr3high * x2 - - h6 += r2lowx2 - - h7 += r2highx2 - - h0 += sr3lowx2 - - h1 += sr3highx2 - -nomorebytes: - - y7 = h7 + alpha130 - - y0 = h0 + alpha32 - - y1 = h1 + alpha32 - - y2 = h2 + alpha64 - - y7 -= alpha130 - - y3 = h3 + alpha64 - - y4 = h4 + alpha96 - - y5 = h5 + alpha96 - - x7 = h7 - y7 - y7 *= scale - - y0 -= alpha32 - - y1 -= alpha32 - - y2 -= alpha64 - - h6 += x7 - - y3 -= alpha64 - - y4 -= alpha96 - - y5 -= alpha96 - - y6 = h6 + alpha130 - - x0 = h0 - y0 - - x1 = h1 - y1 - - x2 = h2 - y2 - - y6 -= alpha130 - - x0 += y7 - - x3 = h3 - y3 - - x4 = h4 - y4 - - x5 = h5 - y5 - - x6 = h6 - y6 - - y6 *= scale - - x2 += y0 - - x3 += y1 - - x4 += y2 - - x0 += y6 - - x5 += y3 - - x6 += y4 - - x2 += x3 - - x0 += x1 - - x4 += x5 - - x6 += y5 - - x2 += offset1 - d1 = int64(math.Float64bits(x2)) - - x0 += offset0 - d0 = int64(math.Float64bits(x0)) - - x4 += offset2 - d2 = int64(math.Float64bits(x4)) - - x6 += offset3 - d3 = int64(math.Float64bits(x6)) - - f0 = uint64(d0) - - f1 = uint64(d1) - bits32 = math.MaxUint64 - - f2 = uint64(d2) - bits32 >>= 32 - - f3 = uint64(d3) - f = f0 >> 32 - - f0 &= bits32 - f &= 255 - - f1 += f - g0 = f0 + 5 - - g = g0 >> 32 - g0 &= bits32 - - f = f1 >> 32 - f1 &= bits32 - - f &= 255 - g1 = f1 + g - - g = g1 >> 32 - f2 += f - - f = f2 >> 32 - g1 &= bits32 - - f2 &= bits32 - f &= 255 - - f3 += f - g2 = f2 + g - - g = g2 >> 32 - g2 &= bits32 - - f4 = f3 >> 32 - f3 &= bits32 - - f4 &= 255 - g3 = f3 + g - - g = g3 >> 32 - g3 &= bits32 - - g4 = f4 + g - - g4 = g4 - 4 - s00 = uint32(s[0]) - - f = uint64(int64(g4) >> 63) - s01 = uint32(s[1]) - - f0 &= f - g0 &^= f - s02 = uint32(s[2]) - - f1 &= f - f0 |= g0 - s03 = uint32(s[3]) - - g1 &^= f - f2 &= f - s10 = uint32(s[4]) - - f3 &= f - g2 &^= f - s11 = uint32(s[5]) - - g3 &^= f - f1 |= g1 - s12 = uint32(s[6]) - - f2 |= g2 - f3 |= g3 - s13 = uint32(s[7]) - - s01 <<= 8 - f0 += uint64(s00) - s20 = uint32(s[8]) - - s02 <<= 16 - f0 += uint64(s01) - s21 = uint32(s[9]) - - s03 <<= 24 - f0 += uint64(s02) - s22 = uint32(s[10]) - - s11 <<= 8 - f1 += uint64(s10) - s23 = uint32(s[11]) - - s12 <<= 16 - f1 += uint64(s11) - s30 = uint32(s[12]) - - s13 <<= 24 - f1 += uint64(s12) - s31 = uint32(s[13]) - - f0 += uint64(s03) - f1 += uint64(s13) - s32 = uint32(s[14]) - - s21 <<= 8 - f2 += uint64(s20) - s33 = uint32(s[15]) - - s22 <<= 16 - f2 += uint64(s21) - - s23 <<= 24 - f2 += uint64(s22) - - s31 <<= 8 - f3 += uint64(s30) - - s32 <<= 16 - f3 += uint64(s31) - - s33 <<= 24 - f3 += uint64(s32) - - f2 += uint64(s23) - f3 += uint64(s33) - - out[0] = byte(f0) - f0 >>= 8 - out[1] = byte(f0) - f0 >>= 8 - out[2] = byte(f0) - f0 >>= 8 - out[3] = byte(f0) - f0 >>= 8 - f1 += f0 - - out[4] = byte(f1) - f1 >>= 8 - out[5] = byte(f1) - f1 >>= 8 - out[6] = byte(f1) - f1 >>= 8 - out[7] = byte(f1) - f1 >>= 8 - f2 += f1 - - out[8] = byte(f2) - f2 >>= 8 - out[9] = byte(f2) - f2 >>= 8 - out[10] = byte(f2) - f2 >>= 8 - out[11] = byte(f2) - f2 >>= 8 - f3 += f2 - - out[12] = byte(f3) - f3 >>= 8 - out[13] = byte(f3) - f3 >>= 8 - out[14] = byte(f3) - f3 >>= 8 - out[15] = byte(f3) -} diff --git a/vendor/golang.org/x/crypto/ripemd160/ripemd160.go b/vendor/golang.org/x/crypto/ripemd160/ripemd160.go deleted file mode 100644 index 6c6e842..0000000 --- a/vendor/golang.org/x/crypto/ripemd160/ripemd160.go +++ /dev/null @@ -1,120 +0,0 @@ -// 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. -package ripemd160 // import "golang.org/x/crypto/ripemd160" - -// RIPEMD-160 is designed by 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/ripemd160_test.go b/vendor/golang.org/x/crypto/ripemd160/ripemd160_test.go deleted file mode 100644 index 5df1b25..0000000 --- a/vendor/golang.org/x/crypto/ripemd160/ripemd160_test.go +++ /dev/null @@ -1,64 +0,0 @@ -// 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 - -// Test vectors are from: -// http://homes.esat.kuleuven.be/~bosselae/ripemd160.html - -import ( - "fmt" - "io" - "testing" -) - -type mdTest struct { - out string - in string -} - -var vectors = [...]mdTest{ - {"9c1185a5c5e9fc54612808977ee8f548b2258d31", ""}, - {"0bdc9d2d256b3ee9daae347be6f4dc835a467ffe", "a"}, - {"8eb208f7e05d987a9b044a8e98c6b087f15a0bfc", "abc"}, - {"5d0689ef49d2fae572b881b123a85ffa21595f36", "message digest"}, - {"f71c27109c692c1b56bbdceb5b9d2865b3708dbc", "abcdefghijklmnopqrstuvwxyz"}, - {"12a053384a9c0c88e405a06c27dcf49ada62eb2b", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"}, - {"b0e20b6e3116640286ed3a87a5713079b21f5189", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"}, - {"9b752e45573d4b39f4dbd3323cab82bf63326bfb", "12345678901234567890123456789012345678901234567890123456789012345678901234567890"}, -} - -func TestVectors(t *testing.T) { - for i := 0; i < len(vectors); i++ { - tv := vectors[i] - md := New() - for j := 0; j < 3; j++ { - if j < 2 { - io.WriteString(md, tv.in) - } else { - io.WriteString(md, tv.in[0:len(tv.in)/2]) - md.Sum(nil) - io.WriteString(md, tv.in[len(tv.in)/2:]) - } - s := fmt.Sprintf("%x", md.Sum(nil)) - if s != tv.out { - t.Fatalf("RIPEMD-160[%d](%s) = %s, expected %s", j, tv.in, s, tv.out) - } - md.Reset() - } - } -} - -func TestMillionA(t *testing.T) { - md := New() - for i := 0; i < 100000; i++ { - io.WriteString(md, "aaaaaaaaaa") - } - out := "52783243c1697bdbe16d37f97f68f08325dc1528" - s := fmt.Sprintf("%x", md.Sum(nil)) - if s != out { - t.Fatalf("RIPEMD-160 (1 million 'a') = %s, expected %s", s, out) - } - md.Reset() -} diff --git a/vendor/golang.org/x/crypto/ripemd160/ripemd160block.go b/vendor/golang.org/x/crypto/ripemd160/ripemd160block.go deleted file mode 100644 index 7bc8e6c..0000000 --- a/vendor/golang.org/x/crypto/ripemd160/ripemd160block.go +++ /dev/null @@ -1,161 +0,0 @@ -// 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 - -// 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 := _r[i] - alpha = (alpha<>(32-s)) + e - beta = c<<10 | c>>22 - a, b, c, d, e = e, alpha, b, beta, d - - // parallel line - alpha = aa + (bb ^ (cc | ^dd)) + x[n_[i]] + 0x50a28be6 - s = r_[i] - alpha = (alpha<>(32-s)) + ee - beta = cc<<10 | cc>>22 - 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 := _r[i] - alpha = (alpha<>(32-s)) + e - beta = c<<10 | c>>22 - a, b, c, d, e = e, alpha, b, beta, d - - // parallel line - alpha = aa + (bb&dd | cc&^dd) + x[n_[i]] + 0x5c4dd124 - s = r_[i] - alpha = (alpha<>(32-s)) + ee - beta = cc<<10 | cc>>22 - 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 := _r[i] - alpha = (alpha<>(32-s)) + e - beta = c<<10 | c>>22 - a, b, c, d, e = e, alpha, b, beta, d - - // parallel line - alpha = aa + (bb | ^cc ^ dd) + x[n_[i]] + 0x6d703ef3 - s = r_[i] - alpha = (alpha<>(32-s)) + ee - beta = cc<<10 | cc>>22 - 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 := _r[i] - alpha = (alpha<>(32-s)) + e - beta = c<<10 | c>>22 - a, b, c, d, e = e, alpha, b, beta, d - - // parallel line - alpha = aa + (bb&cc | ^bb&dd) + x[n_[i]] + 0x7a6d76e9 - s = r_[i] - alpha = (alpha<>(32-s)) + ee - beta = cc<<10 | cc>>22 - 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 := _r[i] - alpha = (alpha<>(32-s)) + e - beta = c<<10 | c>>22 - a, b, c, d, e = e, alpha, b, beta, d - - // parallel line - alpha = aa + (bb ^ cc ^ dd) + x[n_[i]] - s = r_[i] - alpha = (alpha<>(32-s)) + ee - beta = cc<<10 | cc>>22 - 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/hsalsa20.go b/vendor/golang.org/x/crypto/salsa20/salsa/hsalsa20.go deleted file mode 100644 index 4c96147..0000000 --- a/vendor/golang.org/x/crypto/salsa20/salsa/hsalsa20.go +++ /dev/null @@ -1,144 +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. - -// Package salsa provides low-level access to functions in the Salsa family. -package salsa // import "golang.org/x/crypto/salsa20/salsa" - -// Sigma is the Salsa20 constant for 256-bit keys. -var Sigma = [16]byte{'e', 'x', 'p', 'a', 'n', 'd', ' ', '3', '2', '-', 'b', 'y', 't', 'e', ' ', 'k'} - -// HSalsa20 applies the HSalsa20 core function to a 16-byte input in, 32-byte -// key k, and 16-byte constant c, and puts the result into the 32-byte array -// out. -func HSalsa20(out *[32]byte, in *[16]byte, k *[32]byte, c *[16]byte) { - x0 := uint32(c[0]) | uint32(c[1])<<8 | uint32(c[2])<<16 | uint32(c[3])<<24 - x1 := uint32(k[0]) | uint32(k[1])<<8 | uint32(k[2])<<16 | uint32(k[3])<<24 - x2 := uint32(k[4]) | uint32(k[5])<<8 | uint32(k[6])<<16 | uint32(k[7])<<24 - x3 := uint32(k[8]) | uint32(k[9])<<8 | uint32(k[10])<<16 | uint32(k[11])<<24 - x4 := uint32(k[12]) | uint32(k[13])<<8 | uint32(k[14])<<16 | uint32(k[15])<<24 - x5 := uint32(c[4]) | uint32(c[5])<<8 | uint32(c[6])<<16 | uint32(c[7])<<24 - x6 := uint32(in[0]) | uint32(in[1])<<8 | uint32(in[2])<<16 | uint32(in[3])<<24 - x7 := uint32(in[4]) | uint32(in[5])<<8 | uint32(in[6])<<16 | uint32(in[7])<<24 - x8 := uint32(in[8]) | uint32(in[9])<<8 | uint32(in[10])<<16 | uint32(in[11])<<24 - x9 := uint32(in[12]) | uint32(in[13])<<8 | uint32(in[14])<<16 | uint32(in[15])<<24 - x10 := uint32(c[8]) | uint32(c[9])<<8 | uint32(c[10])<<16 | uint32(c[11])<<24 - x11 := uint32(k[16]) | uint32(k[17])<<8 | uint32(k[18])<<16 | uint32(k[19])<<24 - x12 := uint32(k[20]) | uint32(k[21])<<8 | uint32(k[22])<<16 | uint32(k[23])<<24 - x13 := uint32(k[24]) | uint32(k[25])<<8 | uint32(k[26])<<16 | uint32(k[27])<<24 - x14 := uint32(k[28]) | uint32(k[29])<<8 | uint32(k[30])<<16 | uint32(k[31])<<24 - x15 := uint32(c[12]) | uint32(c[13])<<8 | uint32(c[14])<<16 | uint32(c[15])<<24 - - for i := 0; i < 20; i += 2 { - u := x0 + x12 - x4 ^= u<<7 | u>>(32-7) - u = x4 + x0 - x8 ^= u<<9 | u>>(32-9) - u = x8 + x4 - x12 ^= u<<13 | u>>(32-13) - u = x12 + x8 - x0 ^= u<<18 | u>>(32-18) - - u = x5 + x1 - x9 ^= u<<7 | u>>(32-7) - u = x9 + x5 - x13 ^= u<<9 | u>>(32-9) - u = x13 + x9 - x1 ^= u<<13 | u>>(32-13) - u = x1 + x13 - x5 ^= u<<18 | u>>(32-18) - - u = x10 + x6 - x14 ^= u<<7 | u>>(32-7) - u = x14 + x10 - x2 ^= u<<9 | u>>(32-9) - u = x2 + x14 - x6 ^= u<<13 | u>>(32-13) - u = x6 + x2 - x10 ^= u<<18 | u>>(32-18) - - u = x15 + x11 - x3 ^= u<<7 | u>>(32-7) - u = x3 + x15 - x7 ^= u<<9 | u>>(32-9) - u = x7 + x3 - x11 ^= u<<13 | u>>(32-13) - u = x11 + x7 - x15 ^= u<<18 | u>>(32-18) - - u = x0 + x3 - x1 ^= u<<7 | u>>(32-7) - u = x1 + x0 - x2 ^= u<<9 | u>>(32-9) - u = x2 + x1 - x3 ^= u<<13 | u>>(32-13) - u = x3 + x2 - x0 ^= u<<18 | u>>(32-18) - - u = x5 + x4 - x6 ^= u<<7 | u>>(32-7) - u = x6 + x5 - x7 ^= u<<9 | u>>(32-9) - u = x7 + x6 - x4 ^= u<<13 | u>>(32-13) - u = x4 + x7 - x5 ^= u<<18 | u>>(32-18) - - u = x10 + x9 - x11 ^= u<<7 | u>>(32-7) - u = x11 + x10 - x8 ^= u<<9 | u>>(32-9) - u = x8 + x11 - x9 ^= u<<13 | u>>(32-13) - u = x9 + x8 - x10 ^= u<<18 | u>>(32-18) - - u = x15 + x14 - x12 ^= u<<7 | u>>(32-7) - u = x12 + x15 - x13 ^= u<<9 | u>>(32-9) - u = x13 + x12 - x14 ^= u<<13 | u>>(32-13) - u = x14 + x13 - x15 ^= u<<18 | u>>(32-18) - } - out[0] = byte(x0) - out[1] = byte(x0 >> 8) - out[2] = byte(x0 >> 16) - out[3] = byte(x0 >> 24) - - out[4] = byte(x5) - out[5] = byte(x5 >> 8) - out[6] = byte(x5 >> 16) - out[7] = byte(x5 >> 24) - - out[8] = byte(x10) - out[9] = byte(x10 >> 8) - out[10] = byte(x10 >> 16) - out[11] = byte(x10 >> 24) - - out[12] = byte(x15) - out[13] = byte(x15 >> 8) - out[14] = byte(x15 >> 16) - out[15] = byte(x15 >> 24) - - out[16] = byte(x6) - out[17] = byte(x6 >> 8) - out[18] = byte(x6 >> 16) - out[19] = byte(x6 >> 24) - - out[20] = byte(x7) - out[21] = byte(x7 >> 8) - out[22] = byte(x7 >> 16) - out[23] = byte(x7 >> 24) - - out[24] = byte(x8) - out[25] = byte(x8 >> 8) - out[26] = byte(x8 >> 16) - out[27] = byte(x8 >> 24) - - out[28] = byte(x9) - out[29] = byte(x9 >> 8) - out[30] = byte(x9 >> 16) - out[31] = byte(x9 >> 24) -} diff --git a/vendor/golang.org/x/crypto/salsa20/salsa/salsa2020_amd64.s b/vendor/golang.org/x/crypto/salsa20/salsa/salsa2020_amd64.s deleted file mode 100644 index 6e1df96..0000000 --- a/vendor/golang.org/x/crypto/salsa20/salsa/salsa2020_amd64.s +++ /dev/null @@ -1,902 +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,!appengine,!gccgo - -// This code was translated into a form compatible with 6a from the public -// domain sources in SUPERCOP: http://bench.cr.yp.to/supercop.html - -// func salsa2020XORKeyStream(out, in *byte, n uint64, nonce, key *byte) -TEXT ·salsa2020XORKeyStream(SB),0,$512-40 - MOVQ out+0(FP),DI - MOVQ in+8(FP),SI - MOVQ n+16(FP),DX - MOVQ nonce+24(FP),CX - MOVQ key+32(FP),R8 - - MOVQ SP,R11 - MOVQ $31,R9 - NOTQ R9 - ANDQ R9,SP - ADDQ $32,SP - - MOVQ R11,352(SP) - MOVQ R12,360(SP) - MOVQ R13,368(SP) - MOVQ R14,376(SP) - MOVQ R15,384(SP) - MOVQ BX,392(SP) - MOVQ BP,400(SP) - MOVQ DX,R9 - MOVQ CX,DX - MOVQ R8,R10 - CMPQ R9,$0 - JBE DONE - START: - MOVL 20(R10),CX - 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 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 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) - 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) - CMPQ R9,$256 - JB BYTESBETWEEN1AND255 - MOVOA 48(SP),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 - 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 - 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 - PSHUFL $0X00,X0,X1 - PSHUFL $0XAA,X0,X2 - PSHUFL $0XFF,X0,X0 - MOVOA X1,240(SP) - MOVOA X2,256(SP) - MOVOA X0,272(SP) - BYTESATLEAST256: - MOVL 16(SP),DX - MOVL 36 (SP),CX - MOVL DX,288(SP) - MOVL CX,304(SP) - ADDQ $1,DX - SHLQ $32,CX - ADDQ CX,DX - MOVQ DX,CX - SHRQ $32,CX - MOVL DX, 292 (SP) - MOVL CX, 308 (SP) - ADDQ $1,DX - SHLQ $32,CX - ADDQ CX,DX - MOVQ DX,CX - SHRQ $32,CX - MOVL DX, 296 (SP) - MOVL CX, 312 (SP) - ADDQ $1,DX - SHLQ $32,CX - ADDQ CX,DX - MOVQ DX,CX - SHRQ $32,CX - MOVL DX, 300 (SP) - MOVL CX, 316 (SP) - ADDQ $1,DX - SHLQ $32,CX - ADDQ CX,DX - MOVQ DX,CX - SHRQ $32,CX - MOVL DX,16(SP) - MOVL CX, 36 (SP) - MOVQ R9,408(SP) - 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 - MAINLOOP1: - MOVOA X1,320(SP) - MOVOA X2,336(SP) - MOVOA X13,X1 - PADDL X12,X1 - MOVOA X1,X2 - PSLLL $7,X1 - PXOR X1,X14 - PSRLL $25,X2 - PXOR X2,X14 - MOVOA X7,X1 - PADDL X0,X1 - MOVOA X1,X2 - PSLLL $7,X1 - PXOR X1,X11 - PSRLL $25,X2 - PXOR X2,X11 - MOVOA X12,X1 - PADDL X14,X1 - MOVOA X1,X2 - PSLLL $9,X1 - PXOR X1,X15 - PSRLL $23,X2 - PXOR X2,X15 - MOVOA X0,X1 - PADDL X11,X1 - MOVOA X1,X2 - PSLLL $9,X1 - PXOR X1,X9 - PSRLL $23,X2 - PXOR X2,X9 - MOVOA X14,X1 - PADDL X15,X1 - MOVOA X1,X2 - PSLLL $13,X1 - PXOR X1,X13 - PSRLL $19,X2 - PXOR X2,X13 - MOVOA X11,X1 - PADDL X9,X1 - MOVOA X1,X2 - PSLLL $13,X1 - PXOR X1,X7 - PSRLL $19,X2 - PXOR X2,X7 - MOVOA X15,X1 - PADDL X13,X1 - MOVOA X1,X2 - PSLLL $18,X1 - PXOR X1,X12 - PSRLL $14,X2 - PXOR X2,X12 - MOVOA 320(SP),X1 - MOVOA X12,320(SP) - MOVOA X9,X2 - PADDL X7,X2 - MOVOA X2,X12 - PSLLL $18,X2 - PXOR X2,X0 - PSRLL $14,X12 - PXOR X12,X0 - MOVOA X5,X2 - PADDL X1,X2 - MOVOA X2,X12 - PSLLL $7,X2 - PXOR X2,X3 - PSRLL $25,X12 - PXOR X12,X3 - MOVOA 336(SP),X2 - MOVOA X0,336(SP) - MOVOA X6,X0 - PADDL X2,X0 - MOVOA X0,X12 - PSLLL $7,X0 - PXOR X0,X4 - PSRLL $25,X12 - PXOR X12,X4 - MOVOA X1,X0 - PADDL X3,X0 - MOVOA X0,X12 - PSLLL $9,X0 - PXOR X0,X10 - PSRLL $23,X12 - PXOR X12,X10 - MOVOA X2,X0 - PADDL X4,X0 - MOVOA X0,X12 - PSLLL $9,X0 - PXOR X0,X8 - PSRLL $23,X12 - PXOR X12,X8 - MOVOA X3,X0 - PADDL X10,X0 - MOVOA X0,X12 - PSLLL $13,X0 - PXOR X0,X5 - PSRLL $19,X12 - PXOR X12,X5 - MOVOA X4,X0 - PADDL X8,X0 - MOVOA X0,X12 - PSLLL $13,X0 - PXOR X0,X6 - PSRLL $19,X12 - PXOR X12,X6 - MOVOA X10,X0 - PADDL X5,X0 - MOVOA X0,X12 - PSLLL $18,X0 - PXOR X0,X1 - PSRLL $14,X12 - PXOR X12,X1 - MOVOA 320(SP),X0 - MOVOA X1,320(SP) - MOVOA X4,X1 - PADDL X0,X1 - MOVOA X1,X12 - PSLLL $7,X1 - PXOR X1,X7 - PSRLL $25,X12 - PXOR X12,X7 - MOVOA X8,X1 - PADDL X6,X1 - MOVOA X1,X12 - PSLLL $18,X1 - PXOR X1,X2 - PSRLL $14,X12 - PXOR X12,X2 - MOVOA 336(SP),X12 - MOVOA X2,336(SP) - MOVOA X14,X1 - PADDL X12,X1 - MOVOA X1,X2 - PSLLL $7,X1 - PXOR X1,X5 - PSRLL $25,X2 - PXOR X2,X5 - MOVOA X0,X1 - PADDL X7,X1 - MOVOA X1,X2 - PSLLL $9,X1 - PXOR X1,X10 - PSRLL $23,X2 - PXOR X2,X10 - MOVOA X12,X1 - PADDL X5,X1 - MOVOA X1,X2 - PSLLL $9,X1 - PXOR X1,X8 - PSRLL $23,X2 - PXOR X2,X8 - MOVOA X7,X1 - PADDL X10,X1 - MOVOA X1,X2 - PSLLL $13,X1 - PXOR X1,X4 - PSRLL $19,X2 - PXOR X2,X4 - MOVOA X5,X1 - PADDL X8,X1 - MOVOA X1,X2 - PSLLL $13,X1 - PXOR X1,X14 - PSRLL $19,X2 - PXOR X2,X14 - MOVOA X10,X1 - PADDL X4,X1 - MOVOA X1,X2 - PSLLL $18,X1 - PXOR X1,X0 - PSRLL $14,X2 - PXOR X2,X0 - MOVOA 320(SP),X1 - MOVOA X0,320(SP) - MOVOA X8,X0 - PADDL X14,X0 - MOVOA X0,X2 - PSLLL $18,X0 - PXOR X0,X12 - PSRLL $14,X2 - PXOR X2,X12 - MOVOA X11,X0 - PADDL X1,X0 - MOVOA X0,X2 - PSLLL $7,X0 - PXOR X0,X6 - PSRLL $25,X2 - PXOR X2,X6 - MOVOA 336(SP),X2 - MOVOA X12,336(SP) - MOVOA X3,X0 - PADDL X2,X0 - MOVOA X0,X12 - PSLLL $7,X0 - PXOR X0,X13 - PSRLL $25,X12 - PXOR X12,X13 - MOVOA X1,X0 - PADDL X6,X0 - MOVOA X0,X12 - PSLLL $9,X0 - PXOR X0,X15 - PSRLL $23,X12 - PXOR X12,X15 - MOVOA X2,X0 - PADDL X13,X0 - MOVOA X0,X12 - PSLLL $9,X0 - PXOR X0,X9 - PSRLL $23,X12 - PXOR X12,X9 - MOVOA X6,X0 - PADDL X15,X0 - MOVOA X0,X12 - PSLLL $13,X0 - PXOR X0,X11 - PSRLL $19,X12 - PXOR X12,X11 - MOVOA X13,X0 - PADDL X9,X0 - MOVOA X0,X12 - PSLLL $13,X0 - PXOR X0,X3 - PSRLL $19,X12 - PXOR X12,X3 - MOVOA X15,X0 - PADDL X11,X0 - MOVOA X0,X12 - PSLLL $18,X0 - PXOR X0,X1 - PSRLL $14,X12 - PXOR X12,X1 - MOVOA X9,X0 - PADDL X3,X0 - MOVOA X0,X12 - PSLLL $18,X0 - PXOR X0,X2 - PSRLL $14,X12 - PXOR X12,X2 - MOVOA 320(SP),X12 - MOVOA 336(SP),X0 - SUBQ $2,DX - JA MAINLOOP1 - PADDL 112(SP),X12 - PADDL 176(SP),X7 - PADDL 224(SP),X10 - PADDL 272(SP),X4 - MOVD X12,DX - MOVD X7,CX - MOVD X10,R8 - MOVD X4,R9 - PSHUFL $0X39,X12,X12 - PSHUFL $0X39,X7,X7 - PSHUFL $0X39,X10,X10 - PSHUFL $0X39,X4,X4 - XORL 0(SI),DX - XORL 4(SI),CX - XORL 8(SI),R8 - XORL 12(SI),R9 - MOVL DX,0(DI) - MOVL CX,4(DI) - MOVL R8,8(DI) - MOVL R9,12(DI) - MOVD X12,DX - MOVD X7,CX - MOVD X10,R8 - MOVD X4,R9 - PSHUFL $0X39,X12,X12 - PSHUFL $0X39,X7,X7 - PSHUFL $0X39,X10,X10 - PSHUFL $0X39,X4,X4 - XORL 64(SI),DX - XORL 68(SI),CX - XORL 72(SI),R8 - XORL 76(SI),R9 - MOVL DX,64(DI) - MOVL CX,68(DI) - MOVL R8,72(DI) - MOVL R9,76(DI) - MOVD X12,DX - MOVD X7,CX - MOVD X10,R8 - MOVD X4,R9 - PSHUFL $0X39,X12,X12 - PSHUFL $0X39,X7,X7 - PSHUFL $0X39,X10,X10 - PSHUFL $0X39,X4,X4 - XORL 128(SI),DX - XORL 132(SI),CX - XORL 136(SI),R8 - XORL 140(SI),R9 - MOVL DX,128(DI) - MOVL CX,132(DI) - MOVL R8,136(DI) - MOVL R9,140(DI) - MOVD X12,DX - MOVD X7,CX - MOVD X10,R8 - MOVD X4,R9 - XORL 192(SI),DX - XORL 196(SI),CX - XORL 200(SI),R8 - XORL 204(SI),R9 - MOVL DX,192(DI) - 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 - MOVD X14,DX - MOVD X0,CX - MOVD X5,R8 - MOVD X8,R9 - PSHUFL $0X39,X14,X14 - PSHUFL $0X39,X0,X0 - PSHUFL $0X39,X5,X5 - PSHUFL $0X39,X8,X8 - XORL 16(SI),DX - XORL 20(SI),CX - XORL 24(SI),R8 - XORL 28(SI),R9 - MOVL DX,16(DI) - MOVL CX,20(DI) - MOVL R8,24(DI) - MOVL R9,28(DI) - MOVD X14,DX - MOVD X0,CX - MOVD X5,R8 - MOVD X8,R9 - PSHUFL $0X39,X14,X14 - PSHUFL $0X39,X0,X0 - PSHUFL $0X39,X5,X5 - PSHUFL $0X39,X8,X8 - XORL 80(SI),DX - XORL 84(SI),CX - XORL 88(SI),R8 - XORL 92(SI),R9 - MOVL DX,80(DI) - MOVL CX,84(DI) - MOVL R8,88(DI) - MOVL R9,92(DI) - MOVD X14,DX - MOVD X0,CX - MOVD X5,R8 - MOVD X8,R9 - PSHUFL $0X39,X14,X14 - PSHUFL $0X39,X0,X0 - PSHUFL $0X39,X5,X5 - PSHUFL $0X39,X8,X8 - XORL 144(SI),DX - XORL 148(SI),CX - XORL 152(SI),R8 - XORL 156(SI),R9 - MOVL DX,144(DI) - MOVL CX,148(DI) - MOVL R8,152(DI) - MOVL R9,156(DI) - MOVD X14,DX - MOVD X0,CX - MOVD X5,R8 - MOVD X8,R9 - XORL 208(SI),DX - XORL 212(SI),CX - XORL 216(SI),R8 - XORL 220(SI),R9 - MOVL DX,208(DI) - 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 - MOVD X15,DX - MOVD X11,CX - MOVD X1,R8 - MOVD X6,R9 - PSHUFL $0X39,X15,X15 - PSHUFL $0X39,X11,X11 - PSHUFL $0X39,X1,X1 - PSHUFL $0X39,X6,X6 - XORL 32(SI),DX - XORL 36(SI),CX - XORL 40(SI),R8 - XORL 44(SI),R9 - MOVL DX,32(DI) - MOVL CX,36(DI) - MOVL R8,40(DI) - MOVL R9,44(DI) - MOVD X15,DX - MOVD X11,CX - MOVD X1,R8 - MOVD X6,R9 - PSHUFL $0X39,X15,X15 - PSHUFL $0X39,X11,X11 - PSHUFL $0X39,X1,X1 - PSHUFL $0X39,X6,X6 - XORL 96(SI),DX - XORL 100(SI),CX - XORL 104(SI),R8 - XORL 108(SI),R9 - MOVL DX,96(DI) - MOVL CX,100(DI) - MOVL R8,104(DI) - MOVL R9,108(DI) - MOVD X15,DX - MOVD X11,CX - MOVD X1,R8 - MOVD X6,R9 - PSHUFL $0X39,X15,X15 - PSHUFL $0X39,X11,X11 - PSHUFL $0X39,X1,X1 - PSHUFL $0X39,X6,X6 - XORL 160(SI),DX - XORL 164(SI),CX - XORL 168(SI),R8 - XORL 172(SI),R9 - MOVL DX,160(DI) - MOVL CX,164(DI) - MOVL R8,168(DI) - MOVL R9,172(DI) - MOVD X15,DX - MOVD X11,CX - MOVD X1,R8 - MOVD X6,R9 - XORL 224(SI),DX - XORL 228(SI),CX - XORL 232(SI),R8 - XORL 236(SI),R9 - MOVL DX,224(DI) - 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 - MOVD X13,DX - MOVD X9,CX - MOVD X3,R8 - MOVD X2,R9 - PSHUFL $0X39,X13,X13 - PSHUFL $0X39,X9,X9 - PSHUFL $0X39,X3,X3 - PSHUFL $0X39,X2,X2 - XORL 48(SI),DX - XORL 52(SI),CX - XORL 56(SI),R8 - XORL 60(SI),R9 - MOVL DX,48(DI) - MOVL CX,52(DI) - MOVL R8,56(DI) - MOVL R9,60(DI) - MOVD X13,DX - MOVD X9,CX - MOVD X3,R8 - MOVD X2,R9 - PSHUFL $0X39,X13,X13 - PSHUFL $0X39,X9,X9 - PSHUFL $0X39,X3,X3 - PSHUFL $0X39,X2,X2 - XORL 112(SI),DX - XORL 116(SI),CX - XORL 120(SI),R8 - XORL 124(SI),R9 - MOVL DX,112(DI) - MOVL CX,116(DI) - MOVL R8,120(DI) - MOVL R9,124(DI) - MOVD X13,DX - MOVD X9,CX - MOVD X3,R8 - MOVD X2,R9 - PSHUFL $0X39,X13,X13 - PSHUFL $0X39,X9,X9 - PSHUFL $0X39,X3,X3 - PSHUFL $0X39,X2,X2 - XORL 176(SI),DX - XORL 180(SI),CX - XORL 184(SI),R8 - XORL 188(SI),R9 - MOVL DX,176(DI) - MOVL CX,180(DI) - MOVL R8,184(DI) - MOVL R9,188(DI) - MOVD X13,DX - MOVD X9,CX - MOVD X3,R8 - MOVD X2,R9 - XORL 240(SI),DX - XORL 244(SI),CX - XORL 248(SI),R8 - XORL 252(SI),R9 - MOVL DX,240(DI) - MOVL CX,244(DI) - MOVL R8,248(DI) - MOVL R9,252(DI) - MOVQ 408(SP),R9 - SUBQ $256,R9 - ADDQ $256,SI - ADDQ $256,DI - CMPQ R9,$256 - JAE BYTESATLEAST256 - CMPQ R9,$0 - JBE DONE - BYTESBETWEEN1AND255: - CMPQ R9,$64 - JAE NOCOPY - MOVQ DI,DX - LEAQ 416(SP),DI - MOVQ R9,CX - REP; MOVSB - LEAQ 416(SP),DI - LEAQ 416(SP),SI - NOCOPY: - MOVQ R9,408(SP) - MOVOA 48(SP),X0 - MOVOA 0(SP),X1 - MOVOA 16(SP),X2 - MOVOA 32(SP),X3 - MOVOA X1,X4 - MOVQ $20,CX - MAINLOOP2: - PADDL X0,X4 - MOVOA X0,X5 - MOVOA X4,X6 - PSLLL $7,X4 - PSRLL $25,X6 - PXOR X4,X3 - PXOR X6,X3 - PADDL X3,X5 - MOVOA X3,X4 - MOVOA X5,X6 - PSLLL $9,X5 - PSRLL $23,X6 - PXOR X5,X2 - PSHUFL $0X93,X3,X3 - PXOR X6,X2 - PADDL X2,X4 - MOVOA X2,X5 - MOVOA X4,X6 - PSLLL $13,X4 - PSRLL $19,X6 - PXOR X4,X1 - PSHUFL $0X4E,X2,X2 - PXOR X6,X1 - PADDL X1,X5 - MOVOA X3,X4 - MOVOA X5,X6 - PSLLL $18,X5 - PSRLL $14,X6 - PXOR X5,X0 - PSHUFL $0X39,X1,X1 - PXOR X6,X0 - PADDL X0,X4 - MOVOA X0,X5 - MOVOA X4,X6 - PSLLL $7,X4 - PSRLL $25,X6 - PXOR X4,X1 - PXOR X6,X1 - PADDL X1,X5 - MOVOA X1,X4 - MOVOA X5,X6 - PSLLL $9,X5 - PSRLL $23,X6 - PXOR X5,X2 - PSHUFL $0X93,X1,X1 - PXOR X6,X2 - PADDL X2,X4 - MOVOA X2,X5 - MOVOA X4,X6 - PSLLL $13,X4 - PSRLL $19,X6 - PXOR X4,X3 - PSHUFL $0X4E,X2,X2 - PXOR X6,X3 - PADDL X3,X5 - MOVOA X1,X4 - MOVOA X5,X6 - PSLLL $18,X5 - PSRLL $14,X6 - PXOR X5,X0 - PSHUFL $0X39,X3,X3 - PXOR X6,X0 - PADDL X0,X4 - MOVOA X0,X5 - MOVOA X4,X6 - PSLLL $7,X4 - PSRLL $25,X6 - PXOR X4,X3 - PXOR X6,X3 - PADDL X3,X5 - MOVOA X3,X4 - MOVOA X5,X6 - PSLLL $9,X5 - PSRLL $23,X6 - PXOR X5,X2 - PSHUFL $0X93,X3,X3 - PXOR X6,X2 - PADDL X2,X4 - MOVOA X2,X5 - MOVOA X4,X6 - PSLLL $13,X4 - PSRLL $19,X6 - PXOR X4,X1 - PSHUFL $0X4E,X2,X2 - PXOR X6,X1 - PADDL X1,X5 - MOVOA X3,X4 - MOVOA X5,X6 - PSLLL $18,X5 - PSRLL $14,X6 - PXOR X5,X0 - PSHUFL $0X39,X1,X1 - PXOR X6,X0 - PADDL X0,X4 - MOVOA X0,X5 - MOVOA X4,X6 - PSLLL $7,X4 - PSRLL $25,X6 - PXOR X4,X1 - PXOR X6,X1 - PADDL X1,X5 - MOVOA X1,X4 - MOVOA X5,X6 - PSLLL $9,X5 - PSRLL $23,X6 - PXOR X5,X2 - PSHUFL $0X93,X1,X1 - PXOR X6,X2 - PADDL X2,X4 - MOVOA X2,X5 - MOVOA X4,X6 - PSLLL $13,X4 - PSRLL $19,X6 - PXOR X4,X3 - PSHUFL $0X4E,X2,X2 - PXOR X6,X3 - SUBQ $4,CX - PADDL X3,X5 - MOVOA X1,X4 - MOVOA X5,X6 - PSLLL $18,X5 - PXOR X7,X7 - PSRLL $14,X6 - PXOR X5,X0 - 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 - MOVD X0,CX - MOVD X1,R8 - MOVD X2,R9 - MOVD X3,AX - PSHUFL $0X39,X0,X0 - PSHUFL $0X39,X1,X1 - PSHUFL $0X39,X2,X2 - PSHUFL $0X39,X3,X3 - XORL 0(SI),CX - XORL 48(SI),R8 - XORL 32(SI),R9 - XORL 16(SI),AX - MOVL CX,0(DI) - MOVL R8,48(DI) - MOVL R9,32(DI) - MOVL AX,16(DI) - MOVD X0,CX - MOVD X1,R8 - MOVD X2,R9 - MOVD X3,AX - PSHUFL $0X39,X0,X0 - PSHUFL $0X39,X1,X1 - PSHUFL $0X39,X2,X2 - PSHUFL $0X39,X3,X3 - XORL 20(SI),CX - XORL 4(SI),R8 - XORL 52(SI),R9 - XORL 36(SI),AX - MOVL CX,20(DI) - MOVL R8,4(DI) - MOVL R9,52(DI) - MOVL AX,36(DI) - MOVD X0,CX - MOVD X1,R8 - MOVD X2,R9 - MOVD X3,AX - PSHUFL $0X39,X0,X0 - PSHUFL $0X39,X1,X1 - PSHUFL $0X39,X2,X2 - PSHUFL $0X39,X3,X3 - XORL 40(SI),CX - XORL 24(SI),R8 - XORL 8(SI),R9 - XORL 56(SI),AX - MOVL CX,40(DI) - MOVL R8,24(DI) - MOVL R9,8(DI) - MOVL AX,56(DI) - MOVD X0,CX - MOVD X1,R8 - MOVD X2,R9 - MOVD X3,AX - XORL 60(SI),CX - XORL 44(SI),R8 - XORL 28(SI),R9 - XORL 12(SI),AX - MOVL CX,60(DI) - MOVL R8,44(DI) - MOVL R9,28(DI) - MOVL AX,12(DI) - MOVQ 408(SP),R9 - MOVL 16(SP),CX - MOVL 36 (SP),R8 - ADDQ $1,CX - SHLQ $32,R8 - ADDQ R8,CX - MOVQ CX,R8 - SHRQ $32,R8 - MOVL CX,16(SP) - MOVL R8, 36 (SP) - CMPQ R9,$64 - JA BYTESATLEAST65 - JAE BYTESATLEAST64 - MOVQ DI,SI - MOVQ DX,DI - MOVQ R9,CX - REP; MOVSB - BYTESATLEAST64: - DONE: - MOVQ 352(SP),R11 - MOVQ 360(SP),R12 - MOVQ 368(SP),R13 - MOVQ 376(SP),R14 - MOVQ 384(SP),R15 - MOVQ 392(SP),BX - MOVQ 400(SP),BP - MOVQ R11,SP - RET - BYTESATLEAST65: - SUBQ $64,R9 - ADDQ $64,DI - ADDQ $64,SI - JMP BYTESBETWEEN1AND255 diff --git a/vendor/golang.org/x/crypto/salsa20/salsa/salsa208.go b/vendor/golang.org/x/crypto/salsa20/salsa/salsa208.go deleted file mode 100644 index 9bfc092..0000000 --- a/vendor/golang.org/x/crypto/salsa20/salsa/salsa208.go +++ /dev/null @@ -1,199 +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. - -package salsa - -// Core208 applies the Salsa20/8 core function to the 64-byte array in and puts -// the result into the 64-byte array out. The input and output may be the same array. -func Core208(out *[64]byte, in *[64]byte) { - j0 := uint32(in[0]) | uint32(in[1])<<8 | uint32(in[2])<<16 | uint32(in[3])<<24 - j1 := uint32(in[4]) | uint32(in[5])<<8 | uint32(in[6])<<16 | uint32(in[7])<<24 - j2 := uint32(in[8]) | uint32(in[9])<<8 | uint32(in[10])<<16 | uint32(in[11])<<24 - j3 := uint32(in[12]) | uint32(in[13])<<8 | uint32(in[14])<<16 | uint32(in[15])<<24 - j4 := uint32(in[16]) | uint32(in[17])<<8 | uint32(in[18])<<16 | uint32(in[19])<<24 - j5 := uint32(in[20]) | uint32(in[21])<<8 | uint32(in[22])<<16 | uint32(in[23])<<24 - j6 := uint32(in[24]) | uint32(in[25])<<8 | uint32(in[26])<<16 | uint32(in[27])<<24 - j7 := uint32(in[28]) | uint32(in[29])<<8 | uint32(in[30])<<16 | uint32(in[31])<<24 - j8 := uint32(in[32]) | uint32(in[33])<<8 | uint32(in[34])<<16 | uint32(in[35])<<24 - j9 := uint32(in[36]) | uint32(in[37])<<8 | uint32(in[38])<<16 | uint32(in[39])<<24 - j10 := uint32(in[40]) | uint32(in[41])<<8 | uint32(in[42])<<16 | uint32(in[43])<<24 - j11 := uint32(in[44]) | uint32(in[45])<<8 | uint32(in[46])<<16 | uint32(in[47])<<24 - j12 := uint32(in[48]) | uint32(in[49])<<8 | uint32(in[50])<<16 | uint32(in[51])<<24 - j13 := uint32(in[52]) | uint32(in[53])<<8 | uint32(in[54])<<16 | uint32(in[55])<<24 - j14 := uint32(in[56]) | uint32(in[57])<<8 | uint32(in[58])<<16 | uint32(in[59])<<24 - j15 := uint32(in[60]) | uint32(in[61])<<8 | uint32(in[62])<<16 | uint32(in[63])<<24 - - x0, x1, x2, x3, x4, x5, x6, x7, x8 := j0, j1, j2, j3, j4, j5, j6, j7, j8 - x9, x10, x11, x12, x13, x14, x15 := j9, j10, j11, j12, j13, j14, j15 - - for i := 0; i < 8; i += 2 { - u := x0 + x12 - x4 ^= u<<7 | u>>(32-7) - u = x4 + x0 - x8 ^= u<<9 | u>>(32-9) - u = x8 + x4 - x12 ^= u<<13 | u>>(32-13) - u = x12 + x8 - x0 ^= u<<18 | u>>(32-18) - - u = x5 + x1 - x9 ^= u<<7 | u>>(32-7) - u = x9 + x5 - x13 ^= u<<9 | u>>(32-9) - u = x13 + x9 - x1 ^= u<<13 | u>>(32-13) - u = x1 + x13 - x5 ^= u<<18 | u>>(32-18) - - u = x10 + x6 - x14 ^= u<<7 | u>>(32-7) - u = x14 + x10 - x2 ^= u<<9 | u>>(32-9) - u = x2 + x14 - x6 ^= u<<13 | u>>(32-13) - u = x6 + x2 - x10 ^= u<<18 | u>>(32-18) - - u = x15 + x11 - x3 ^= u<<7 | u>>(32-7) - u = x3 + x15 - x7 ^= u<<9 | u>>(32-9) - u = x7 + x3 - x11 ^= u<<13 | u>>(32-13) - u = x11 + x7 - x15 ^= u<<18 | u>>(32-18) - - u = x0 + x3 - x1 ^= u<<7 | u>>(32-7) - u = x1 + x0 - x2 ^= u<<9 | u>>(32-9) - u = x2 + x1 - x3 ^= u<<13 | u>>(32-13) - u = x3 + x2 - x0 ^= u<<18 | u>>(32-18) - - u = x5 + x4 - x6 ^= u<<7 | u>>(32-7) - u = x6 + x5 - x7 ^= u<<9 | u>>(32-9) - u = x7 + x6 - x4 ^= u<<13 | u>>(32-13) - u = x4 + x7 - x5 ^= u<<18 | u>>(32-18) - - u = x10 + x9 - x11 ^= u<<7 | u>>(32-7) - u = x11 + x10 - x8 ^= u<<9 | u>>(32-9) - u = x8 + x11 - x9 ^= u<<13 | u>>(32-13) - u = x9 + x8 - x10 ^= u<<18 | u>>(32-18) - - u = x15 + x14 - x12 ^= u<<7 | u>>(32-7) - u = x12 + x15 - x13 ^= u<<9 | u>>(32-9) - u = x13 + x12 - x14 ^= u<<13 | u>>(32-13) - u = x14 + x13 - x15 ^= u<<18 | u>>(32-18) - } - x0 += j0 - x1 += j1 - x2 += j2 - x3 += j3 - x4 += j4 - x5 += j5 - x6 += j6 - x7 += j7 - x8 += j8 - x9 += j9 - x10 += j10 - x11 += j11 - x12 += j12 - x13 += j13 - x14 += j14 - x15 += j15 - - out[0] = byte(x0) - out[1] = byte(x0 >> 8) - out[2] = byte(x0 >> 16) - out[3] = byte(x0 >> 24) - - out[4] = byte(x1) - out[5] = byte(x1 >> 8) - out[6] = byte(x1 >> 16) - out[7] = byte(x1 >> 24) - - out[8] = byte(x2) - out[9] = byte(x2 >> 8) - out[10] = byte(x2 >> 16) - out[11] = byte(x2 >> 24) - - out[12] = byte(x3) - out[13] = byte(x3 >> 8) - out[14] = byte(x3 >> 16) - out[15] = byte(x3 >> 24) - - out[16] = byte(x4) - out[17] = byte(x4 >> 8) - out[18] = byte(x4 >> 16) - out[19] = byte(x4 >> 24) - - out[20] = byte(x5) - out[21] = byte(x5 >> 8) - out[22] = byte(x5 >> 16) - out[23] = byte(x5 >> 24) - - out[24] = byte(x6) - out[25] = byte(x6 >> 8) - out[26] = byte(x6 >> 16) - out[27] = byte(x6 >> 24) - - out[28] = byte(x7) - out[29] = byte(x7 >> 8) - out[30] = byte(x7 >> 16) - out[31] = byte(x7 >> 24) - - out[32] = byte(x8) - out[33] = byte(x8 >> 8) - out[34] = byte(x8 >> 16) - out[35] = byte(x8 >> 24) - - out[36] = byte(x9) - out[37] = byte(x9 >> 8) - out[38] = byte(x9 >> 16) - out[39] = byte(x9 >> 24) - - out[40] = byte(x10) - out[41] = byte(x10 >> 8) - out[42] = byte(x10 >> 16) - out[43] = byte(x10 >> 24) - - out[44] = byte(x11) - out[45] = byte(x11 >> 8) - out[46] = byte(x11 >> 16) - out[47] = byte(x11 >> 24) - - out[48] = byte(x12) - out[49] = byte(x12 >> 8) - out[50] = byte(x12 >> 16) - out[51] = byte(x12 >> 24) - - out[52] = byte(x13) - out[53] = byte(x13 >> 8) - out[54] = byte(x13 >> 16) - out[55] = byte(x13 >> 24) - - out[56] = byte(x14) - out[57] = byte(x14 >> 8) - out[58] = byte(x14 >> 16) - out[59] = byte(x14 >> 24) - - out[60] = byte(x15) - out[61] = byte(x15 >> 8) - out[62] = byte(x15 >> 16) - out[63] = byte(x15 >> 24) -} diff --git a/vendor/golang.org/x/crypto/salsa20/salsa/salsa20_amd64.go b/vendor/golang.org/x/crypto/salsa20/salsa/salsa20_amd64.go deleted file mode 100644 index 903c785..0000000 --- a/vendor/golang.org/x/crypto/salsa20/salsa/salsa20_amd64.go +++ /dev/null @@ -1,23 +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,!appengine,!gccgo - -package salsa - -// This function is implemented in salsa2020_amd64.s. - -//go:noescape - -func salsa2020XORKeyStream(out, in *byte, n uint64, nonce, key *byte) - -// XORKeyStream crypts bytes from in to out using the given key and counters. -// In and out may be the same slice but otherwise should not overlap. Counter -// contains the raw salsa20 counter bytes (both nonce and block counter). -func XORKeyStream(out, in []byte, counter *[16]byte, key *[32]byte) { - if len(in) == 0 { - return - } - salsa2020XORKeyStream(&out[0], &in[0], uint64(len(in)), &counter[0], &key[0]) -} diff --git a/vendor/golang.org/x/crypto/salsa20/salsa/salsa20_ref.go b/vendor/golang.org/x/crypto/salsa20/salsa/salsa20_ref.go deleted file mode 100644 index 95f8ca5..0000000 --- a/vendor/golang.org/x/crypto/salsa20/salsa/salsa20_ref.go +++ /dev/null @@ -1,234 +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 appengine gccgo - -package salsa - -const rounds = 20 - -// core applies the Salsa20 core function to 16-byte input in, 32-byte key k, -// and 16-byte constant c, and puts the result into 64-byte array out. -func core(out *[64]byte, in *[16]byte, k *[32]byte, c *[16]byte) { - j0 := uint32(c[0]) | uint32(c[1])<<8 | uint32(c[2])<<16 | uint32(c[3])<<24 - j1 := uint32(k[0]) | uint32(k[1])<<8 | uint32(k[2])<<16 | uint32(k[3])<<24 - j2 := uint32(k[4]) | uint32(k[5])<<8 | uint32(k[6])<<16 | uint32(k[7])<<24 - j3 := uint32(k[8]) | uint32(k[9])<<8 | uint32(k[10])<<16 | uint32(k[11])<<24 - j4 := uint32(k[12]) | uint32(k[13])<<8 | uint32(k[14])<<16 | uint32(k[15])<<24 - j5 := uint32(c[4]) | uint32(c[5])<<8 | uint32(c[6])<<16 | uint32(c[7])<<24 - j6 := uint32(in[0]) | uint32(in[1])<<8 | uint32(in[2])<<16 | uint32(in[3])<<24 - j7 := uint32(in[4]) | uint32(in[5])<<8 | uint32(in[6])<<16 | uint32(in[7])<<24 - j8 := uint32(in[8]) | uint32(in[9])<<8 | uint32(in[10])<<16 | uint32(in[11])<<24 - j9 := uint32(in[12]) | uint32(in[13])<<8 | uint32(in[14])<<16 | uint32(in[15])<<24 - j10 := uint32(c[8]) | uint32(c[9])<<8 | uint32(c[10])<<16 | uint32(c[11])<<24 - j11 := uint32(k[16]) | uint32(k[17])<<8 | uint32(k[18])<<16 | uint32(k[19])<<24 - j12 := uint32(k[20]) | uint32(k[21])<<8 | uint32(k[22])<<16 | uint32(k[23])<<24 - j13 := uint32(k[24]) | uint32(k[25])<<8 | uint32(k[26])<<16 | uint32(k[27])<<24 - j14 := uint32(k[28]) | uint32(k[29])<<8 | uint32(k[30])<<16 | uint32(k[31])<<24 - j15 := uint32(c[12]) | uint32(c[13])<<8 | uint32(c[14])<<16 | uint32(c[15])<<24 - - x0, x1, x2, x3, x4, x5, x6, x7, x8 := j0, j1, j2, j3, j4, j5, j6, j7, j8 - x9, x10, x11, x12, x13, x14, x15 := j9, j10, j11, j12, j13, j14, j15 - - for i := 0; i < rounds; i += 2 { - u := x0 + x12 - x4 ^= u<<7 | u>>(32-7) - u = x4 + x0 - x8 ^= u<<9 | u>>(32-9) - u = x8 + x4 - x12 ^= u<<13 | u>>(32-13) - u = x12 + x8 - x0 ^= u<<18 | u>>(32-18) - - u = x5 + x1 - x9 ^= u<<7 | u>>(32-7) - u = x9 + x5 - x13 ^= u<<9 | u>>(32-9) - u = x13 + x9 - x1 ^= u<<13 | u>>(32-13) - u = x1 + x13 - x5 ^= u<<18 | u>>(32-18) - - u = x10 + x6 - x14 ^= u<<7 | u>>(32-7) - u = x14 + x10 - x2 ^= u<<9 | u>>(32-9) - u = x2 + x14 - x6 ^= u<<13 | u>>(32-13) - u = x6 + x2 - x10 ^= u<<18 | u>>(32-18) - - u = x15 + x11 - x3 ^= u<<7 | u>>(32-7) - u = x3 + x15 - x7 ^= u<<9 | u>>(32-9) - u = x7 + x3 - x11 ^= u<<13 | u>>(32-13) - u = x11 + x7 - x15 ^= u<<18 | u>>(32-18) - - u = x0 + x3 - x1 ^= u<<7 | u>>(32-7) - u = x1 + x0 - x2 ^= u<<9 | u>>(32-9) - u = x2 + x1 - x3 ^= u<<13 | u>>(32-13) - u = x3 + x2 - x0 ^= u<<18 | u>>(32-18) - - u = x5 + x4 - x6 ^= u<<7 | u>>(32-7) - u = x6 + x5 - x7 ^= u<<9 | u>>(32-9) - u = x7 + x6 - x4 ^= u<<13 | u>>(32-13) - u = x4 + x7 - x5 ^= u<<18 | u>>(32-18) - - u = x10 + x9 - x11 ^= u<<7 | u>>(32-7) - u = x11 + x10 - x8 ^= u<<9 | u>>(32-9) - u = x8 + x11 - x9 ^= u<<13 | u>>(32-13) - u = x9 + x8 - x10 ^= u<<18 | u>>(32-18) - - u = x15 + x14 - x12 ^= u<<7 | u>>(32-7) - u = x12 + x15 - x13 ^= u<<9 | u>>(32-9) - u = x13 + x12 - x14 ^= u<<13 | u>>(32-13) - u = x14 + x13 - x15 ^= u<<18 | u>>(32-18) - } - x0 += j0 - x1 += j1 - x2 += j2 - x3 += j3 - x4 += j4 - x5 += j5 - x6 += j6 - x7 += j7 - x8 += j8 - x9 += j9 - x10 += j10 - x11 += j11 - x12 += j12 - x13 += j13 - x14 += j14 - x15 += j15 - - out[0] = byte(x0) - out[1] = byte(x0 >> 8) - out[2] = byte(x0 >> 16) - out[3] = byte(x0 >> 24) - - out[4] = byte(x1) - out[5] = byte(x1 >> 8) - out[6] = byte(x1 >> 16) - out[7] = byte(x1 >> 24) - - out[8] = byte(x2) - out[9] = byte(x2 >> 8) - out[10] = byte(x2 >> 16) - out[11] = byte(x2 >> 24) - - out[12] = byte(x3) - out[13] = byte(x3 >> 8) - out[14] = byte(x3 >> 16) - out[15] = byte(x3 >> 24) - - out[16] = byte(x4) - out[17] = byte(x4 >> 8) - out[18] = byte(x4 >> 16) - out[19] = byte(x4 >> 24) - - out[20] = byte(x5) - out[21] = byte(x5 >> 8) - out[22] = byte(x5 >> 16) - out[23] = byte(x5 >> 24) - - out[24] = byte(x6) - out[25] = byte(x6 >> 8) - out[26] = byte(x6 >> 16) - out[27] = byte(x6 >> 24) - - out[28] = byte(x7) - out[29] = byte(x7 >> 8) - out[30] = byte(x7 >> 16) - out[31] = byte(x7 >> 24) - - out[32] = byte(x8) - out[33] = byte(x8 >> 8) - out[34] = byte(x8 >> 16) - out[35] = byte(x8 >> 24) - - out[36] = byte(x9) - out[37] = byte(x9 >> 8) - out[38] = byte(x9 >> 16) - out[39] = byte(x9 >> 24) - - out[40] = byte(x10) - out[41] = byte(x10 >> 8) - out[42] = byte(x10 >> 16) - out[43] = byte(x10 >> 24) - - out[44] = byte(x11) - out[45] = byte(x11 >> 8) - out[46] = byte(x11 >> 16) - out[47] = byte(x11 >> 24) - - out[48] = byte(x12) - out[49] = byte(x12 >> 8) - out[50] = byte(x12 >> 16) - out[51] = byte(x12 >> 24) - - out[52] = byte(x13) - out[53] = byte(x13 >> 8) - out[54] = byte(x13 >> 16) - out[55] = byte(x13 >> 24) - - out[56] = byte(x14) - out[57] = byte(x14 >> 8) - out[58] = byte(x14 >> 16) - out[59] = byte(x14 >> 24) - - out[60] = byte(x15) - out[61] = byte(x15 >> 8) - out[62] = byte(x15 >> 16) - out[63] = byte(x15 >> 24) -} - -// XORKeyStream crypts bytes from in to out using the given key and counters. -// In and out may be the same slice but otherwise should not overlap. Counter -// contains the raw salsa20 counter bytes (both nonce and block counter). -func XORKeyStream(out, in []byte, counter *[16]byte, key *[32]byte) { - var block [64]byte - var counterCopy [16]byte - copy(counterCopy[:], counter[:]) - - for len(in) >= 64 { - core(&block, &counterCopy, key, &Sigma) - for i, x := range block { - out[i] = in[i] ^ x - } - u := uint32(1) - for i := 8; i < 16; i++ { - u += uint32(counterCopy[i]) - counterCopy[i] = byte(u) - u >>= 8 - } - in = in[64:] - out = out[64:] - } - - if len(in) > 0 { - core(&block, &counterCopy, key, &Sigma) - for i, v := range in { - out[i] = v ^ block[i] - } - } -} diff --git a/vendor/golang.org/x/crypto/salsa20/salsa/salsa_test.go b/vendor/golang.org/x/crypto/salsa20/salsa/salsa_test.go deleted file mode 100644 index f8cecd9..0000000 --- a/vendor/golang.org/x/crypto/salsa20/salsa/salsa_test.go +++ /dev/null @@ -1,35 +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. - -package salsa - -import "testing" - -func TestCore208(t *testing.T) { - in := [64]byte{ - 0x7e, 0x87, 0x9a, 0x21, 0x4f, 0x3e, 0xc9, 0x86, - 0x7c, 0xa9, 0x40, 0xe6, 0x41, 0x71, 0x8f, 0x26, - 0xba, 0xee, 0x55, 0x5b, 0x8c, 0x61, 0xc1, 0xb5, - 0x0d, 0xf8, 0x46, 0x11, 0x6d, 0xcd, 0x3b, 0x1d, - 0xee, 0x24, 0xf3, 0x19, 0xdf, 0x9b, 0x3d, 0x85, - 0x14, 0x12, 0x1e, 0x4b, 0x5a, 0xc5, 0xaa, 0x32, - 0x76, 0x02, 0x1d, 0x29, 0x09, 0xc7, 0x48, 0x29, - 0xed, 0xeb, 0xc6, 0x8d, 0xb8, 0xb8, 0xc2, 0x5e} - - out := [64]byte{ - 0xa4, 0x1f, 0x85, 0x9c, 0x66, 0x08, 0xcc, 0x99, - 0x3b, 0x81, 0xca, 0xcb, 0x02, 0x0c, 0xef, 0x05, - 0x04, 0x4b, 0x21, 0x81, 0xa2, 0xfd, 0x33, 0x7d, - 0xfd, 0x7b, 0x1c, 0x63, 0x96, 0x68, 0x2f, 0x29, - 0xb4, 0x39, 0x31, 0x68, 0xe3, 0xc9, 0xe6, 0xbc, - 0xfe, 0x6b, 0xc5, 0xb7, 0xa0, 0x6d, 0x96, 0xba, - 0xe4, 0x24, 0xcc, 0x10, 0x2c, 0x91, 0x74, 0x5c, - 0x24, 0xad, 0x67, 0x3d, 0xc7, 0x61, 0x8f, 0x81, - } - - Core208(&in, &in) - if in != out { - t.Errorf("expected %x, got %x", out, in) - } -} diff --git a/vendor/golang.org/x/crypto/salsa20/salsa20.go b/vendor/golang.org/x/crypto/salsa20/salsa20.go deleted file mode 100644 index fde9846..0000000 --- a/vendor/golang.org/x/crypto/salsa20/salsa20.go +++ /dev/null @@ -1,54 +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. - -/* -Package salsa20 implements the Salsa20 stream cipher as specified in http://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 -an 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 http://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/salsa20/salsa" -) - -// XORKeyStream crypts bytes from in to out using the given key and nonce. In -// and out may be the same slice but otherwise should not overlap. Nonce must -// be either 8 or 24 bytes long. -func XORKeyStream(out, in []byte, nonce []byte, key *[32]byte) { - if len(out) < len(in) { - in = in[:len(out)] - } - - 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/salsa20/salsa20_test.go b/vendor/golang.org/x/crypto/salsa20/salsa20_test.go deleted file mode 100644 index 0ef3328..0000000 --- a/vendor/golang.org/x/crypto/salsa20/salsa20_test.go +++ /dev/null @@ -1,139 +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. - -package salsa20 - -import ( - "bytes" - "encoding/hex" - "testing" -) - -func fromHex(s string) []byte { - ret, err := hex.DecodeString(s) - if err != nil { - panic(err) - } - return ret -} - -// testVectors was taken from set 6 of the ECRYPT test vectors: -// http://www.ecrypt.eu.org/stream/svn/viewcvs.cgi/ecrypt/trunk/submissions/salsa20/full/verified.test-vectors?logsort=rev&rev=210&view=markup -var testVectors = []struct { - key []byte - iv []byte - numBytes int - xor []byte -}{ - { - fromHex("0053A6F94C9FF24598EB3E91E4378ADD3083D6297CCF2275C81B6EC11467BA0D"), - fromHex("0D74DB42A91077DE"), - 131072, - fromHex("C349B6A51A3EC9B712EAED3F90D8BCEE69B7628645F251A996F55260C62EF31FD6C6B0AEA94E136C9D984AD2DF3578F78E457527B03A0450580DD874F63B1AB9"), - }, - { - fromHex("0558ABFE51A4F74A9DF04396E93C8FE23588DB2E81D4277ACD2073C6196CBF12"), - fromHex("167DE44BB21980E7"), - 131072, - fromHex("C3EAAF32836BACE32D04E1124231EF47E101367D6305413A0EEB07C60698A2876E4D031870A739D6FFDDD208597AFF0A47AC17EDB0167DD67EBA84F1883D4DFD"), - }, - { - fromHex("0A5DB00356A9FC4FA2F5489BEE4194E73A8DE03386D92C7FD22578CB1E71C417"), - fromHex("1F86ED54BB2289F0"), - 131072, - fromHex("3CD23C3DC90201ACC0CF49B440B6C417F0DC8D8410A716D5314C059E14B1A8D9A9FB8EA3D9C8DAE12B21402F674AA95C67B1FC514E994C9D3F3A6E41DFF5BBA6"), - }, - { - fromHex("0F62B5085BAE0154A7FA4DA0F34699EC3F92E5388BDE3184D72A7DD02376C91C"), - fromHex("288FF65DC42B92F9"), - 131072, - fromHex("E00EBCCD70D69152725F9987982178A2E2E139C7BCBE04CA8A0E99E318D9AB76F988C8549F75ADD790BA4F81C176DA653C1A043F11A958E169B6D2319F4EEC1A"), - }, -} - -func TestSalsa20(t *testing.T) { - var inBuf, outBuf []byte - var key [32]byte - - for i, test := range testVectors { - if test.numBytes%64 != 0 { - t.Errorf("#%d: numBytes is not a multiple of 64", i) - continue - } - - if test.numBytes > len(inBuf) { - inBuf = make([]byte, test.numBytes) - outBuf = make([]byte, test.numBytes) - } - in := inBuf[:test.numBytes] - out := outBuf[:test.numBytes] - copy(key[:], test.key) - XORKeyStream(out, in, test.iv, &key) - - var xor [64]byte - for len(out) > 0 { - for i := 0; i < 64; i++ { - xor[i] ^= out[i] - } - out = out[64:] - } - - if !bytes.Equal(xor[:], test.xor) { - t.Errorf("#%d: bad result", i) - } - } -} - -var xSalsa20TestData = []struct { - in, nonce, key, out []byte -}{ - { - []byte("Hello world!"), - []byte("24-byte nonce for xsalsa"), - []byte("this is 32-byte key for xsalsa20"), - []byte{0x00, 0x2d, 0x45, 0x13, 0x84, 0x3f, 0xc2, 0x40, 0xc4, 0x01, 0xe5, 0x41}, - }, - { - make([]byte, 64), - []byte("24-byte nonce for xsalsa"), - []byte("this is 32-byte key for xsalsa20"), - []byte{0x48, 0x48, 0x29, 0x7f, 0xeb, 0x1f, 0xb5, 0x2f, 0xb6, - 0x6d, 0x81, 0x60, 0x9b, 0xd5, 0x47, 0xfa, 0xbc, 0xbe, 0x70, - 0x26, 0xed, 0xc8, 0xb5, 0xe5, 0xe4, 0x49, 0xd0, 0x88, 0xbf, - 0xa6, 0x9c, 0x08, 0x8f, 0x5d, 0x8d, 0xa1, 0xd7, 0x91, 0x26, - 0x7c, 0x2c, 0x19, 0x5a, 0x7f, 0x8c, 0xae, 0x9c, 0x4b, 0x40, - 0x50, 0xd0, 0x8c, 0xe6, 0xd3, 0xa1, 0x51, 0xec, 0x26, 0x5f, - 0x3a, 0x58, 0xe4, 0x76, 0x48}, - }, -} - -func TestXSalsa20(t *testing.T) { - var key [32]byte - - for i, test := range xSalsa20TestData { - out := make([]byte, len(test.in)) - copy(key[:], test.key) - XORKeyStream(out, test.in, test.nonce, &key) - if !bytes.Equal(out, test.out) { - t.Errorf("%d: expected %x, got %x", i, test.out, out) - } - } -} - -var ( - keyArray [32]byte - key = &keyArray - nonce [8]byte - msg = make([]byte, 1<<10) -) - -func BenchmarkXOR1K(b *testing.B) { - b.StopTimer() - out := make([]byte, 1024) - b.StartTimer() - for i := 0; i < b.N; i++ { - XORKeyStream(out, msg[:1024], nonce[:], key) - } - b.SetBytes(1024) -} diff --git a/vendor/golang.org/x/crypto/scrypt/scrypt.go b/vendor/golang.org/x/crypto/scrypt/scrypt.go deleted file mode 100644 index dc0124b..0000000 --- a/vendor/golang.org/x/crypto/scrypt/scrypt.go +++ /dev/null @@ -1,243 +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. - -// Package scrypt implements the scrypt key derivation function as defined in -// Colin Percival's paper "Stronger Key Derivation via Sequential Memory-Hard -// Functions" (http://www.tarsnap.com/scrypt/scrypt.pdf). -package scrypt // import "golang.org/x/crypto/scrypt" - -import ( - "crypto/sha256" - "errors" - - "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 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 { - u := x0 + x12 - x4 ^= u<<7 | u>>(32-7) - u = x4 + x0 - x8 ^= u<<9 | u>>(32-9) - u = x8 + x4 - x12 ^= u<<13 | u>>(32-13) - u = x12 + x8 - x0 ^= u<<18 | u>>(32-18) - - u = x5 + x1 - x9 ^= u<<7 | u>>(32-7) - u = x9 + x5 - x13 ^= u<<9 | u>>(32-9) - u = x13 + x9 - x1 ^= u<<13 | u>>(32-13) - u = x1 + x13 - x5 ^= u<<18 | u>>(32-18) - - u = x10 + x6 - x14 ^= u<<7 | u>>(32-7) - u = x14 + x10 - x2 ^= u<<9 | u>>(32-9) - u = x2 + x14 - x6 ^= u<<13 | u>>(32-13) - u = x6 + x2 - x10 ^= u<<18 | u>>(32-18) - - u = x15 + x11 - x3 ^= u<<7 | u>>(32-7) - u = x3 + x15 - x7 ^= u<<9 | u>>(32-9) - u = x7 + x3 - x11 ^= u<<13 | u>>(32-13) - u = x11 + x7 - x15 ^= u<<18 | u>>(32-18) - - u = x0 + x3 - x1 ^= u<<7 | u>>(32-7) - u = x1 + x0 - x2 ^= u<<9 | u>>(32-9) - u = x2 + x1 - x3 ^= u<<13 | u>>(32-13) - u = x3 + x2 - x0 ^= u<<18 | u>>(32-18) - - u = x5 + x4 - x6 ^= u<<7 | u>>(32-7) - u = x6 + x5 - x7 ^= u<<9 | u>>(32-9) - u = x7 + x6 - x4 ^= u<<13 | u>>(32-13) - u = x4 + x7 - x5 ^= u<<18 | u>>(32-18) - - u = x10 + x9 - x11 ^= u<<7 | u>>(32-7) - u = x11 + x10 - x8 ^= u<<9 | u>>(32-9) - u = x8 + x11 - x9 ^= u<<13 | u>>(32-13) - u = x9 + x8 - x10 ^= u<<18 | u>>(32-18) - - u = x15 + x14 - x12 ^= u<<7 | u>>(32-7) - u = x12 + x15 - x13 ^= u<<9 | u>>(32-9) - u = x13 + x12 - x14 ^= u<<13 | u>>(32-13) - u = x14 + x13 - x15 ^= u<<18 | u>>(32-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 - x := xy - y := xy[32*r:] - - j := 0 - for i := 0; i < 32*r; i++ { - x[i] = uint32(b[j]) | uint32(b[j+1])<<8 | uint32(b[j+2])<<16 | uint32(b[j+3])<<24 - j += 4 - } - for i := 0; i < N; i += 2 { - blockCopy(v[i*(32*r):], x, 32*r) - blockMix(&tmp, x, y, r) - - blockCopy(v[(i+1)*(32*r):], y, 32*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*(32*r):], 32*r) - blockMix(&tmp, x, y, r) - - j = int(integer(y, r) & uint64(N-1)) - blockXOR(y, v[j*(32*r):], 32*r) - blockMix(&tmp, y, x, r) - } - j = 0 - for _, v := range x[:32*r] { - b[j+0] = byte(v >> 0) - b[j+1] = byte(v >> 8) - b[j+2] = byte(v >> 16) - b[j+3] = byte(v >> 24) - 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 := scrypt.Key([]byte("some password"), salt, 16384, 8, 1, 32) -// -// The recommended parameters for interactive logins as of 2009 are N=16384, -// r=8, p=1. They should be increased as memory latency and CPU parallelism -// increases. 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/scrypt/scrypt_test.go b/vendor/golang.org/x/crypto/scrypt/scrypt_test.go deleted file mode 100644 index e096c3a..0000000 --- a/vendor/golang.org/x/crypto/scrypt/scrypt_test.go +++ /dev/null @@ -1,160 +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. - -package scrypt - -import ( - "bytes" - "testing" -) - -type testVector struct { - password string - salt string - N, r, p int - output []byte -} - -var good = []testVector{ - { - "password", - "salt", - 2, 10, 10, - []byte{ - 0x48, 0x2c, 0x85, 0x8e, 0x22, 0x90, 0x55, 0xe6, 0x2f, - 0x41, 0xe0, 0xec, 0x81, 0x9a, 0x5e, 0xe1, 0x8b, 0xdb, - 0x87, 0x25, 0x1a, 0x53, 0x4f, 0x75, 0xac, 0xd9, 0x5a, - 0xc5, 0xe5, 0xa, 0xa1, 0x5f, - }, - }, - { - "password", - "salt", - 16, 100, 100, - []byte{ - 0x88, 0xbd, 0x5e, 0xdb, 0x52, 0xd1, 0xdd, 0x0, 0x18, - 0x87, 0x72, 0xad, 0x36, 0x17, 0x12, 0x90, 0x22, 0x4e, - 0x74, 0x82, 0x95, 0x25, 0xb1, 0x8d, 0x73, 0x23, 0xa5, - 0x7f, 0x91, 0x96, 0x3c, 0x37, - }, - }, - { - "this is a long \000 password", - "and this is a long \000 salt", - 16384, 8, 1, - []byte{ - 0xc3, 0xf1, 0x82, 0xee, 0x2d, 0xec, 0x84, 0x6e, 0x70, - 0xa6, 0x94, 0x2f, 0xb5, 0x29, 0x98, 0x5a, 0x3a, 0x09, - 0x76, 0x5e, 0xf0, 0x4c, 0x61, 0x29, 0x23, 0xb1, 0x7f, - 0x18, 0x55, 0x5a, 0x37, 0x07, 0x6d, 0xeb, 0x2b, 0x98, - 0x30, 0xd6, 0x9d, 0xe5, 0x49, 0x26, 0x51, 0xe4, 0x50, - 0x6a, 0xe5, 0x77, 0x6d, 0x96, 0xd4, 0x0f, 0x67, 0xaa, - 0xee, 0x37, 0xe1, 0x77, 0x7b, 0x8a, 0xd5, 0xc3, 0x11, - 0x14, 0x32, 0xbb, 0x3b, 0x6f, 0x7e, 0x12, 0x64, 0x40, - 0x18, 0x79, 0xe6, 0x41, 0xae, - }, - }, - { - "p", - "s", - 2, 1, 1, - []byte{ - 0x48, 0xb0, 0xd2, 0xa8, 0xa3, 0x27, 0x26, 0x11, 0x98, - 0x4c, 0x50, 0xeb, 0xd6, 0x30, 0xaf, 0x52, - }, - }, - - { - "", - "", - 16, 1, 1, - []byte{ - 0x77, 0xd6, 0x57, 0x62, 0x38, 0x65, 0x7b, 0x20, 0x3b, - 0x19, 0xca, 0x42, 0xc1, 0x8a, 0x04, 0x97, 0xf1, 0x6b, - 0x48, 0x44, 0xe3, 0x07, 0x4a, 0xe8, 0xdf, 0xdf, 0xfa, - 0x3f, 0xed, 0xe2, 0x14, 0x42, 0xfc, 0xd0, 0x06, 0x9d, - 0xed, 0x09, 0x48, 0xf8, 0x32, 0x6a, 0x75, 0x3a, 0x0f, - 0xc8, 0x1f, 0x17, 0xe8, 0xd3, 0xe0, 0xfb, 0x2e, 0x0d, - 0x36, 0x28, 0xcf, 0x35, 0xe2, 0x0c, 0x38, 0xd1, 0x89, - 0x06, - }, - }, - { - "password", - "NaCl", - 1024, 8, 16, - []byte{ - 0xfd, 0xba, 0xbe, 0x1c, 0x9d, 0x34, 0x72, 0x00, 0x78, - 0x56, 0xe7, 0x19, 0x0d, 0x01, 0xe9, 0xfe, 0x7c, 0x6a, - 0xd7, 0xcb, 0xc8, 0x23, 0x78, 0x30, 0xe7, 0x73, 0x76, - 0x63, 0x4b, 0x37, 0x31, 0x62, 0x2e, 0xaf, 0x30, 0xd9, - 0x2e, 0x22, 0xa3, 0x88, 0x6f, 0xf1, 0x09, 0x27, 0x9d, - 0x98, 0x30, 0xda, 0xc7, 0x27, 0xaf, 0xb9, 0x4a, 0x83, - 0xee, 0x6d, 0x83, 0x60, 0xcb, 0xdf, 0xa2, 0xcc, 0x06, - 0x40, - }, - }, - { - "pleaseletmein", "SodiumChloride", - 16384, 8, 1, - []byte{ - 0x70, 0x23, 0xbd, 0xcb, 0x3a, 0xfd, 0x73, 0x48, 0x46, - 0x1c, 0x06, 0xcd, 0x81, 0xfd, 0x38, 0xeb, 0xfd, 0xa8, - 0xfb, 0xba, 0x90, 0x4f, 0x8e, 0x3e, 0xa9, 0xb5, 0x43, - 0xf6, 0x54, 0x5d, 0xa1, 0xf2, 0xd5, 0x43, 0x29, 0x55, - 0x61, 0x3f, 0x0f, 0xcf, 0x62, 0xd4, 0x97, 0x05, 0x24, - 0x2a, 0x9a, 0xf9, 0xe6, 0x1e, 0x85, 0xdc, 0x0d, 0x65, - 0x1e, 0x40, 0xdf, 0xcf, 0x01, 0x7b, 0x45, 0x57, 0x58, - 0x87, - }, - }, - /* - // Disabled: needs 1 GiB RAM and takes too long for a simple test. - { - "pleaseletmein", "SodiumChloride", - 1048576, 8, 1, - []byte{ - 0x21, 0x01, 0xcb, 0x9b, 0x6a, 0x51, 0x1a, 0xae, 0xad, - 0xdb, 0xbe, 0x09, 0xcf, 0x70, 0xf8, 0x81, 0xec, 0x56, - 0x8d, 0x57, 0x4a, 0x2f, 0xfd, 0x4d, 0xab, 0xe5, 0xee, - 0x98, 0x20, 0xad, 0xaa, 0x47, 0x8e, 0x56, 0xfd, 0x8f, - 0x4b, 0xa5, 0xd0, 0x9f, 0xfa, 0x1c, 0x6d, 0x92, 0x7c, - 0x40, 0xf4, 0xc3, 0x37, 0x30, 0x40, 0x49, 0xe8, 0xa9, - 0x52, 0xfb, 0xcb, 0xf4, 0x5c, 0x6f, 0xa7, 0x7a, 0x41, - 0xa4, - }, - }, - */ -} - -var bad = []testVector{ - {"p", "s", 0, 1, 1, nil}, // N == 0 - {"p", "s", 1, 1, 1, nil}, // N == 1 - {"p", "s", 7, 8, 1, nil}, // N is not power of 2 - {"p", "s", 16, maxInt / 2, maxInt / 2, nil}, // p * r too large -} - -func TestKey(t *testing.T) { - for i, v := range good { - k, err := Key([]byte(v.password), []byte(v.salt), v.N, v.r, v.p, len(v.output)) - if err != nil { - t.Errorf("%d: got unexpected error: %s", i, err) - } - if !bytes.Equal(k, v.output) { - t.Errorf("%d: expected %x, got %x", i, v.output, k) - } - } - for i, v := range bad { - _, err := Key([]byte(v.password), []byte(v.salt), v.N, v.r, v.p, 32) - if err == nil { - t.Errorf("%d: expected error, got nil", i) - } - } -} - -func BenchmarkKey(b *testing.B) { - for i := 0; i < b.N; i++ { - Key([]byte("password"), []byte("salt"), 16384, 8, 1, 64) - } -} diff --git a/vendor/golang.org/x/crypto/sha3/doc.go b/vendor/golang.org/x/crypto/sha3/doc.go deleted file mode 100644 index a0ee3ae..0000000 --- a/vendor/golang.org/x/crypto/sha3/doc.go +++ /dev/null @@ -1,66 +0,0 @@ -// 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 -// 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 deleted file mode 100644 index 2b51cf4..0000000 --- a/vendor/golang.org/x/crypto/sha3/hashes.go +++ /dev/null @@ -1,65 +0,0 @@ -// 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 { 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 { 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 { 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 { return &state{rate: 72, outputLen: 64, dsbyte: 0x06} } - -// 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/keccakf.go b/vendor/golang.org/x/crypto/sha3/keccakf.go deleted file mode 100644 index 13e7058..0000000 --- a/vendor/golang.org/x/crypto/sha3/keccakf.go +++ /dev/null @@ -1,410 +0,0 @@ -// 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 - -// 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/register.go b/vendor/golang.org/x/crypto/sha3/register.go deleted file mode 100644 index 3cf6a22..0000000 --- a/vendor/golang.org/x/crypto/sha3/register.go +++ /dev/null @@ -1,18 +0,0 @@ -// 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. - -// +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 deleted file mode 100644 index c8fd31c..0000000 --- a/vendor/golang.org/x/crypto/sha3/sha3.go +++ /dev/null @@ -1,193 +0,0 @@ -// 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 [maxRate]byte - - // Specific to SHA-3 and SHAKE. - fixedOutput bool // whether this is a fixed-ouput-length instance - 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[:0] -} - -func (d *state) clone() *state { - ret := *d - if ret.state == spongeAbsorbing { - ret.buf = ret.storage[:len(ret.buf)] - } else { - ret.buf = ret.storage[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[:0] - keccakF1600(&d.a) - case spongeSqueezing: - // If we're squeezing, we need to apply the permutatin before - // copying more output. - keccakF1600(&d.a) - d.buf = d.storage[: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[: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[: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[: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[: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_test.go b/vendor/golang.org/x/crypto/sha3/sha3_test.go deleted file mode 100644 index caf72f2..0000000 --- a/vendor/golang.org/x/crypto/sha3/sha3_test.go +++ /dev/null @@ -1,306 +0,0 @@ -// 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 - -// Tests include all the ShortMsgKATs provided by the Keccak team at -// https://github.com/gvanas/KeccakCodePackage -// -// They only include the zero-bit case of the bitwise testvectors -// published by NIST in the draft of FIPS-202. - -import ( - "bytes" - "compress/flate" - "encoding/hex" - "encoding/json" - "hash" - "os" - "strings" - "testing" -) - -const ( - testString = "brekeccakkeccak koax koax" - katFilename = "testdata/keccakKats.json.deflate" -) - -// Internal-use instances of SHAKE used to test against KATs. -func newHashShake128() hash.Hash { - return &state{rate: 168, dsbyte: 0x1f, outputLen: 512} -} -func newHashShake256() hash.Hash { - return &state{rate: 136, dsbyte: 0x1f, outputLen: 512} -} - -// testDigests contains functions returning hash.Hash instances -// with output-length equal to the KAT length for both SHA-3 and -// SHAKE instances. -var testDigests = map[string]func() hash.Hash{ - "SHA3-224": New224, - "SHA3-256": New256, - "SHA3-384": New384, - "SHA3-512": New512, - "SHAKE128": newHashShake128, - "SHAKE256": newHashShake256, -} - -// testShakes contains functions that return ShakeHash instances for -// testing the ShakeHash-specific interface. -var testShakes = map[string]func() ShakeHash{ - "SHAKE128": NewShake128, - "SHAKE256": NewShake256, -} - -// decodeHex converts a hex-encoded string into a raw byte string. -func decodeHex(s string) []byte { - b, err := hex.DecodeString(s) - if err != nil { - panic(err) - } - return b -} - -// structs used to marshal JSON test-cases. -type KeccakKats struct { - Kats map[string][]struct { - Digest string `json:"digest"` - Length int64 `json:"length"` - Message string `json:"message"` - } -} - -func testUnalignedAndGeneric(t *testing.T, testf func(impl string)) { - xorInOrig, copyOutOrig := xorIn, copyOut - xorIn, copyOut = xorInGeneric, copyOutGeneric - testf("generic") - if xorImplementationUnaligned != "generic" { - xorIn, copyOut = xorInUnaligned, copyOutUnaligned - testf("unaligned") - } - xorIn, copyOut = xorInOrig, copyOutOrig -} - -// TestKeccakKats tests the SHA-3 and Shake implementations against all the -// ShortMsgKATs from https://github.com/gvanas/KeccakCodePackage -// (The testvectors are stored in keccakKats.json.deflate due to their length.) -func TestKeccakKats(t *testing.T) { - testUnalignedAndGeneric(t, func(impl string) { - // Read the KATs. - deflated, err := os.Open(katFilename) - if err != nil { - t.Errorf("error opening %s: %s", katFilename, err) - } - file := flate.NewReader(deflated) - dec := json.NewDecoder(file) - var katSet KeccakKats - err = dec.Decode(&katSet) - if err != nil { - t.Errorf("error decoding KATs: %s", err) - } - - // Do the KATs. - for functionName, kats := range katSet.Kats { - d := testDigests[functionName]() - for _, kat := range kats { - d.Reset() - in, err := hex.DecodeString(kat.Message) - if err != nil { - t.Errorf("error decoding KAT: %s", err) - } - d.Write(in[:kat.Length/8]) - got := strings.ToUpper(hex.EncodeToString(d.Sum(nil))) - if got != kat.Digest { - t.Errorf("function=%s, implementation=%s, length=%d\nmessage:\n %s\ngot:\n %s\nwanted:\n %s", - functionName, impl, kat.Length, kat.Message, got, kat.Digest) - t.Logf("wanted %+v", kat) - t.FailNow() - } - continue - } - } - }) -} - -// TestUnalignedWrite tests that writing data in an arbitrary pattern with -// small input buffers. -func testUnalignedWrite(t *testing.T) { - testUnalignedAndGeneric(t, func(impl string) { - buf := sequentialBytes(0x10000) - for alg, df := range testDigests { - d := df() - d.Reset() - d.Write(buf) - want := d.Sum(nil) - d.Reset() - for i := 0; i < len(buf); { - // Cycle through offsets which make a 137 byte sequence. - // Because 137 is prime this sequence should exercise all corner cases. - offsets := [17]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 1} - for _, j := range offsets { - if v := len(buf) - i; v < j { - j = v - } - d.Write(buf[i : i+j]) - i += j - } - } - got := d.Sum(nil) - if !bytes.Equal(got, want) { - t.Errorf("Unaligned writes, implementation=%s, alg=%s\ngot %q, want %q", impl, alg, got, want) - } - } - }) -} - -// TestAppend checks that appending works when reallocation is necessary. -func TestAppend(t *testing.T) { - testUnalignedAndGeneric(t, func(impl string) { - d := New224() - - for capacity := 2; capacity <= 66; capacity += 64 { - // The first time around the loop, Sum will have to reallocate. - // The second time, it will not. - buf := make([]byte, 2, capacity) - d.Reset() - d.Write([]byte{0xcc}) - buf = d.Sum(buf) - expected := "0000DF70ADC49B2E76EEE3A6931B93FA41841C3AF2CDF5B32A18B5478C39" - if got := strings.ToUpper(hex.EncodeToString(buf)); got != expected { - t.Errorf("got %s, want %s", got, expected) - } - } - }) -} - -// TestAppendNoRealloc tests that appending works when no reallocation is necessary. -func TestAppendNoRealloc(t *testing.T) { - testUnalignedAndGeneric(t, func(impl string) { - buf := make([]byte, 1, 200) - d := New224() - d.Write([]byte{0xcc}) - buf = d.Sum(buf) - expected := "00DF70ADC49B2E76EEE3A6931B93FA41841C3AF2CDF5B32A18B5478C39" - if got := strings.ToUpper(hex.EncodeToString(buf)); got != expected { - t.Errorf("%s: got %s, want %s", impl, got, expected) - } - }) -} - -// TestSqueezing checks that squeezing the full output a single time produces -// the same output as repeatedly squeezing the instance. -func TestSqueezing(t *testing.T) { - testUnalignedAndGeneric(t, func(impl string) { - for functionName, newShakeHash := range testShakes { - d0 := newShakeHash() - d0.Write([]byte(testString)) - ref := make([]byte, 32) - d0.Read(ref) - - d1 := newShakeHash() - d1.Write([]byte(testString)) - var multiple []byte - for _ = range ref { - one := make([]byte, 1) - d1.Read(one) - multiple = append(multiple, one...) - } - if !bytes.Equal(ref, multiple) { - t.Errorf("%s (%s): squeezing %d bytes one at a time failed", functionName, impl, len(ref)) - } - } - }) -} - -// sequentialBytes produces a buffer of size consecutive bytes 0x00, 0x01, ..., used for testing. -func sequentialBytes(size int) []byte { - result := make([]byte, size) - for i := range result { - result[i] = byte(i) - } - return result -} - -// BenchmarkPermutationFunction measures the speed of the permutation function -// with no input data. -func BenchmarkPermutationFunction(b *testing.B) { - b.SetBytes(int64(200)) - var lanes [25]uint64 - for i := 0; i < b.N; i++ { - keccakF1600(&lanes) - } -} - -// benchmarkHash tests the speed to hash num buffers of buflen each. -func benchmarkHash(b *testing.B, h hash.Hash, size, num int) { - b.StopTimer() - h.Reset() - data := sequentialBytes(size) - b.SetBytes(int64(size * num)) - b.StartTimer() - - var state []byte - for i := 0; i < b.N; i++ { - for j := 0; j < num; j++ { - h.Write(data) - } - state = h.Sum(state[:0]) - } - b.StopTimer() - h.Reset() -} - -// benchmarkShake is specialized to the Shake instances, which don't -// require a copy on reading output. -func benchmarkShake(b *testing.B, h ShakeHash, size, num int) { - b.StopTimer() - h.Reset() - data := sequentialBytes(size) - d := make([]byte, 32) - - b.SetBytes(int64(size * num)) - b.StartTimer() - - for i := 0; i < b.N; i++ { - h.Reset() - for j := 0; j < num; j++ { - h.Write(data) - } - h.Read(d) - } -} - -func BenchmarkSha3_512_MTU(b *testing.B) { benchmarkHash(b, New512(), 1350, 1) } -func BenchmarkSha3_384_MTU(b *testing.B) { benchmarkHash(b, New384(), 1350, 1) } -func BenchmarkSha3_256_MTU(b *testing.B) { benchmarkHash(b, New256(), 1350, 1) } -func BenchmarkSha3_224_MTU(b *testing.B) { benchmarkHash(b, New224(), 1350, 1) } - -func BenchmarkShake128_MTU(b *testing.B) { benchmarkShake(b, NewShake128(), 1350, 1) } -func BenchmarkShake256_MTU(b *testing.B) { benchmarkShake(b, NewShake256(), 1350, 1) } -func BenchmarkShake256_16x(b *testing.B) { benchmarkShake(b, NewShake256(), 16, 1024) } -func BenchmarkShake256_1MiB(b *testing.B) { benchmarkShake(b, NewShake256(), 1024, 1024) } - -func BenchmarkSha3_512_1MiB(b *testing.B) { benchmarkHash(b, New512(), 1024, 1024) } - -func Example_sum() { - buf := []byte("some data to hash") - // A hash needs to be 64 bytes long to have 256-bit collision resistance. - h := make([]byte, 64) - // Compute a 64-byte hash of buf and put it in h. - ShakeSum256(h, buf) -} - -func Example_mac() { - k := []byte("this is a secret key; you should generate a strong random key that's at least 32 bytes long") - buf := []byte("and this is some data to authenticate") - // A MAC with 32 bytes of output has 256-bit security strength -- if you use at least a 32-byte-long key. - h := make([]byte, 32) - d := NewShake256() - // Write the key into the hash. - d.Write(k) - // Now write the data. - d.Write(buf) - // Read 32 bytes of output from the hash into h. - d.Read(h) -} diff --git a/vendor/golang.org/x/crypto/sha3/shake.go b/vendor/golang.org/x/crypto/sha3/shake.go deleted file mode 100644 index 841f986..0000000 --- a/vendor/golang.org/x/crypto/sha3/shake.go +++ /dev/null @@ -1,60 +0,0 @@ -// 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 instances, as well as utility -// functions for hashing bytes to arbitrary-length output. - -import ( - "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() -} - -func (d *state) Clone() ShakeHash { - return d.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 { return &state{rate: 168, dsbyte: 0x1f} } - -// NewShake256 creates a new SHAKE128 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 { return &state{rate: 136, dsbyte: 0x1f} } - -// 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/testdata/keccakKats.json.deflate b/vendor/golang.org/x/crypto/sha3/testdata/keccakKats.json.deflate deleted file mode 100644 index 62e85ae24236b46c09e5cfa84c71c69f5cc33cf6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 521342 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%0DdSPIES;LF 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

;TQ8)#7l>4Snz*J)FMZ0Q-2>;ACWq)?04 z{KkU8ZD7LUQgu>@A=|8$d%ND$tibIvY5|s7dN*s`P+G1D05)v14kM8?)#m=Hiq5o* z*S6%XcTi;6bBrp89z{SixoY1t-IiN&1J6i8< z9fusdj-pOLv_X5RCj-6eb(|kZ0?Q0_^Qc3mCy^)}PRsM>s$vA&3d{Sd%M_4HF?NaX z7>it?UM2H$A)7Esd_e1W81xA7o~pfqS}*ZBXuG|F9)Tp!=h~~2WBs7~G+*+wb!Fs- z{8pb|D;p=Jrz(Rh-ElJq-i*-pfwJiOj5Pqq2}h`9!9eu7V5QqV|XUTTg%?mS91 zDjJ#2=M?>nc3Ros5$RTS=gmW1-h3I=k?Au`8HQ3622_=iOOM(dbfuwza#LM_j!PU~ zXpvR$bICWowY`tU$-kIpfG?&cJ4F*-;xp%(e&jLnl+R)*T^fl@i=%?3ASaWLKu3W5 z2;ZrBKS5YTyqM<3#`DtbLQ7?QnM9^wEhw#&_MW3v%9>KQ8vEM9s2g=SkJ0O>dWC3P z9{SMb0i;7+s`M;}j6t$Cvx_Upb=MBKHWf?ng}!-@f~PhNwD9E-9hNosNCIHrHVIxO z`WjK|Vsjy?272-7v1fQG*K4qA*VNy^2G}9XVtAENN(c^{okvXy|AN}i2eKY0l%!_g z6QcB&jmeK@VrxdJcBK=!TlltNUX~7ScE6|aj*$DwdXs3?+CgF?LaL;$ootQTdrx4x zDqWBa6E@X3Aur+4o;(o5lAECSBIe?W+C&xZw(;mCXA29C>s!psyVua4( zCUMI1jTCc>czd@&01`&7X`h@nYg-{74=m?2hC$Z2Q??speJks-${Iw9xqkFDISP(cc|^L+xKsr(_N+ zD{DS#m%h%ncR<(j01m_HvWkw-V#y!8Wi}Uv;GSz2eh4cKrx5Xa?}W#Bv{)a#i3d3a z)@Tw@Pf9=zV$HcaC0rKJh{P=HN}h5oZ5X}1L3NdWSki9<@s)TL)U^k}Wz8hGj>)rC z9fKGUs6ig+P;h&PqL(A}<~c*p^>ox~o?uLoQj#5mhh~vWFj6nE z4qdZ`DMZD+UWxYvdl(Fbn<*&#MRhC5w!PH}!7YziS1AFc9V4O$@go;Vi!LX^93uAg zQG;|a5{z7(JMXKrByfEE!>saWjLO@x@sql@D4MXbe0I7oj_uj{Z1 zM<PHNJ=wK;{#D=i+aw2^>`#K}Bs_@NORA#8FmS4y_$EhQI)C0NL16-tmV` zD6(h`1^$Y5sd`IHqIG39&!dw#dqr7C8P1OUAozttC5BDu zs-@dKb1JKeNL{jXI(%=cb&RN_XCcV!h{4qGj=2%h7D?q~J1#3BgSFIVNWEW$)na%J zm7vQO*fYPH?4{xgYoDbCLDL>|Ey#IiBRpvasKQ$~cu4>l*qfmP2h^^eNoKb#vDon- z>`DfPp91V-crDMu^SwRk&UzyZvN9zGN!l-=rXKJkzn-W2$Vw)}0$*lN^ThKS05J=F zBbSdKLL3{$I0h9G8O>b2=Zch>JyqNlxJa?gfQy=HZ}hfMDfqEm4{TJn*Yty}?S9od zeRCu^)x~6HsdwBUCE+NBd7kf0tj%M2e10A$B8e$tidRcBsuk}&aDsVT@MtVWrz|q9 z`x!lk3V9I5@&w|Dp)Rs@dSDKG2p8d#YSb^PLAz?zHaNqa;BAgJh$W^JgtK{Zao3(? z*v4yLrV}wTd}4A<>CWS89*}|e_!;BNdM}r0D-nJ8NSk)M0_A)?`Wb9 z-t`pc^uv}Xy7W*S@?z2~p1lNE?iAw3*UtbB-}eQon#gA`sL)gdnp z_qi+ND=y);>X-XeQp*12|& zfwnXX`3Q^Z*1_@FX(i<3X;z-p`D`j!X}h+0tZhD`fQMBYt59hyCyE4)fK$t6oVl-i zZ1Sx(D@lPd*L$lP)(=(SE*L^u`pON6FI$ktvFC-1=YwleT3<&SnKjr5T&|aO5GaAB zvH6M#!;+6@n@#TZU9lO!`lBl_DmH)9#|+5IG!YLDB57Z9I442v7%mU(V9Tuu6r95w z_P|7PdwA?~&&Kw_=Hs&+M{U7-v!fJk#}B&R;f}E)ERV{QS&%JV6N17%Re6*2bUK#L zyVGk+L-QzKqcqd%xi#(L2H;z}eYhTYdZFS+O9sjGP}qsPM{AA4Q}4<*wRxpHwGaEf zhurW!u_pe)`mlw(&+LU88`$u8j#T(ro1w-mlo-0t(R)SHo>C8YQl^*!XX4aXE9Y7H z*l9-tFxRUyuIe{7XyJ>`4WeL7)>`7t>+WeRf;KcRUJc3_C&*q>8kX+MB`{kzx6sFi z>Y$LQwB70byfNLMK#jgCd4Z450B$&EMnYmqQ#lk}7wky5KwHkIR+1BM+}M#4XEm+j^~lQ!qep*n4R##w9i=sed&QVMVrbl| z&F34Ei9jLX6k5emHTSAf*mu7gVuI5;v~XVIia~3LsYT zLiQ1&KErzU%tJcjDrBgI$tz=e5Oh!J)P&je(Ie(kn0%M$rgJHkBs$YNtvrlB?ACEiFj{|j8{B1(sF`Lz6>_ZJqo3? z#V#)Lz=jeQVM}D~B+q#p-I{e8V{_$J6y8Zf&&}PJpgXH$V~3qdDPL*gx!7s|ya!op z%)+U(G&{Hb^3H0>m!DvBHrR7`RE`aINO{FwSixtAk$RNHDAr|7m&NE7!7sst-s?S2 zWubQl`&v)6W%rHTR0I(f<=cX|%j#@bTPPaP5b1JQ+gvm?_fM`LeQ_NV_tLgUuozFp z=mrMdaUZ;ZxiW_coLrlF#ikhe*w9xm+#CQwK)%0Wg-J2yGOYxpP0OA@D?b{q!@jLK z1dR&FCkF%EHHQxh=GxrkIC+(N%2!A-XROzmgdo`|8~q@dY0MwUtxFp3i#3I0f5uKb zbo^`vU(q%KQ(j-p_VimfTY)=9&>Vym5_&L*LGXyv5rQWl&Soi_W-=W?J3GI=#ugWr zU56)BGtU@iG*K-mm&WxFm9fgu`cJTJ-&GDVN711&sS0iqpE6x}S1}ZZ#?>LTr1o1Y z%%Nd?jpu3JJ#w4{m5{(fv0LwqN<}vj9`poHO0SlVHM5a7^xoFkrG$aK^V%D&OnD@M z-dLIa%4cnGxr|~_F81J@USmX}AMqN4L^aea0w*@;3TbkmLUbN+G22q(u z9=fk|YD(ams+tF1(>{|!!|`pUW_pRF#WJt)mG0Y%zKZf2lDafbw0K*!i0TGXmZW<~ zO-#I@9ux5@y@4!X{q>^iOj-N$SyVRW%0e}M^iVXErI0xv*X&CMLps1|pk-5J7_iDW z%_lhN!A8dXJZPK!IllogA6-%A)wTSPU0 ztAKv9@5Nlj=2NAo>|hmmHiRG}0gqEp92E>onu|CmS4bM`Xh?073m#Z7Nb=K3CgpB{ zqI!@&M0to319;jVV&@CXvln5H6MD+x6KwuoFrtOK8?j?t<-EKMvUy@=p{lT&jx99d z8xI~SjwGi)dUSdw9*;*L)8AbzK}wL$ZDlrxPz-=>1-+JB0rnkX-e$uc!@!+mefpk1 zC%!;2je4u@5ZvliKq$Df3%G(%{IK0s^3F?3k4~aX2Pq~kHmr51{8C#d-zhwd7#gh3 z5;k>8#~$rdITb-9e1T(L-SkRoV1sB|$Lqp6gw}b6Jof@3D-WkGUQdJ) zN+QzpzsN3ijYIS}q0Q@tC+{q8%E7dy7xXR7G4Q>?hnzes_JlFWHjY~@MY!5&!}=wi zwpz3!bxf)-sUs^^9zfjNK^PlqF(mh7+&jItH+P=-x){j4ojZ1lyLl zp;SS)zUNL};kYH0ezp<_1{YQ@MGf6^xLM@31Gk$xoMHj=MVM%|4Ka__VlkU05lAH7>ExMQmT; zL*4N^tPaM98y2?LkTel?K1tN8v+%@`JTLD!bV^y35YpA@V#qa1^#QL%Zx9-1^$avm z3HZTls$FQe(|$266%W1MT+6!62nJmYu6`L-sWLHBDnO2+0IhMl>G*mP3X1YR|5 z)tvDhco6E5Y27mu>ifdw2w-As?&7~&!yBc}F>kH8u%Zqieh z4J&OF-dB|`>j@*uvugJT+jSwY$_aTcWc5lit9rrD2hc*?*#q?!xZcpnX-ow@CW6WL z-1j|~?h3%*kN`4>m+{Vk{hsVgDfkhP7UTp)O#RpZuGY>LpaDj+=5k4AI;4{=jqtq- z3*u3uz}EXF+ds)R-FreX56Y4~qP$^bpTx4XphwOi!1AkQiUhiPvvSAhH?S5HsxQ0K zsE4A1#i=kTC`GKL@S#xHp!!t_Z!B#OK8I*3x!wrhX%z!uS>%YRwJYOc>#=*{^oo!Q zr0$)hMQ1)H;+s)}c~7njK~E;AU$7qYyu7YlTE=V<9$z(ydymSr)+6B&XCk$*)8OXY z^_U%wr}y?XIPlYx7nk^Kja%nEkD8NY0pn(?wjwA9b_Pq;agn9_3+>%GXXNb47Z1Bj znz4Xo4LnG@)m!jAqoS0K^V%|PP+-NLnq}8>3?bAgRsls}+!uyHofTBdJ(3GxT-9Qhn_7= zSP`|d@(2O_J#krME|uMU2>hPi<=rui;QNoQCZnq zecTR8tioJjn~fG7kM>!xSIJ5{Pd#FRdli?$?QsL|R@@cK*Hhd3jS)y$sw7YaEHF}Y zyzJ`tTox0<=FFvl_LvH4t48?YuEg9!At?8KQ1eWyd5vHU4;wmix#?<=baGZt)s}jl zq!SVSq@0e@^+swOl<-n-6WP@F27FAGn^A9&SPB|U)aRIpdFo6RdEp))s52of$AGK% z%Q|cia25nrs_DLXgr<`hFJ1v8-&`PWdnNKZ7AX4)l9rWr<6H+&${VOO0&WtWRl6!7 zIc*wlo&sm*MCOO}1j@8vW;cR3ePO0~wPG#>DJvdzZBQLeo!F4Qf&$UhnWLzDns$!QUx2IR#CDrjwSJ;4-%H0iLZM4O zeq!y$C=@ehYyN^{-k5Gk( zYwO`AUK)T@f}!auOqPxLsUz%x>oFbpO31-Bp*^Dt4})%fgkm~Dz0c43g(btQoJ3(C z0_n#u8)CN8^^rV#{mOLW9s&7n`qm>s`HOAE(uKf#>9zOVm7VQ@Qsg6%SGZ?;>FSZI z4G2mnAlt{j&I+Z*5x8C<;zvB#KrQyLP-Gf+MmL;W`UI=xM=Ut! zdbC?M<%tEg&O(_od+vG55qqcJppckBdoe#wQxWpVeaMc^FJoU42qO5rDJ>_Jv!^e_ z*(a&RL`r~+wML_zR$JH>;Wx8JDRy9!Y>GsqL}6vvv@5`wUJp5e8#+Noq2k7)SLUcg-B zTh?o7P<`p1sA zif$eXK5RGuA7ESUrpNMRg6%+E*vSnUh9A7A5&^4J>@4}#dID4pUNnK!VENN#Vkkm_ z5}re9RvIdVyQNVq7Ci{qOVXCNc!EO|G!MULZRIbv-=aK$aU0z#Y0rrmCPC?2v~Y;` z+R{(UtLh;28F}wz4uO!;Yp9WU=r0f{+4a4v*95=|#?fxcSfuI29xU==@QyLLNQ0Gb zFrsdISe~(oo=66wZV<%Fj$pyuE6R(TN26mWS8Zo03?mTM5W3Z`UK*h=&Vs$fZlJR( zxWbA@b_Iom-pSFyZdvj|l_>G$3TuaD&7PL%bC^j3r1a+ufu$-skVQuG^!27W>bo-St80@Wx_rX)rn|nzO49t!4aNY$a zkaTLi>nw>0*rBAE_l`~dM1QHKb(_cQNAX;#i4(BTq8S+&qvcA*-l)Tj=w;*G&WSxQTpHBxI?X!*6cZpTblhAlFk* z_m&+?!`&@_x9%_U8J3UhS&2_Rc{^9+fpwD7U7L+7M?2fdOg9##`LJA;4QNh%=Oqa6 zlCnpkG&H7AF~6TZYIs9n52(0uD&rU{j4Kr_Hc<_iRiWEY^2r&dS5)Rsv)COz(pR7~ zr66&|WHRIr3B7=emiTaAy=m^G4lc$9k)7n;mfxAS#iZMZ41*^y!eOmL|g3%>fN+tX8duycI|4t#e*oiwYriDDIMY_Qq30Vp_;o&mDiFF3{;NH+E4vhCa&cQod1%uEE zb4$T4Q|EDDxK=fU);BIG2s1bHP60$gkU`gu&<@Gf9ukIWz^-q;w;E3#Xqo0XD)74= zArcAG3k~dtdG!<($z4sn)^h`q7>PxTUkIS(hUObY-zT_BgLajn_414~3yby+@cNY( zPcJJb3mvSw%Pz;WdR#U0#L{1?XUHJcMbBbOR*pfh<%2Sg*-K_!>OwqlB7H7tIPp5w`n0=!%a@&*N5D7XNtQ(3SuB{|oeT7En1vrlwZ6B< zSddIF)NztLU-cE;<;w^Ph=l}XH^;|aPabl;Lwmzs{fJ|O zRmsj74625yNTC6U9R&73TS9dR3d516q)ENiV0~Dn+@?=<=b@h9L*E#m z#n%Q&SqYrT{?tY8$+ClxmzfSEt|z?`w)XPTgn=kxoL3vq3>CVQS1sNEq@YYw1a;Z9 zF-~@(AwQgq=w3ZDk3)*3Z0S=ehB0{Xq=(R@DxS6z08O5EHCbB5ig1Bqs6JrU)PqE> zM3EiR38_)CG6HEZ8lX~`f*V_oO%QKds3f4tJD3ezXX&%}bM7wf&Yai-DHSXACn{p> zAh_?5K=Y*n)Z>R63i1kaG-uDoSGsqSL?^VX&+siqcwwBwdv)-rqbNlmL_IW-Dfg5v zMAb-+JdTJK!R=*Qjj865SCB;pLLsRfPkB9;L)zk%y=*?oOu)2MJr<_ql%mKaRTQ81 zEV7E5R6@Jo8is5JA_-VlLSxnVUW&PpusSYccAZLw8Ac2Yd-U)V>p8`P$ydq{;&*S` zI!kt--x|rb@}PIM*A#?>+V#G?NJBdboZ-mp=U2u2EKtS@6;~ag-+04jmSW2e$haXE zz?yhaW(#U8Q-x#`SdxXKI;SORMcV?LWku4AGd~N4G}Ne$@DyFhhZ^s(WXn62inIZF zl-&*s@szmbF+QZVqqVz}0z+CV#5is}>BJTBhgelBe>|xi}MIiyCv)PB15lOZ+jo@22W`f?2seHqOdYOswg3I0EjqMpN z={iAFli=lvmoF^!WTzAh1R57uhv!Ze^>f49FiP%+b9tSN5aANQli69=NW3Z`N@YfF zr4v*3@_CZxz#3~AUV`gsChrRZgLnztQ>_v4nh2zCr+FTs2G6@Jf7D|X+a!Q{G|zPl z4H6J5bKm+)+Z#lVdICEV$HadvU*q_Nl9y#s$?FJADSUHZN_J6q>`ub->BNds0F zlD-ZGnZN+wSSW!tmbk3aH{M!R_Qv*CXZs4~3LFX(d`kzcxSw9Fy(ac6*Nu2-$(&3ADDldT5S;SVpY9c^ zfOD42;A>LGm&p&_V4%OQgAme<(UX7(XiG(ecTWBGt$3=v^GzIpcG(+O8y>qzSPIdn z@g6j^R;^ZWGfR zaGCb>^V-elyL@kXYzee(ry@4)by^X!m5S3LIgq@aVnQx3XMYFQmtn6sqz`XEw0B?WMZZ{z5n~b*+uZ|3w&29shmcZsD1`wB? znO)^87RKlG@NhxI(R&q@<6w9|O@-Jp%5Tf(lkd>a*}Htyt2|BY(JdJ{N~$Mzv}8Uk z#@T7-cxx&og9G^Hz22Hw!j!6zDN@uhO>eO4W5kowYCT&hvFtSOCJRWtC=Yk>>}ZQZ zl{?~9RWo_GFHVeVWgNF2DGM<=BFa572NJ8R$lcaFq&)H!x6TIj#H5f{5;^K{+{99} zZ~N&<1j9UAoHzA+@$D2vNy9Pl>7Cm-Tzjo0k=zkoRkW8Dj=cvh<_tqzZBn4+Fb^h2 z9aNY{5c0IyT-NDjzlHL@0LKjw0zsRKyP$M`GpEMAF zLEhk;0cV<-;J8!d#yNW<<`(soqx;evh6o={m*66Io<*<^hYci`_p1eZBG~HVKK=G- zmXAFrxN(Pjp&ZJWbqaL>5J7e%^R{~Tv9)l$wTcX}gC2w&l!1(-$?R1_(f2YKVA7r5 zvvmPUen^6KiS-ad0eE%c7!KgHpGU@x%v7DN9qA!S49QWWX>l1IG{9^Hy4=CCfZq%( zh~@F|(A-OuxfDjt>O62AK=fM7G-ylYNyZ9Aa^!wdx;C{H$tX9xmhJZzSPyDRs$oD9 z{UzUBb2tJt;Q+odq_Hb@Rb%1g6t33ZCxT$4w#1?)0F>=-0g^OL_vh((E1?qfvxIkb zHLYhg?kN+Ywdsf#XY!KRm6TRl=sYybkD;h0>_XuAl=|&(3Sn@?x;V`lML3UC+22eLttfaI-16vj`~+T3L`>n3W`mHF1EcreiIj`g`uNu&6i zyET~9$FZHH>o2Av;!GObh((lN1`w+@v7v#+Ue3<*#^MoMpwrC*mF=obFFM`sCG^+KD|I5p>>7%z7tp zXCO?QUH&3m&>iTe<5DOo4Q}cv4~yT z3{Oh8NX$23uUQjeLu%lb94J<*Jr5pGj4>Y-7*tuUNv>=BA;LB$p$>CLN+K zRHdX$URQ{Af!7%w;Cn8wl91Ak5kUgcCA8fwq{Ha^PDH`#oXQ)?vt)pAT}RBhp6u+R z!d(yOLl%T-&Wnm`!H5`xjznONmQpHlR%By>N418q0>zY_!PM6F%yhE^3vTb(3A3&D z5{8rN+70eAAL*i_(7ZBJfKpboOMF#@G0CLleoSv$6|Dv%&HTLs?37aHnwH9q7im#S z@QUd8itM;HXzSjy3zXOM#(WY&8rHPK%@WgLD3|A~S2X?H^d2qZw~MRH;?=u)3^Ig3hn28}rkRyA?QJSLDsRMEOoN)#j)@-!Rt^JRe5D(;7{_f98~1XUlUP$*(8%RBFve5QX-YL7)kUYsvN^)a2~}Cy z9u+wgP4lfd^YQ1bnD81?2mNW0&7=-#?5LFO6M_c}nB7jQ$9R>z^mvG5_fg#;G3ePT zLDysFQ4`yHSsL4;CK)6^0QSU5OCOZcDj(s#aV~t4PZp1J*|TUJn79#YwaPNh&*!28 z<=JIb;1rKIlb_BiJ!J|)#*MVQop^^jI8Xca7Kg%GmtT)p;NF=OkfDUQPCsA}6wyTn zOl=WK2UgT9GO^K!y25?Nq~Wh$+~YZIywnEgn~v7^N;BWXmK7kcL6_vMdt1=S-7jp| z@fesHj~3r*vk{#vw;*CoUjvt8-tzdcbs%k3ay0 zsFV;V zjHit*b|}j(x@=H%-}ZAjWUo4Zm_e2U^j@G zO0Oikd2_FBPtZm>pF^8@h}bx#CcMap~>peLSfl4QuARsvBMf< z(33*iCWC;Kd=E{Ms>sK4noW9d-#c@7=e=a1MrhCRfL1ME@j0jAVGEHjH06Zhvv+!G zq{P>oKA3SXXmB|XE}?2j;7Pw?OhuDnwFs|4LOH$XswdCcF8b8>-qKYGS4Z$HJ)m-m zmfcj}X2$Ev8ynPIzKy#JuLD@ArX1m!z`M9fo-r$J6VAX88NA9I_>1wEz^3g>?4WjV zp$906J#e}rRS$2+U?@k9oDLoU^G^s(fp%d zqQD^rz~*FbeV)0J9>CJbxTqyc*XZ%?MIT31>Y(jaUvgk1w!$d%6h7)bP*0F_yp(>% zWbgK=9(N|HyS3yXxz~Vd8RO97JAIiOrfW*r^24;w{oQ1cN6LD9hKJ$+WxD%qw)FNBES%M{#t zoRnzX@lxY8x@}m!y5#nbwi!W6<0IWO-d*B($0P^cAP4zUA2{e$DDbn>ouYnNfbiCAHK%$4>G1+fSDYSFNYfu-%4iM+LM#{G+Nao^wy z5YB2sk2#I<%Eynf%z8%1*IZ#`_Bzv|pd(o*hs!DRfz~?9(=F?rt_AV2a!$=XCoLc^ zPawn6$bJfvp-(pBWD_zC;NF(`lWJi_tRM>I2hbsJZ;b=@saaEREjZDJXb&pCS3s@a zob*Vj-^HR}GHP+?Be61n3(rrBM>-A>&J9(lEtMm!dZ(+q^=QCIssdg&hE|%kX=WTk zVnE>_sz=vsZv0#LH^o&(BD#(po@*J){<$r>!B_d9IN%{3YT*y|d* zn0&XuM7b4-P>uz*-Mi347Hn%XvQ%W24u%dWb<)Wl^)_YOI$OG?EtIJnO4y7dAw=6= zbchbb=M76qFb1@X_re%2S%gC#q-qj=L!Gb(gvXPpmQ7(NGlT z8z3P_$GjNE2w30_QzZpwT-Q*Uk|Sd+*-t%Qb)2@eS~25-ZTel(BcwSk2~aSoxUn2d?nyvmjFVd zJB%e7aONlEBJC5Xo?NPWy);S1qGM@mjg}=xSGXHc7OUZgw4u*X!ru*;GUjse#!8^~MMdVzPy zX|%cZjyZ?tTwHbb_zjz5LOn6Bj?i`sgThCDQO+@T`BL95D&ofWUb>&dT<7>$j>c+w zL=NyEkh|m}W1MfSdf4G;JVUd^8t+8lv?j9h>B(Vx14-3LjY;HIGOe0$4n9E5LN!+> z*?j!!If9gA9IaY%YdhY`OgHAd%~6t~fQL77xQBk6xhT8cRC<#9p03os8=DsfBS4CG zdJ(jeaE@O4m?{v8)Y^@q?B2r#rB`C{hLLq@yz=SOK?>x#C*4=Ot5o+E;Juk4MdV$B zNM+m+Zoy*w+BGpQ(_*%Z3HM0Zk>t-cxTr}`Air&=FQ1=pRTRA&W@ zSJrFfqdrbuZpH_BOd>z7i|T2_&bi5JW4Rcgrk7X890_s@a^3!}^k+#*twn*Z*t}(u zhdbT)3UkY}R=9W0RfS*J!`@|N?wyA9?2BE>BNo#b;z=dNed>KM5OCobs^HEh?8tbFQx9HE;WNWM3^hIs-Px= zY9;x5+Ao$&9jaVwn<8+W_KKlzHC%#u=N0-=cH0V85f2O2hRmrRt1HsD@ z?%m9SanAQ*#u>qbLiMG<9=+YkOW@7RpS*WEMIB3$7M+F0NpVrZ$2D4VJ^nx)ZX1EHHZi3}JHyO5; z9XXfAv=r-p0t=EnU3efgamTsyyk&7z8l+#_lxL(iKrYoQmfPv{eh@|dG}0;*JoBjl zN*>0$_aJD%xhO4L`nmx3s5q@y)#xUSD? zBR<0{f3RoVEo+ZUw6y`>6KEu)0DMGsUC=Xg_#QLc+ZO`;;<4)7l*HY|iql3}oW%12 zHl0P1>!)|d4X>}%r3<3&xaskc(L`aTCW*oWXXW0fGYwnn`f`}c1~>o$8zhaTQ;yv0 z!ArOSuRE(GQYmeuB5{T%Hre*1Hz!uXZJuWs6ZY^53;I|?AB4Iqls@)BdDxXdjD%_wr^DZozfcIe$1lt+**5`Mc_we|MjKkTZkT6zxGou7OvuqEpw0&S`x~NztX!vSM z)Ee@wYYnESh2)W59mTb_N-*|JLBO5$(1UCt^(#mHQ9Y`t}K;DIZd{E?$+3<9U z7X@oQc1wFAEiE9g`;H!ubs<*7)`|B(i^mbvWb?(rlAp=G1zxE)TfGXF96HWEYL`|V z_^1ub&2L1+7Mv1&JMn5Vc)0$Y%`Gwe7@qb^r6fK}T12)JqnL8n_oA)WGE&zRUzI|$ zi4l+3TjgaSI|>DQYf7C2=MGug_K<1b;5==N0I5o3duZ-36NHc^H`XEqrbmpykCwGv zd^O6>+UOb83c`UMVVKRPk_qzZcGcsV9_^EHEx_70$a|JNV$-yVod3g!+2h8qtwi=4?RMq9!dOwfV?A)Jx5-%-d0{C+W(VExT#hWi^P# zX)#Yi+Z3*w#>QW2atSfOzME4{N?V?oXo+|r7Q=$7=(iCTg&<1xRg7^Dx!)<$D;r!FgzIf@ z8L7vd*n>-5!3!sl!b{1H$#Y6`S1T2%7Z%j&D(JNjh*K_1HY|bgl&?(yS)V+^j_LLg zIx1mcadMHn0uE8Uw*-K1joTCCh93(mp?B-DzEcvEV&Qt?t%yefR56H^!_SpCOdicS z&)Q2M5N3(8=nB!*xg(18tM+aYA5~ohRVcTL0)IGX6g_T9borhKPV^RaTkjU$LsftZ ze)L!euL-digEd(1y-JDEl6OJi=ZBa6l!Tbs``pq6I~Q!AdtFz8OE$X?iVxwuc^Ekx zg9D;(g|yr4x)+~o+lf3IgeP?J$+^N8=YA@u)e`AqAb`45xppfS4zmx*RCr7F_|UFEnx3ImTp8s{Elmw;S_~ zMR{v_UTNFf?i`MA5?5Rm1;7uT5bD_>MF^>@9y3TRpe@mcb}gf8!~k;ZCSb<_JTC-_ zaObJ*hY?jEIUT$qk|^&HMkAu!4y+s@krx;q!;DxnF--V8D|^dGw{Xb@4++K^S}lxr z=)INMdH_kJAZ&E`@>RP21v(vQ`y1(MGwoPf4q&GVsv4h11y%^;3#{TagBF5~uji7i zK_$rvC&KPo@8G=C*zxq;ev%@Mj8Wuf-~g$b-rXSYQ7aeZLr6T%h}}r^oyXJ-FFi0` zl|JW4Js|g@C~!ak*oJ+fc;m9#$L{d(fSewc-_EL&wKefozn7%xmQhLw01VGtZMP5h zVletm`z^Iic{0bLdWQEk1^~YsUAlX!-A_amgZ9OsDr4|y@VnTQVl^27K?GRju*NWG z3NisLDMK5Yy6cWpO2~fCA47Yyy?S94?nu>U1e9t_nqB^m6XB^FlT4h&dq`q%r(NS= z_Fk{OhR?>A= zt_QldGMixx;ni!XZqJ+Lz#_?HquRZ|p}drsaM;82_W;PBC!s{c#ZB%D_9$If$(ekc zI_;|_%aSZEhKNa99Jep0M`$mXkxO@(9y2gTJ%oLICU_i{vlBJ1w*!rm-d(%-Ox!8F zx7pF$YZ_J=yQffUs?u9o&9A;e_fOE-16OEaSkUniLcbe*QZEu-YFXMtD?9XN3J9G1RTb7Z84NhhSqoXOrAyB7LNImDbW?HXPI+m zR`SZ@)VaYqy+jej$GAqaL+f_o_N=?CG=$3u8XB3xmX z$Qq#PR5CX%$5>l~JMcPRsm-E$g0OKslgBD!iYzDR3OhsR_ZlK+6JPXO5X)9(w@})* z`+V^#j-pDgkH#S4FS+1 zy=XXEAV|FB;nQxi24maKXT@ifh)}QGQ1(rMO=VWWibL}e%yilIDinnfVwUxui=(`$ zd*=g7c1kFM_0Z(;hB}DpC`C(e^n7pqTouK+>KOfP2SHr}^6) zym|pyRR^Ut-Dc7m*^d&tYE)|+CM8g)!W@OyujeJr-3vvua{T$WJK3G1yRuLhbX z_hFF%v?BR?eEh<(_7&kP97{wWiMG{Jj+d_Is)_ofkzAs$A_t8X(yUmBQX1V~ztQY= zT}35T+h*jAMBq#h0(nV=V}vT{B9%RUc@B?LW}*!B*b*GQA*!_Uh%yCUgBEv^;)$3k zhR0A|jeBXTc@C22sjCr!4IEzEYw0uwmY}eD6jbE6@v65>v1W}3`=yA1uWUQBQO|Uy z^Y+m*dfgC#Po$L`{+!cY6dt9$h-w;69)4rfK%Du2VFwMv378fJlR;mp!V}Uho=ujU z0SYRp>7)Qs(88mUxQ^=&r56M#C_um>@{|o>7gQ&yysy7dVoG zJcYJJueyxK43JzC#S2~rS>M2G2BmFa#q*AS!{xIu2E8p?fc{JtpOg7c>^#*G*7498 zcbSBKg0CgZ_LjEO*^3N%vft3HE%Lotb@p4pQ66VJ3~!fSu|+M=JI1?V;nG$VjWQg0 z-YZ5iEh(8eJU4PU@3=eRnAiZ85iSb#71OD0$E5DFx2A;4&mvzF6+1a25xv|Y z4_0&TQ!DL_2=s+ULK8qGmWbuG*Z@Gy8d6!p4I~gJF1xCbjh%>SfeUCc_Vc%fn^mgQ z)To`MuR*!WyZ=%4zOkZjJJo@U;a4;e^cg%n3Ys;#7fML@8>F z%^2a^ZeECLnAb5!T0)AovYR6+wV||b$&f+-2`-BCc5H~9AMR~ijKw1cOB++dXSnPYTX76WL8Va;2^k5s*H8)P6NyGsQ@ zsbua@w4un}Q+3PWB2|mNnV3AwA>j9XCYlEsk>S0RCXyP&BearZdo+n^yYJ!!DGdX^ z>*&g$2d}JTLvs@;XHwZE=D1upcA>=g1q7}Zx)+0I2QN}^dLRCNpfwcWCTW44O~;Lzkd3Aj?e z@Yqz;%LI9EIr0^_c-+yPmnT`}k|e#$c!mIvj%K!b-vvmgXFuyooERc0I;F>NMi`y^ zP1)!&*`7R8fnYXzGh=f*`hqJ_7>aIFMW5Jc^a zs2~SEORmLMhU0D56w$)annOP6_mt766W@cbMRT0%nrqS$B_QdT3SdPQZ$1pR#KLDh zjs&QlnB@b#X+m}&@D8I{L0DfeKJKi=HgeT_wn>K|!<_F39A=m%1!8*&H@zW;UpT>V z^{!Dsf!KW4Pr+q^V-`dX#&_Oxhi?NHxUoUJb7? zGuXXi#j^FbI|w}@i%=ScHS@)ON-4*-oSh4z7|gXu+P?FgD`gGOo8CaH3msJW!lACE|&~`}pJqK5cakB)xrUSJhw{)JcM=I}fl6 z(;4LswVQm9ovzB#U=H_aBvT~88BxXT0d8iGd)*1X7ziAw$`#p%D{yt>A+!dD5`5!W zN_xo{JYix4;zwvZU{GN@Oyg}6(`yfg3=*);*@EH@mN0->$LZotG}S$b^QVqDi^~Qu zQE5-rs2FVJ1!3spdlaJE{mFXJC+qw~mpP8>T$#_TkdH^LOKYO>B=?Ca;Yc~MttgdB ztBOnK(Q;t13q=Cv;~~=Fry+sz9OXHTsK-92Cr_*=TNixZQNg+|0Vu#I)x^o>vHP5B zG8=3X8GxeGGCKr7xO#JwL-QLO5f1#qjEn$`Zyoz9(pKOf7Jpm-jMRMh6^ zwzLVh=jFRcHthmH{c@iiraC@8M_U~I3H!#_imVrj6Zow*wm>fj)HxdaY*8@-IzSWC+hB{lSB=H} zj5v~}0S*bKWeJgU7P8W~$5%N5;o;^Tb zrDwrj{`h4vx}hFygyEDXS`;FgWf#q9X-UA_x`%i)!G+K-2Wsair;S~MqP_X`!H%lE zR#xxRD2~^$*_5-8^}-D;#K2vXyuk;i+g|}Hr4LJ}!_5#AH8n#r@4FQl$Rh5|Sq6O_ zzZ_d|K|7P!TUu+bJ6{5vcTsQsI3@sHGpl2!6%jUkA0sH*B=KFPq^HJ=zx- zGkPeKPsxs{lt?y@>(B*L3>G48U-{Y?Yd;oyX>82Hgiqe1$?V8@j4R=7$d^|OLT76% zl{ie?wa|s}C}TNn2obX->}&-P(pA)2kkDCh`wg<<;Lr%4tebGVa1W0{7*#{C6F6tN z%G@O2U|TM?an#k!U{v*ltfxGH5DHeW=4P7!lthe*el|mm9Idk25gO4N{rZwYT4iAc z^NGtm*&GABE%C!_qcL8$p;oy9qed)xa@VsjL?T(v9jA+eI(I_qW$D7Q`ne`OSsH%^ z4$Nb+rk-?f3!l(?&rNZvpQkS%gV5BlCV+A-kVxfKYC`+f6+;)}^ki2HtD2iWuK>(p zp|KH2Xhi_PtI|W#02;cHFW42n7p46ydu0ZUUHLIqJJtn75B=c=< z*1i&)c6<|8w3&QxIC1`XtaGBRH6+)$9>sI1hT8Lxio=~_PI$w`2;KD3BDIv3@3E$= z&$wWdi$%yxofM6s<(9KOgvHZj&3;3gc2UgXlBc3WWgQH-x@?x%M=kZOya?y84SU`-}EEq3kprV(b!)d9g*~sxerkObtEdg^cUgudt@@2uK+d z6(HxiJ7{H`ObMj*-Gz10+YPgZc^+|$d?(E|>fsD0v9>lvI}?<5@9OCdhOgDhI9`&) z8NZv-iU!y)1{DVic+(8sZwd9z$kOOYO^H4D5V@7s3IQi3U*NtZkhbEWvQ6^wr`f7v zq0m*!{XFfR+a{hTilkCQ%1EUXPUPG$RUcE=Ljh9D&0GOX28c?ZK7+)Ux6?&PDDe7j z&GiBA%M6Es>#+`S2EC!4=vS=!NXQ*(iEN_&ATRa&($J2NsWxx;+fr`dbPX~ZKsRc0LxO-7~7mAdI7K5t}g?xEv>|f!BlpS&>rJm=)pkG2`G&h#tU?5w#!=K@HA&7 z8Z4TGsRNx{Jyj&o3*VX|u`0UecHPsp)_u5UqV0Wa&Cb-5;pU?xwlj7FoB)xrm>hJH z^@}LG#G{9g*vQXQ5Sr}-b?KXS|Dyd;w9XzhpT7_{L61ggz9K;dF|qX9?uQrlY+sYW zDW04m-H&|)oJ!nS(Xcim!n%z^|0{BzK7n~ z_2@=Pu^;BzX$$XZT2gYyz3p=BeIhb^ki)7o+z6flFJcUUF~a&4$z#b-dG|U}4KWKV za5Q6xP?>3xI_!0gy6l?rs~fXNmUNaIUF1&*65LSdij`IxM};4C#)xLXIwJGy!R_*c zS+wZrVz1=W+kOhIdL(qZ$~zref8h?k#zkb|a_(h~?wn{bP|(~7ttUjRyZY06Lhd-*Af|I2heQdISDr* zQ!$SO8?Y--t!VTiEC@1K(&jNr(z1E2ynexw26VtnV)(XcX>kNcpSpoEodUh&cLOew zuUI`pfYSH252G$DKo=t#LReV=3d#}-9m*L|ytTszUq8dMEKv^KMDDwX2$?bOxdvz? zUJy#^O+;@H>F!CAQ30@%%`7Yy)^R~YSE)hgp%ywr>$0%c%IvfPHbqQ z4D9AQ(OI#BJUMZ0bGXsZ7!bx|I9*Y@r%v4#X{_h!xp!5$m+0-j+^LqQ0Pe|gjYW$y zBIpYXa02@}h}t_9AQ{i7!sUSWQQ}47?c!okoEYofmfJStfxF`7V|`f_4zGK?oy1(; zO+!J0*)WMr4qnE}xJrj(B?>)t^0j4>lgVx_dp?W4+UlttBxTgd`+zA>5p4szG#(;2 zF0Zo`gj#fhf>q^p<6|uHS2@Be`X1O@ncN)}#=;v2dA5^uFqDFQdiLa>z6Sy)?7ZvT(iQ++CvHWIcqdq&u~mdDpQ} zv@;83s2)ZHStg1YCX3Iegk+XkWxI+d20w8}{ldKzA7Av_z!?VsV;F##aZqA##1YIw zVa+hEF7$cK%2b)sBLOeZdBnG+672zwY{MaR4+un8y_CR?=Rk8y(NT&D|;g9fJr29xTeiAIS&`< zV)rq-GL*fMywRc2%bv!9zLa;YDH`yeEP{{h9lBBjH6~P@Y!S86j?h{p$NGKw!G8w&vQM1lp_TQq;b4m<(D+A}z%MA3k3??vL7Tx~08zIr!3 zGeJ)_wdNhF=HR3ACZc6Y2N_g7zirWB_oOUUd$y0BuNq@42CK?U4v!P^3r?QIT!@8j z-j*VWMhD?_lhyX!0yb3p`qBU#}8! z0VU1!AduRAX-lL|58q&T;pKbRMj_Af3A?z7=W6@5UiKrF)@9*Ay`&RtM%Bv_oFgL_ zKN^K+2F(y|r_4;lZh0I%(k}vgU3`;LVX`z;@-ZWaO1u~LvWdmOW1j>nl=bX1(@`u! z1_q(IoR$&sF4W_A@p}4BQLqH+nT=u=blsmaEc1lEcH;0x2H)MQLl;4rbPe} zrJTf>U>|Z5Q8fTm^9tizopI`jcm5unv<}vCwZ(xaCM4@$z$?ntF^-}09_*ZDL4ie? zCa2X=A*4mp-TDwM9i*3%gGkhk@$#v!X&@=56suq^?6d%%W`mk7^7ELWz^4jpqNIwV zL^CX2*15cOILT)@1!kBIQB%wt=x3vjhPb)5<7_O6YxnXF;vp(kU2T~33(i&N*PFw_ z39u{}ixk8j;x`i~3HqDOAo^V|t6iCfZ&}ez(g#v;DitfRn0<6P02vh{|Yh@zbD9?2= zd#$x0PC@XlcC~ZoC_*4clP1OB5p*geY`8oz$;WiDk!!kSiv{gLMIDdEA%`k3eU!#Q z?q)G`8V@ywDn{_gFIR=t-O#B5DZH%cX4$Cj#`QVxVwo40sPMh%=eNuNy(jRVAC5(_ zd8;{YC*gy>m#z~?+z(ASJd)^uNX7e7$=~adBS|1Ec#c52^29a%>F0%3zjDIFACqwj@o`(jGlF4Wj0 zB1CE|?F2cHls|th(z>$)Rk8FIW(k*pN-Kno#Q{JOGcw)28^Sn!M zRqlNIwI|?KPBz5VhQi8-oC&#kDtNtB+jItjHxi{vQcPlS#%fqhYQ!2LC1OIsLr}UJ zZ-8D%wmb?JyZ|ZWvAc6kX23IF?Y8pgpp9`4^0ZCN?L>*F;!f?I=tET5@gtbThib=j z$t{mf$Ck#<^mtQe%)sdONV8wIoysOPAL8?{;RD!TMbfiSsj&K?;F!h`C)3QiUkFM9 z@4FSd;_b{OJq5qignfXjCy7M#8X>1d9p2-&@qEj@{l#8f;I$=G%y~r4n||b|+Mf5` ztc$|VhHpQ^B#P%G#E&k;47C}=%X+SG#!kSkhh=l64wL)k!fTA~5{GRhnj7I6LeS)u zR5lSW;z5}Qy>y)*YVSM(0p7ME85~)ZHO;CG#)Fg&_70L5-k6#!n&4?%WOy3J5yG5! zKh;AtlW3CNOEJSX-n;E=2}4}0kx-jM#|ND+_$Gm*@;xqcvBaJ20-#FK>E6Bo<`oO% zH_cWH4~!@T7zTkdqZ|g}c)x9;BaTMlaw?-Kb`zE7kVlM4u#Nz{QI9M7NOc8A<6B zs`JqU$nc6pjFlm~GvK@{MPDQXU$fPfdyFqqk`W)?;OKkWWR!mW3>*#^+wd{gu4aiq z7bijLOlkT8MI04!wLNIz^1{Yux8mTM?wgnLBy>^y_GrYmT&cQLF75h%X!7v`i+V zRx6yk&DqowCcw#w9%p2=CR;tonv= z#4RIVy^%+8KF2MxuJ>;Hfw_+_z?_D5H*1RW(KC!kOPDOe_)y0C;q1Ib#f6iQJ+||! zpVL@k^6c{IAjn}3tU?Fc0Zz30B>=(W=uR)dG0VH9*U2R&S%=GHq(z3eW_NJwn4Sa; zn(b2>kx7eqAlERkEoUz>AX>skz9GfNaj_F&f z;RuS=_V%}JrnTXoF64z*PoYl6sz-(IBC&6AYvl9@L-Ka z8PqK=&f9d}K-gMp>f5R)akrg&eP9aYEmb2GQ;!gzVa~fn!r_fNW}-M=+&)RTIM_-a z=`ABS&m!t~uqCM^k6yOw87Lm7<7N9}He6^4k#`8rCbtwY{8kf0a^EiNl^PSBBd2$ML~&oj#oq0aH|S$U1wn=+Bqfzg_eQDMd^yrLPS5cGN+2pS4wEnd08I1lgd_5OKo-RK{B2OEte@pKr*;$Zin`67r|bfb=Q@@bYU0NXC97t zJ667s{BBVClB@7R#J$c6vB2{JIRP>?+H9H^cC*-H3wk*M+KGEjloMU`geSaKET9+& z+wxZTNQUSMf-29pzIlS;5z*1pE%@5oHXfR!n&ktM=pu*ge12`|5mu@%DYhnju%Dbw z<7C#T8Pv@y=fj4FylRKMb{Xl8O;`;pO?e}Sg}lc*7dg-AY-|BM9`Bh_F`CnKZj>^! zXXV-($=B@w!NnKhuPbO2`-#YkHw>|nu7kaP(T^Rjs4~vgqGDaq`w}<^jj`UYQIe^s zgZg{Cir~?kWY!1sc=Nplf{@zx2xwbl=piHdOpd+-z`5rTm1(js#R%&0dRyvS&`HKf zcJyVh2jc~~w8S7FucOyAo27+zHc#mpDI9t*96SId=~d%eW1gl2Bc(*vu2&}^C9%a3 z{9=O7@yV?HN^=8Y%v)7qHQWe|<^g;{ZR}V)4!){yW~%Pd6KC$tH}&XM^){MlHM2wW z?LZ?h^1M&xMZcII>Y}mt;Ju3td?63X!JofwKIjbNb=y{FfDzizdY2l`+2Rv95YJ~; zGVB5PIC^s^*u*T6^O~X`mgkN?qpK0x5f-sLCW6a`m`i7VfT$4_HpcJ#s4(}QJliUk z>5j!WSNxpGcQGJ&Z|Ze!*}ZrV(dzVNP1}mq7NcR?Vh$-}fw(zn^Wd}6hgt$z9o-9a z_p)=6t*TsW&1@B|YQ_AH1;d%Ap29+gwi+M>tZ7xqkRF@^we2{KzagM?9Qunmibo^7CyIsqA1Ht*mX;kxXq``VtZ7PnhxaF^yh zA}lFDkD+^!!cKQtosH*h3rUfM78O>StJ}i0k(A`qem)BYMEsKMB zaaLUN=F?)riR8wf_$60Hji=u%>y8xkZPax&LCs`6bEHe=g2aqS zJ%m13t%--Fc}tW>;q32W>1>NvLFhm-(Ty<8p~+$`is6+|uIkaaCY?HQdS7N&Hm7k=4)A-sg~Gyleh;Z$ zQHq%f?Axn(2J7jajp8JZVR)6Vl51d0*U%^XoZp-GQew#MygP^`omb9yrUD(gzocbM6hOw5|Ct_d&sK>C1~=x_ZgrQHD4|s z_+~uwxLiz6MH9Jhv=eJ@-^WbgNf8l}uiuW6s)-KTTp6s|kttznUhDmse3CF^74y5zCO50GzJ@ds=!v9K0El{Bw9*0 zRS$1Cy!nN>P17E2EBA1V=yX{7daYCr+{!I8EGtc-USV6IXV{5Pa>-`ox&h={8hj*M zvoVzucA0~3%60tsxwz-xhU#+KWDQhuz5tur8Y+?qLoau+2h}*nfeA~Oto~E(ZLO>b zF7)0Io{OlDrdhe5>@fxSQz)^{u_ypwBc4GtAg}7poD$?=8Pn@EyR1v)My$xD>hcF? z))v>LmWHDmbv8%$%1$mWFEhlj@hIVW&}y}qYJ`Kzi#))_bcWGFb#-kyaO0|cJIhh1 zXc$3OvX7PzBb-L(Q3A_zvjcAl+Um2+NAJv2b=R?1C~RLjCg7g(b+GW&PNOuwd~urX zRgutJ$mvFX4FiL@F{RmN3FC*3`Xg!P3(>ZsZju@9yk`qKs$yIfNhIr)Le&B0b@Y+xN zwe%v+!H7OFhUc6_7r@p+=PimE&VGQvs5V{;$<=ICp327PP}Tc(H4xd#cv|e{M472b7(IwDafSf;cb~;Coktb+^v$!LvPmppoxmoneM&$e_heN>Z*>xJ1gYW>r>(VIvX7z=>=b9%? zMGrRisg-$ip-~}I+a5n4YFFJbIYT5jjOl7ped9r`&ExK?+G-PPYI#ERu;NX|j(JFN z0m{TUE4_XI?uHfeoVLyVN}PzAXWSoyaBHv;5&Lo4K$`qC-x3s*vC<$=WNt-XmegP zxH5eknFMmm4<4v(VfALbIhky(lcWVGa|}5LpCi6DUD7VAeK`H(z?pk?P}HiD!o~Zp z!>%X*;XN$C(R^1ACAzV~-jK-T&#=b{$)MO-Q?c{xh_NoKUK7kC<97_CC6V0S&n4*r zp1+2I#DIdM0n9Ex7)C@~grnm{j%Pt85|KjF;89O*M(A-tUs>sRZjI>c#7mXe(m*&j zdJ+VyhhCRAwOt2U0Oa`I+YzY9h!Bp(_Vd;^rligOh&C*6Yobiau&AjF=nYIJb6RuB(E&ZDJpi;4ZU*l$AiH`XR-1*BSSYZ<7+kYk zZl|)jrzV`^3$V@gE_{bpxm@xESUq{8uE>Itlr)HtxQ{r<^_eki%X>l2_4;kq`8eZn zbO1OReb%#d2(hgbH?M`sR;!8C)3EQf#n|);(*@=pu(C9)@`XkUqasrHVqsj! zrjp0ArkoqmcljXv`7Rq=vLie+G#kYo=cu?%VMb^-D{N^ACCQbCyiTvHao&tYHI{Pt z5}ggoBi|AkaC(^-2SHTJqbDroNhG?9jJq}HH>k`{J(p(|ft}V(eA!j5(OJ3#P~^mT z(JWsTS$I64jF_r`OUq5 zai5D4_b%U43;@d2>R#`v85{DIoft)VEFsMu$FCVEqw3+kdVpOwocwyZiF>5OIl7f3 zwliQUEf(;uvcW20k?oR6O%q4e#bDuuKDUzUk%;wG&D_EA#K4wh6Sh-)_JHtGXLGtl zp1z^?nwS}m+TK(N##zUuq=(Yp$SDamFxX+h++L1>-D?A|(YSkB&K@bHWi4WBF~cX& zpn`Z3aiZ;^^`rx>^i@7-y>kevJR4N;HMmS;>G6Jp`m)R$`H!R_g;Cw3MJKBIKW58)cbNyrza z6QV7H2Eln)b|@bZWF#d*(-XNl5ZcN_04r#~#ZHU~DJ+nNhiXAD$g)ZIy&X-b*G7XN zN%aI=g0yDGS0XvO##%uUwN4Z+8=rF9iYsJbpxQb!xQ?<{*OVNxcg}7tb<$8j-l$m= zneOO|m?AQl@smfE$5v&6%P)It~kP0yC8ncDq835hTG1~Eoyd!&WDEKa*m16he@}OQ!M>lV3 z2@F4f8n-Q=RgEt5Y$jTc%4nfp@Mf6? zDw5u)Z`!DA#T$u};+AZNvwrn#?Vbi71rs-Mp0^+DN%X|j;gByZ!dXP>nRgBjOU2Y1 zn_W%=iL8x4CqoW@6&=GocB1?wbokz1Pqr$7AYgQ?bVy2C3Y-a>iQL0&39hYo^j%B1L*H zOQQ4X4(X85ZogJj(U1ATqfR^9H zRMkA;eLc_p2zRz4dFx@cscz+4To;vs?!Bks60{iL$VLF1x6g09&{hXi@^*xFnIk~L zd(jqRc2q(opTj;D>Rug?cSMKlJ;Z6+#;2(v0{yi3c|hCJ3l%S$)Jao!jd>IL-m5hx z%Ce@C2`K6p_C{5U_eCVN93YG8zRJMJ!B9?QpQL%hriEq^<+LfBrJYcj5I$g!!Le{jd-&Z|Zg%X0#@F9nLCaIx+UZ zb6ctkzI^+Ca)$MLUz#|xr}GruOVs{H590u zFx28y5=Hge9_n%TD}9*gSIiujnwO~grl^_;Y47AktM#F?Iyk935sx-R9D8-w%MXj2 zfrHlcO^}5sWajfNnnq4S8l!g+oOr9EcRYhEg1x-fN?4RB3Y-W4SmfsEVM(6g5Ymri z5t4N13e%)+l$!(|M3qP~AHAw<7!lOOR=0V@xJOrY(JeY`FaAP*GkDT&=eUSMo!*w% z!HpxUAG7J|1v~+M=Uf>=fRg9F>hvCAEYHJnh>XIQ25(n4qUpin!m}~6o7Up$edl;b zYl%`ZIj+Z!I+$~C(vMen>9$FqJZ9c&MysqvZI+sau2-O0gK>MTdRl8LRHyfQup=5wdX3Oo(8B zVSB3KW?rS0o(Jb6V~J?fItXP4ynJ2?=o-Tfyc^e=Z7W=yIxa+kbaL+~t+i{L;PP-$ z`MFO#Y9R&F$6`Y!B;;NTu|1cG=|L5d1Cw!$U2hZ$%Vj#`^+r82#9Xa%O1#iMVha?h ze)Y&5-r(km?!o~Py*gC8dT(_N1CB9~a8{z?HY}k1s+tPREN7x0>X@V*PfZC;($2)t z6K%~jOYH5E_aLjEQyP1F7+sC|Lz$uEoVoX8&__B<*p%_KB&)gQP?c0h<8hn0MM`n! z3|V^G#W`Ab;R8$eFc^xNpcpB5X*g1@FC(m-2e8DaQeJeQYP?bab|fP!5*{LUs1ayc zutTLOiETt$oW65>)ueg`{KN<-2aH}ldo{;Vxci2ec!FtY{X&-UjzcSsPo5}XI6T!$ zi&7;4>pb_&UbG$M@YR`8X^Ys@@V4^gsAC7hz8?^wMAH1&v8?eEeWWk+tu5q@WBU;J z4R)A14*PM;06Z3*RbZ2H27^6zwtnxGv6vKI`%t25D6>nxa(#T8`6MJWG3i)B(nd>B zp6Hw1hgI3kuRY(}9UYkv&2UKdr`jZBB?7x4Kmv26fty_;Bbtj`VW8@@XxtuibesHg zg$^Gw>5F#f8>M{euc4m>9UO5MKJ@A$Tf$>|c3Dbow)wpJSCV5qn=IwVcUx;HR3}xI zC24;0SchM?F?Q)0m6eCXk$S1uDP_$SidhQr^IPPSKo0K?IWQ!0R%mM(=`BvHS#e)G z!v2eWd#gsvT4X#A!Xxge9bNM{g&!o>$ zn_j}qC1FlSnD()yhS&yjWfstK)3if044vAoNo>%ViS&lbCKm(CC>kv$v~d)3xP@Fl zlT7tsL{F?GCroqmAvp=t_j*^vwBDdBy-pidHi(=g*w>9t^8mOIsHRUuHBX3I1Q9rH zyU$@bwF$?%bFheKW@Zv53!3g27DNZqQ1ao-6ScVE{G>Uh2qwirm)bo*+M4 zbV+yLlw2c>3M5>9zWush7`|5~??EA>=Yh*wF=wmq22q{BoWqgG7rS9d z{*IEMPoG&U`^LCP#Pzb1hLztIp)-2n9)v|aSvdcdfabY?hKM{$sF?I@TvJ9Rn$9@d zhsu=6IAz!N9=QaR21^)Ygl7eeg;KnTsPrU6oFgF7p<97$EvUYcol$I35TxxVw$3b} zdx!AJKEWsZsmaGTEs;1x?>Xj59*2){83}El#6FMZzz1!cyGpuN6CSpA69j0--Lt9% z%)m-LJ2y{g9ObPhw~r+_(ivd4Ju5-;CJ{X_L?nPMC7WuB=u8WmOYwUWPblK@Jg{52;}$BTRe51_ZecD5u0K+M>b*>OMdN@%jvGRuUil`Ohx&9uEqyxYcrh>x1= zTHoP@MzJwJC!)65_e|;JnKg#ZY~*DGQUKhMJbQcn@(s{i2z&wqLmJg}r@Z%MX>qY1 z03r8N!+6x)Io57?d)%Q>kNb4Jz#W^;47gb25Pe_Gvox;tc*5iDbA8Hj3C{p?(aJ#5 zRoZ%E$8q`U8E+{+3Vx!y!(LA;9!hmR>eaS;Ks!=B>PP4g5%%m(A@{PiuAGFbRU3|h zbo$xW@`U;8G?sY58x-Z~@5Z0`#6nnJ7o?%SLtPPz^%G(B@a7UiQtnIut#{pXtamw$ zL1IFCY?BY}36JWTzRYD!sH^94SBvtLQ8ZSTi0&DmFX8Un^I=kb$<4$LZ!J`h4iYzw zUV?T|9=&+&muiUPA;?WoiU!lk>^EfJ@cS416PJnHTN`DwB3RmBDh!eD#dA>td?o7( ziwmiYK4&jtAT`bK%CTQ()VwNR3c-SE3lfr~;H^RMr|u4VD{F^~cEkIUaRAz5{rWhc zzRsP(>=N;PBT9!4sNVRia@QTQGKKdn93M^=NHL*3$IVQuMA>$NDrtNrs58p2xh+XH zAUD?u_oQCRLqb*uEp8x_>VeFBMSymXHB6>N^`dz2+3_xdGB+hns?KhwJf@|m9MZ3q z9E7}X9&JD#_e52I-(x^3q2g-MVej_TlBg^|4)@I(q{W29rbUCbKk1j+?tDH0?`Yim zDkB|Qa5%xzB$kJ5e)$Qy3u2dQ1paDs@8|Dw!{5rad0G<&`LSfWJ06 zQ;r@9w_}bARqs{ZAr#~WSv!am8t0pRu%S=hu+IU3Gs=|UrVJ9Kq0@A*c(Wmrk-Y2# z8KLV&FMFNXFQxj9=anX7vw)Mnu!(w}E$#aN+mgX-r>8Vo>xBi9A3-5FoSFJg>K^+xu+z_Bg)q8jsK)NYDM)2;MV*~J}g5D#MdmM?8xs$Pp%lDdPGg|l`?5IanYy$r=JT#lqrz2e=b6QL)O4U|Xi1xU)_+j_>&{b5s&8{T+6P2MDO z3o$67)>mp(3fs7ha;(Cq`8Fl{jOQ3{A!c9r6TI17j_3)W@~B6U;=4-cqOk~*-0Bsj zs014$n2+Cp_7*#L%A>sWJ7i4W@y#Z3gE2Z;1Q!G|$Dw7Sdb^!K?2TGnu{OW>%Iu8m&oFJTFG>B`yekpm!V~jB2+IP>!h65lS56MeOWpS$7bW>su1X) zukIbXli+t<%QtEucYmA||);K!mA5BTC- zpSU4yT<+_9f6o2emJkWNO)x9F>Q5bq3C#@UTtsP30L{7K zR&q0m(IJ1~F1SOKm*!PmFB#kP3_#CZ+-+#!0h90O_StOL64XHy<|C|7MZFk2-tK^E zx*hBXjb54bSmeP2<3q?wsVND)S0&YWnI7ViL75>_7#=8%xBZx4G&yB092}5l4U4hc z(kv^~2}^2lohU(9!x3<8c@|gJx-TGJ1T~ZrW27o9X7lYr;Xt!JVbn$!0}UgBoT^Sy z@@Qg{Ma$Mpj}6Vt^pQj3(TRLJ#i_N+rJw_49v4iB=OdMA;(2;HSG5xAdZ+25Bo8Pa z_T%;m@T!6q(#Yu$L%9Hwc+LsuURs%WlPNV~C$~knP@#?lnLwZyh(m}?W7f?oRl4Xe z8pyCul_HGH?BEM82YH? zo-yn$OJ=7~jK71r*Q27(+1Yc%tXJX9!!l@w6qyo3S8qHi%gWd1^15J0ooY6e`+?xv zIu5gNfX-s5a^Pa;8Q6m-r2Y`AvFAyEiWWY?@lkgfl!iKIsA6ci3V zoy=?_M1KC3<#jLsHNTT_+wf4b^XQXO5S!I;9ZIL2aDpd-acmCOtF1WG6R2J{Glyx$tV8IU--*nOqjb}XEr>yC2Bo~*N^i}_K*Uj5x;kqo|Zz|$w`T1xP2`n zW3`eE<1#@AAx~hgRU&MdUlX=N@It=Z8w$nh3eFvP6qx%Ex+hJ>vzM!FJl5u|45~m) z%BXsI3DmW(f-gEB&&x=voaQ?@u!V+d&p28rO41u0ZxI0S%gi#lG0dZ6;@Xb1o?qf} zxP9YcAc~5n8```QdZ~Wr08HW)5wP==9ylvHaOK;Vwn5`Zce&DZl_HgrugMyc&alQ1 zhi=g#nsVx45db`4$BkWS&N<48hD(8>7bbmw@~<*aZ7H)21G3) zMgjMhwx^*8Y{;vH?0xp=VJMGcd8C-+iBqbMRUtEOzKD@XYjGJ<;`c`Rm|NaVl;8S2 zu_T>VUEo5gxEr{(#^N2Yskht?`Gib?W>6~&&v#tX2|@J2ZYhu$@vKj4D!?GZI(eiT zwV+5*;_O~uwviAqHdyF;Jx*@jj92fhOVQ=JcX1!9ZGgE~Z1C%N+SpErvLz*ndGA^a z5I7_@d||8Lj4pvL#aNz02&Fb{L6&pxK2gPc+y}F~8ZMQ4mnSU4o^zmb_$tTPaDjNHNN`SELAK z2QLpE3&YEkt!yx*!5s*-TzE9~VD8%SQ7|2glD4ft)j7;umIK0DrdJ1$EhZSu9<@M9 zTsx@EgEu_@hy$&Bd0M5nMYwRF@(yJDN~6yMAKTnPzQCtdGCTwb*!6Y;paeYe{bD%- zcfz+<-P)kBnEakGjUZAamWX!sl&7ufG{2JkS4CY z*i(;(%QE-^lZ=b#{Ph+XT~uc^6rrk1-I&J-&Zp8PPMJsPJ0ni+lY{%J;l$O&(9Ray3Ei6{GbjYzLjbiCuf~=f@u^ z9jRxNtdt-Stix>2WRqt*9>n&8D{Z?}KegPl(#0T5hp@_OF}z+&rR z#IqNI$)M>cHanBvQ85J1*W9{=OQ~zZdYIUD;=Ng{QNL6J6gR*F_trI+^_g{p2U-rZ zokLU2klu7a`hX)SC^6oP<1~425Xn>H6M0zJf|sYk2^;!cqDT|5*8}pc zG(1PCZ0c@)neCv#SbGW3t<`IECvghxQUakhwlQ1^LoY#KUh#V`NejBPG*;=}TenrY zMp0TBe9p%&#?UetmXZQJEP3l)Fut(OyFT8w=hMn>jf}8Fl}^KJMu2uOohFE@Vay?c z<7`5uN?Zm`jT7`1-a(<~ik9W3fjn|BTFz%&R$(aaRAa9nZ-k0&gS}FDO$wgCU0+>?=|Jfy`7 z$1r#S$D$!G{cg^vF2VP9D;M@F*%QtI@=F|vru#ovN0zJ+J#hp`nPhzQfA2mjuI}7|G1K63eg_=11%1{4SZz+& zMUHsxjsc+0vh7jqX5rz&qnRcQE@CtnWk68aJiy4|iOE-OKs5%nauX9B<$4Uv*~};k z>u$M(`}*y@1KH2Fvt#Vuw{wgZ9ic4m-K@D*)Apm5TwPqU|5KU9GmM&qTu5h=IffM!M%a4 z-ROxx0KD$f3|bDbc%_HR_PYigjf-9mAZT3QS1hlmF`dK5TM){J@DhMtfct_<8B+_A zn5iDdqSXs~O0yj-?*txs%Ock~zza>tmzW_|6kXVU2@*B?q9SBi0-!{f+I#4Dy|PX8 z3CupHc!RghPuXLl=()mT&XXlZ93X_5!G7ZrtWSgpv4F$OK7#Wz(|=-TMhHBz35-mc@Spy7F>5oV-UmPgtzY|a(j zz;k3&hyhR^i%HTU7^LjkkLL|+L+9fBZUO$;0&Xs+JBFfi=;gxm)>i3B%smq$!g4p- zd1G?tb2bS|Hl(^lypGiGC(T)pLv}=K0A{DXn5gTU{+A)Wen-WY^7Kcw=2)IWlPmzJNAM5LCrvmx7!|fI(>-3EB&|WwxU@6Er%j{ZZ2X8S# zJ&mfG6@X#!i}QT(-n{CZ>UP-#$=>ToOS2_i@^zX*v2E<4j%YHv_X>;DMc(TP_o*pe z7pQq{xF8;hD%bQhRSFNMOd#J);|ogDHA7~NVq1doV9m2p--|*;2sA%cdIY18FwSqU zTMAdSPscC4lw+pJS3LY>Wm{1%U}VCA)pHxKWbJvE$5ui#rW%Ho3a_2jxe9{!`8aKL zA$Tu5dHehllE*0ctgP~k<=(>6ZJ>vz`HO|zSueH)ExSb(^Ky=gp@mR^Lv7~b4Rm>~ z+v?$i3#AfY;fQd9KeXb1`K3M-_ob%^l*{v9VF>%u?k zV6>Sj27hoKi_$I|kFSj-bKEMQOrw^iQ+HU9a&UFyZSfBOTo&}~CK>{t_t^yOa|s;o z`kXLs9)vLAIq8WmAH+UU3N0n?*Q@cM<7iF%2GgOP>>Zur@?@?`^C7~#wN40?Y#ZWz z+%V0Rzsf?LRBgO^;&M-TO!##PQ(~sD8qYHUv!i(m>Bqx#ZwepwE6cJ6N@|q|rV_54 z0qq?StdRDUaPVYe-c3ktVHCY7?9zsTs|=i{9w-#$HBS0E6DvzJIq!0ZIh5ugbbO?6 z%USjwqIyA=*9r)O{+ikf!l4+gf{N;oC29?5@EN(^x;9m zx3O7yjEAUb7y~L}!DRyHT>B^=JuV)3$_gVwpzbMYk!Z=49&XpASZ9;zC2V!l*!#3Z z(;kUU)nR3o@)1W(Z~bn!-TfJ4=$jiYP0Cs7y+Q6rLS4_qh2Wr7j)hpA%!ngcUoPfj zbO7|1sj!zIh@RvGXv}AoP>?UkXRLwr-H>uwj}4A|c$S7!T()(~i>FVJ}v&^lUez z@go{LBUESPcwppS%)TuA9-9T@Ev<7gwD-9>og*; zaBEI8khH8d;<8JG4v2d}!W;((qqqc?Ga-ZlhS|GQQ8B&qC}WYHD2{^Du;yMa*e=%K zBU9P8g0EEtu%25M?Ls7QuD&I4a6!x4d<%l8(KmE=-s0j*6H3p+I@SeEvL#(#a1Z38 zgj7mD8SU;mjyIY7&ipA=bu#3fy?1W7&;SuWQ8(%iDyphIR?D~HL9IAF(nBw0nap6uTKL%p{CgdoSxP244=hzMj=`! z-l>G0qUbu@40%UCH1#K_JkKU=5^;hTB4^B?)KeE6dx$!r0l03hhy2y?OL3nJJb@^( zRB>)LPENYF3x_AlY|nxiQnK*M?52~W9>{@Jy4LSlSFu-oO(gB=EC-~U!UU!jm{3hU zgHIQUS|w^pV!~IPagLi#;XN20@7c9FOh{rD;@xibJIXz&1JLMLw?u4R!I;HlP)daM z=g*$|*`BzB=X2KM7>-b z4#?}i%p}KGN+80`(GU9wJe2zqJ>QlX@$gnX+h;GlHwduvy_VAqhB#8nYuP#ogIZAZ zZClYsX?#ToWRN8p^7L}HoVRG=afQbd9=7YjsVjz?Pw*MW<;Z@?B>{jd1E#bR|tQf=9h^4u?C4*3R?_#6~%8s&}gr}gU;}nOoy+eCfhUXvenVJZBd?uHZhPzL3SGkiVxoMnQy;g+w}5ziS<&QDGYA-MMFU7 zdcmU=!Kt}{J=aN)XUA)F=1;vIM(LD2$-7MleedXeD~7bauODGsKi0F)Mi8HiVYYHY z&4jCxQ47_hb!xN*%cKBGK()WoN4BBY<8R-rz4z4P-mXOiC)TlmQ}YD` z^kY1;%PyQ`O{pmAYL3l0bFChCyl0ppmuPeLPC*4DH{s4=BoUdc!guZPr8Iy(TXJE1 ztbrimFOcvyBWtM#tE=kB+PL$cnlDIQVF!nYZ33R?UGn7Bx-u)Gy0oI@Bha=qc)FbJ zs1|V=Z}Qd-;~u5kS8D%*>&gWc@a}Uu4WsPSKu>##| zaPh(>5~&~Hqiyg@W^S5#{SOD9~?w4P4*c)SGeHk2OH zW~3_ao`xwMEPUNycy;aX5V?)!m2g+ziV;8bAi=Z-1+UIThA859q(Xht&Cj)uMQ|uY z?ios8Ljrf*B-zsx8=g{p%N zbtwhBt2}O`Y|cbEK!C^KAcnOY>-rkIJh}kORryWfU}_U_JWh)V4MpvK7md%U9Jl+Q<9zwXaFJ}p zv8(EZIn{~>P>>ZgOb~HA5;+HH={C>M+;!do*UWh5S7+oj=938(jiiKH6BL`Ayz87?9hSx(wLQ<2CTBKrM*s& z+bYt><4R*im`mBWFQwkJ?jRTz+*{eNR^aftBKE$+Q@fSd5bmK9`1EQ9+pj${N8S0Mlf;5*rBN=Ga3%6AOQCBYYPg_ z?pE(DQI&a0=qx<15;bx`JpJK&-e|^8;hp0y+N)~_GFHB*G4k0BZq3cI%+=kOO1A!Y zGk_V>6=;0Lhy%P6;|S&lD;3u=7eeo>DR+y}J0JN18yLFKwQSRcHsO2CnbztL^ll8& zoH*cu9BF~`J$@Ae)W~Iy$qtYnTH6%su2MCqOe5_B z%$Vxc6-%)5f$$<{-rf!uoi|?SF@Rc+o3j)%9|qQ2ZYt)}>fbf3LcA0e7J6`fIT%S@ zNSt*-tRBawDo5))2uZ(t>13qRA%`Y)*kDcVAd)G)uynnAjFQeHboUYxW!ief?0G@a zH1dNQ(JI3%k6i>WsVM_(3yhI%wPv@8_PNxd_g+g7I|AQ($BjxUD4H)-HQ4v1PU0Jw z?`H71EZ*z^3&XyPig*$5&Kt+ON`|Mfggspbc;T5Kr}$IgHMe^dL3M8Z*UHpk6DU=Pqt=%)1qL+*}E~crIrkuW`<3z(DmclYZ%qH6CnGTDY!-E%1 zFeEX%XoySQegpVWYsO(eI#+KEs zH$w^Mnn`bG-hc-lhB2E4S#Z6%Bn?H(2|J^*5Ctl}DGa}N^R^g^Q9zkQ_pz*xw_uCN zv?pNzXA~Ufz}{t#y{;GV7(nk~?Rz}u zt&?C`-nuIErnBOyt(LJVz?#b@)I4@bu(2F`z<|+k02fe{Dj*RB#i%Nhi-qHtUA@l- zCQDL(nPm$oI9qSU;tZ#-Hs96j!~ntRQz+iT(`$*jYN^4Z9j$1iv6AWc)(4-cR;vNN zZbRhF(KjU9or9q%P2#ik#%aBaD%Iq5R7-dYUl4W%u?Zy0lUKtm@lzycNU#)`#qxFD zn^eb!tK+wP&yjO;z%`AM%`K2`z^jccH9AFEvkjtRVNOc4{myBp_BB01PaJtpx%0eU zo$%JB0!lyk_6-`b?h3ngG+Z3wr|=L*cH{|53FF!kcXvih3BheA3EPe?x<`U+B{ulO z@ybA@dd`95R;*P$8#RRCyOVMQu95zPpW&;a;BkJ2hw*6N)-%`#gm6<$F7L>m(Hw-F zVLra(DpEH3q6%qteS8OLq{cH#Lxi+Sk%^S(oy2sM*J?+)GraPN; zckZD#9Z0taXC~SZ^PV(%+{<}MPs6e%T`(QpF`>OXufrjW+JHp4sTSpyn=1}su87zN z2D)g;-ELUI6Nj@WJuH}$?phq~f()ZW`Y4lWTAbCmOERj(R4PViPRzps2jzSwNHUS? zF0XnOoUAyY%I4lo>QN%U_PWrl4tV2lB+>$xM#+)WqZ}NP927*ok2oE27183>dEqVx z;JKrDm!_i4v%L}S1`LDbWE@PNH`B|yQf(45~p!fLsT#*S+unGgVaQwgngf*)ry8gRt&NAwqRDl;vn&37AXk zbH`c~4Gw`ISFPU2eemiTMj2CHB`p#YlsdLYE{|Ssjhnm$Yr}j z#;4}p{G4Ph+L1IaVz8We0^fOdB~R7~GbTmTnnp2KZG>h=Ygo4U!%LB;#M(;+!#K7sssT?YnQ`4kPSN={jObI5H)=ShtXem$Gs>99JZddJ=;xv*M#1oJ9~x! zNkW07`d-?--DN^HAJyKcc5{=OkqX)QiriaSspgJg>df=aP^`VdeCzjaoH(DN8qqG4 zTgJY4ogOH$>8LTC2!6hFTTeQk(e|rAq?N}zXYakRGI0Sx5=&7oXKt`5nLbg5w-TGB zCu$NS&}?Qg69CT9!PAr3m?sGA5MCFOP_dKr=0FJYO^s_pN%Ss(6YWjKRO*mXT90&x zaQHq3P?8s)4S_xv$bd$3_K2K1hTT=8pZGowB89FE`~h5z`)*U43$~G>SdN&o7vfOp zTIum(?RsW;kLY@_>*91}Gzfz=UC5-5A2#Hf@6wJ_zO>keE-;7}x~r5q<$RvJ>uKGc zuW{FTA5cPUIuHTpZ67d%t=ho(dd83nB56ZPcs>KiWg1j3$n`V~!4_hYSY86*l_zBu zYEhH3qIxT004}cRtE9yVm**kXy#a^8b1L zh=+naG7V+PgxVSv?ebJXqITY<^v?4{T^q*hXg5e_M% zszdAE9SJ*9vopPW{+7r1u4HE{=W*-8C|9i=3%Mu9$!ugJ-$ScmS6V!hea{mfguQ5= z88UxSp7jd2;;L7rH?vq_vYZbD7P8}>=}o&!DEREde|Ur z))Ogns7fc-?k@w2X~%N1R=aRlg>PdOwHSH>p7gv5OppbEE)sENNr)FMPm}guN&Ay$ z6#aJTc}u%bnKa0h7TwnV5V&~OX*qm(9FhoKuV2NQaEd`)${M}$hHeBq*ts+91xxCC z+1p&jyojyu)zo>c2;e9H66mm4C}q-#bu`_(p20HBUJ5euBTUVi92UVaD3nJvZ&@c& zP@ynI`nVST5+&zg3Ph@kFl!>E;HufUcc|Rl?9p{q(L**liu-H{?{k&>+@yjS`riH! zh*oi7IMOu0K6K~Mr6x2s_d?Pe3I-ZY6P8yA`h=VZ+@Bl+2qtByzv-a7is#QTFpwUi z!Lz8;u1zmre0zvleBR?qSST9vV~6*7FdF zHg|lOYVj81xu_~W({}6)QJ=)f)F3IgyD>|CZ3%1Q{cJQyI3VueY8YkDx8hm#a9kj( z7e^R3*tBD0joJ&Df(3EoJAX5iD$QuJ@Yrwq&ge2IB(aucn}`=*LB_u8+s>=CQv^&Wt92;&a_P zQbo$Ao7$8F;SQdFPGhH=Mm?hg8`wu;u2f5)0x!|Flmm&R}DfUREsex zWw;ddb%Z(5f;~eMmDY=5Gh1{`sL?Sxm8#dBwoVFoB&v1^=t|&c;jV~jTFrx~SudDJ zEzHTU<@(TaE+Zx+P5|E(32M^3X%GS5X!0z%STKWuDZ0AodF@#NM?*fy0nl~b1qwMdoohbydLI0snw^^Z=C{GkHX4s>Pgi| z9Mml;vi7}{G@-D&kpWVdez6lTIOpcIwIk=cZmH0qP+4v`)FZ#QsOSFLTIW=aHgQuI zycGpxRa_{s7IC)Ab^N)4#iFgzo?kvMjcp8Sr~oBGft2Pa&izoLPZ2%vIe4hNTxEGf ze5^d788y&1d)C-7LBqN(JjxtSHFdC3YyEuZSR>~(Y~>2aBdQ}q3E1bksEL;~$&sUV zUP$OS0Y*&%WLXc*t>T^w1&SiRbV{Egt0C%3!>E@9^N_+4W+N{Ellg(zJnm^kV;dFI zG6fnNofB^gN{wRS*e(?G1o~_W{JB&%wr)&`+p7%DXp>4;?FZA+*aZ#e8&7e<**QdK zWH1>{(K)a7O?I3qkPmil_tj}&L~AbiSLOeA^9d%qKN#tS^)1jvz1gQH=KBqf-Z9`nttm#+ZPFv`|^FlNqRg6Ua!o|&L+ zwa5#)9>8k_7#~)xSW8Qny7w-+g)ug2+<4|jAskU)CeO!iE0dq`fg7bL`8;$0c!*0U zD)Llvco?h+RvLH?Es1DtcH5#Q3lVi(j4rSTbg{dwcjVdAYgfDB*xp*Lb8uSEKi>-Z zdQuE9gnc#D$D?O!E>y%Ov$H8$_FNuKC(@&b14KG7c1plB2GvB;Rk-5;G`?DEQdG|b zI0D%42JpC5boI2%La|L=n!^O%!jtez8aahBqk0_ZQ~q?Qhs>`Si|C~e9!Uo#S9mE` zzO6@dDbuppEtSY>M{Xn98_wpnyMf>~*@;WHkkk3x{dJ^0jmQqqoRa1OH^bOUGbzX_ zELh1dK8u4hnJ!vel1`!qEmVqa>-(bq2$edt+EiOb#8|EBB+^$16Z`TiSE1=3fhJQEjfmqsEdlSwDye8 ztrs7kIWnTy0EZu`buiLfRM6pG%=Iy6>x(OTIhO#Or+P%;__jiWE~)?_A$ApU3XKwggU$!CKk0oOvBc-K;CA zEa;Dtk{_Bb=+tm*%(F<1)dL5|Q;0GGYw3A`%(4iBa7PufFly8oT@xpFt(~knAy32J zQ%_?{OFDX)vyRDcIfgd6cit&?5;q|Ay?mg}uzgRR-$SeQp>TLVna^--gD6nAp!vHk ze6E+p^1|@Cb32TmOw)Gk0aH}(w3f0N#U`q|c zBYa*mB$Wkk(CV>x#+Va=1L#SW&6<=nRJw36z40msTm#&QX}--IiE3;^B$ije^WNsu zC;H;bf!bbE8IE|0R*f1K`t9Q#+BZLU$VT5y;qcWX7X|^~qIydTj_G&cJvvn2=WAsf zkd%cxmW+i1NG?Q8=XEEVcB>W|Ow{WyGKLlW;QiGYXtuEwlfo>8@9_0rgI{dxA=Wyq zos?N~_mKv%K(A}Zh;52@J%BN1f2`@;nmVp~TWF={?fW1UCa3bv zOu53b4jFpe18b2|$vp(83SS00(bD%4Rm_FFoDfO)QuCg39_&7?WIiIa(D?s)6 zlUSevg9diEXEZk&bJ6c@&tqpb2RCqQn;hjug?g0mj2?R4p{k!G6ub_Ge$MnFf=^g) zH+bI;TzNK00MJ16Lj(uCD^dO-+NMX|eoj6Gx&0!=UIx76Xy`bz0|BmR@7hj(rSsDA zi1p#waz$(u(=Gw_BxK`VS!5I66Vx%)f-_v)+w;|~ecr_5TK=B<=)9(j8qEtXPtnqn z9(j2T{_M6}*zqC{Zwb|fnj9C@4?HlyOZ+)Yi6?h4Y9t(G7WLB`bS{*B%K*O57oeeZ zibTt!xu3oDM?U!08Ae4xnmHHH3f#0yvKF&>q7yk^eKrQs&%FXK>g+TUSpZe$y+`u~ zJm@K4%_yJPyG*Py0u1!NMJ-$e6r5Z)nS_SX*Ao3^K%lub-53xH(3vo=S?OiLbM%Kr zlayY`)S=5~;L6#|i=Y?$5J7N_+pLiS>trhA#cGIJohD+R#-pmrdG9<}>%@^8RL2GN zy}=ZGf&ee-am0(dVJa7ILMLm#134Us!U9v7Hcxy~(#dm`;DFURbBQKOuf3FQv#*$$ z%O#o5o(Cw{fR2DApTBr2Ztkjay2rC6KHx3T2_`zSbR2_eIrbI~>dh-T2*^GqDs=Of z!1tEZ*%t)mNzkTa>(%|$8m0-Jx8h4Ve_Hd#lHIYSUfn&QH)%8^Z?S}+I!91x(NSGg zX&6YTcEf4w5pt%%%t3~<48p_NFh^1?TnMAOJC#Xx8&n_V)j7G zm%2_}U;E>S-P|5NlL8&QHykAV=sKUKK41&DI=;Q!U9xDv^3wFdCX;<#yk3Vk?hx>< z^2q8^C28N3FS)pR28YP$HS&QZT#|@JaJeE?S#ogkjMwYK>R7Jx_lE20+`M^SP5ZUM zkdBq@ zGSfP5DK15~6zxbhwy;#smUTzCark9}vEe*vvGTT8t$w0NJHS+Tvg-Oc`O0x=4<_jD za1oc^jZS1dQS+gj0bWp0oP3ow%P1AEC4CB2ULW`@y6Q>4d9U_SzVe~6suvr^(z@<# zPDcd&)Gk<@yrO~xW)0U9dE42lcAE;5U3(SnVeb(Z=SzL^n%Y22;__19=TK=@(<_!E z-!*$Wrzeql&qu-?g^i5+B9HpouW>u)9J7q}c~F|q z;B<9L!Bpdy8(7*%4Zg@K`PmwjKR+e4qx5s$T{v>zUb5~Tp#)TTNLFCc0QStQWpK4+ zV|B3YiP6ih8gamE4i_#e(HLfLsVHtA?cGeTDmn@_Y^vw*#lwa)QDTT>=q|OImv`HCEy1jKN^x{hG zC>p&hlk#+j>zIC=JH2eQ093whVX=&^v^KR)i5E1%on_2^0$YzaGG00W85{OW*wcfE zcGua&EbdAkkCSW5r6cSfvQxzEWF;*c@M)swv_Xw~MW=bwe$#IVjTHCRAag zzG4OJY_tUGYIVFIo4wqbg45KvxqgvlPuO5x6X2XSr-K1Kbtx&JBnqx2MrZcBZjW_p^7qVfa za7A~3P`5+T(O#jxu6HjU3b6*MH;5J{0gKw!+EY8%SBWhBs-D{AYrqxJQMzh>j$N-k zqjmyp*s&qrA(z2m&BM%Oyfk^e53ePRA=&CA9L^K=(PpP7yNgl244eW>l79RiblIdW zT-l&7_Pf{5EcDH?D5Q@#FXBdPVg=d-SU)~O>@g2uHpGbQdoYX+=e|}m4KE18m^r5~ z)aQH8V4ut9r5FK0@u``3HnDFASyX&iPa-Jk+5(PG!6$l(IU#VQg3Em!FPm>pnuD1R zUj<@|xGQTYg$Sa@=A9C|A0}IrO(7HIYiMPUP_nh{7I7r#S-8tKc_NL~xti9+|Ql zlmO>MNm-F}tMCNIWUUtUj)Zht`MHq*4d5{yx@YY`>PG6x4Gi|$h>3LErD{PQ6hV!H z9{7Tys0NH)%w+}3Sl@~%x!p- z1H1SYk44LYlCoU(4ExS0ggtA!Ya-pJ;#MzA;^<9kU-0ATOM!|-KWyz`njzW*PEJdE z*}X<@c_rAdyTiqH>xeo`G0XGL-g6x`$j2mX0@Z6f?VhYBoTYrCRGY4k-OpLoP~ffX z1G(3&NJtwpAmW0_!x@Pzb3${K&O4RI;dcg~2ijpqD`Q zEo(oS<`N)~Mnt!5$L*BbSF{0%1|x4(p9LEm5J6GuPNg>t>=Tk&7G<>6O}GiK6Ham9 z%+k6t@*+wZz{>jt*q#%fESMxLmnp|Sc!Nfv;kZ}sk8GqcUwWqzQdC&XRo^tr_8Y7l zz(H{2Ba+rSh)_D8v z)FPV7O6#IStP(~|-$}n}K?-B5DtRhY92C%Z*ltTbN6i&7p1BKA?N^uT{#I$|nY%aw z2i7$L9*(y@-8Zna{yYby2`t|nUydmYg~e9HQRL+K{7WzfN|?I zZ_pqfc=U42-Ilcj)|&?bvL|+jaR1ypD5s5KrLUUV%a$zYeTsUBY>#ngw-OW0)`g;A z_8|IY!~_DxnDx6j7Xi;To<*a3;ypvvyw_f2b>y(9RPYjhEv0rTP) z1G-5Tgob!*Iitz~Qp=B7qt|>+!qPn8IbQ8n?^@h!@GdbV)teiIqIZm>Dc3KoxOim= zJznQk*0yq;yi<7m_)z`2RL#lP;+PACbi++9wj-RBy`uFRb5zL2ZYXm=naC#6WiRZ# zqGD$PT7dJQSagr5ORb=OnO-0ln?o`Ov_Ng^P0FRV4VJ~0HX#9Ws?e=Ql%3>+lDoq1 z%0l3PfXzAY%${-i&*M~!BT6_?iG2EYktox&rrmLid}JS+GZl3^-T||fdU&icFSg<@%{#*P7WGv009GdTBWZ=@!DN@u8FbsdhscU;jm zuNWT-P&`EQ7Qenrhb|7iae*hKkI&u!&^4zTiL>{TFuGE`7E#SWar0HESKPQ~2gnEa zh*>Gz1M~SieWKpZF-J+@YqGh|cKo|Rd@iJ4BAp9(G4!K0=Acr2^q$G|EeATc`PoB@ zdk?uRR^Kx%&sKjYDR?N4YmB0R3ix+Wk*@Le>nPdAO|4o@7+B+ng1%bGGDr+hF6K=y zq*qxT@`H?1v4!HzID##LHrEtK$HXPb&_g9ZH}b?+bCz6OkFGt_K)9RTG1o3J@=~R> z-!9h6*@r=SOdy<|fmptcPUcH>WW=%Yh+IWO7^(DJt z^|Z1#Z9S|J2xm^wvhn~kT3}eUd6W#{d(}O#qeD`Z6}vZ3DqCeb!Z2{#+hmpMlHA8JAVNSIHEcsD|T_;I9}oMLoenT67PX+%Zc{RY-hir^0f8 zOY*^UAKQc3`zP)-7 zhwpNvliG=!uIF(c&Zexwa(YkDTB*DTXoT@>;cYkNh%)61qTx|hW;cmYY#o2lT`Z%j zr6wH&*~G4e03|7yrV>YNPa5rA+#FCL117v3sb<-O@U@7wd`+=MO2gotkvi1qE&B9c zJ@eIf-iB=e;$gb(FrIMq7LE=(7vOk7ZxqyCAB1|+zLp6~3zevLJk=Ms8in4vJb158 zo;Y&yD7xLdsIfDFDBALf)E#yqZB;1)O(8v4+2!}9>y@yInuvN0D-jj1=5 z)C8$h@N`a+Me?BKMzbzBdlTX1dj|c4*(J?cubl5?TT=j+6kQ#W0Z^|X;d@oK*t`ND zRyVlJQ}4C)RA^+xl5?T+2_$lXdg8SJ#6(f})CSQDF-lXi%m&I@zqha09;4mU;UNJT z)G{$U7SfIhPBKWETNW75Nk6>|QMX7)k-m*sW7-svO*X518^zo`0^ZMr=_z7f(26{k zX+klJq7lT{N{%)hj*8oNC>oc745>`Nj*w!(I4iNn#diF2EJ>4D(Rxid7ydnz?%hXaA*&jf%B-y^!0t>{QPY}336 z49q}xxA>wR_4T>2!h@m}tD-ax6_hw;=Y7e|xOUD_w{A4`ift=!xntF)A+q4g{boJG zQ7Usf5$Sn_%>gHztcbx(yAAs4zV}|tu;UPP87rHkQV+6nP)sjg1!$?TjI)jh_69!j zicO$6a@?L4u`bit_QuQ1LHHfC98AH8MQZltBhyY6U%zYKXO^A9{$4-a0Cm-k*|yEi zGtLEjFUBC}F_{;bb_!$f@eIPLUr{vL!2=L7pt5os7duvBgazW*jn3PsWR)u?}T1PFTc!0%D*I8@KP(l2Y2L zc#PFBk!kls)`K*1e7G@>wE`z`x3u0q-jrN)c%e%eC3mIghU_~&T-k(c3a(fjNBsGY z2>4u5gAd%zzSQMC6$Rf^qh){4NWpIm-Ma6<4)50K-H>YFh|R8@P^(Xn2*uNyF{7Nd&9FQu_jEVG zfMR*7d{@fXeA%xN!Sgi{9lb&-Q+&Z#_>4K&u#%l^GdWRfOCS{PPUfm;O*Ed@^Nc4D z)hibODX|(?@IVq{S>Z0%eT>t{+UeTxdAU!4?Gzf-3sIdRI#?GvL&=MI{SLrmV=ImB z6!bl@*+^qPg2l`FEHkn4`I*5>))BYeU> z2Ps+w3%F9h;$jEjrnd#I1?q}gwEOV5bYXUr4wRSJXG9I;ultRX(u>iA?gR{lG zM>i2DD7eQOiv6=TES>*!wC9wHo7uN>5pqm2U zgG6;`wRs6sSlQhm!+@FT*Qyif0Uld6Q&|aenLgw1QkZX6JuO~79TzsCBf7-*-fKmn zvqRr84`)w&j|>dQWn`Z=UsGV86j!{!^CiJIT&hq=0Tz%YFi2(ZIter0d4!J`Xv4F9 zZlg-q1hr3yd|Xy)04xpd)qt*al`SLa%Vp_Oo$NIAzt~?`fIo_3`qGu-rVb<2SZVoj{ z1zCx&QE^~x3!Y|?Z4@|z)d*k_J2g2(*ycuaiQ$g!i^Mm^V~I;7-gQs>75UopE95LH zh1J7F_mDTC8BcM@sa$57_}yw-w=!1}yn5tU%?seZ4CJpgm5>Nj5;0ME1~);D35$0W zj(Izr^yvY~%jMP0N3fIh1m|XfTn2YsAq6#J4Jbh{3i=@iD^*9=o9$6mHmA3XFQ#ta zE|R34aqgS|Gd+JE3kAvZ@Mb zDDa#tvRX;@4hPPjSkc8Us@tNc&ppssoWYw}TT2e-)re%n>0u6N7Gto&2}z0av|6=R zQQv^~lpvtu874(;hqT(GM-olQ-7gq$+24lKu8L{eA*dI)KlVUPX|};BhT7aZJg~n3iM|PvW1EepK zO86>oCLH+sMj^MUfVqP(&5EQ99`&gUo1DNKfQj@ed#_6orLl6bovpE|<}s}j8;s6b z6Cy@FL5rN%cIrLET7K^Ym-NYGv%-|W>z0NY;7BU_Y!vjlxR&d6gvci@2Fnos7SVZy z(ch~I2wZYF67MTyer^Ra7_j`X3!^gC$X+G1c-96!@I_~y9;m10mC1DP$iSqJJR|C&s)Lu8!ab&u5%&=6$*v^G%K0jjE)Ki5D2DfCIb$2htH*Vt1}s2*G{%RF`pUI8q9Bs7a`3`gaX zD-4sR^jqAwMpV}GT((YB*X&g7E(n!cKZ`^iAsA~ z6jhI+(5Yn7@5ahS2%sxQ`IhxPv?hEJwl#;2Q1@&BM)XW9@R_t+I!|9d+s4o;nt83- zIPbyZZ1!rq%|p2`ps_(*Hl%E~c)SG4(lzgds?iyT zUPxZ~gk9voQ-iK`=+(g`(!}u`q!=#qFcGc;dNVnR#OfVw0d;3vTKU_@*=Zxf{oa9e zzH?Lku)$I6{Gil~UiO$u-QY84G=6Rd^}WC9L{jqY7ATfOx}cbSxgc zKu~RQa;?o)veE5?C_bI*Zo^*jD4fLgfLv%v=#z&NjYIE2wZE`~IAXsDj0kz8S3$@Y z68%v)RW!(}oRE>*j;PZp z;!@*kv>9_iRFoBx_Hi*8fmFcEe`8XgK-EaAoArk9#rUC?365ww@93r^5(F`jSW`Z@k)4dv0$9x zp#5U7fLmEA5g6OXr;Z37q|(bo(dYFhBB>eR&h#D$fkmGCP(8aRyQ+=(t4os4o9CX* z0u?rLa2CtLXd+LvUSW!c7SOvFS(YV7KF0(UPpiXTyoy&HC|xMAi8YpxjNHX#iP}uL+zD&}E9(3!MPyr;XQE!c1>@2Lj+?35O+;2ex%uql?$@Pt~;FQYkY(Kus4-q zeb~mmWdyXvF!F6C8)^<;1!xMm)1N#Ve$10)8?Jd82dzOP%&=gcQi7PP(G_0p&xgTK0aWo;<1ROl9L%uNEqu zI?6&`m%g&Kb*0d97qQxBN#q;lE$SRqgO{FJH{Wi4_}Z7(AjXG`jdr}%r_%NaBYN6%6~ zM;?qaKT(gxDT}kbNf7L7P zG7&``+>7S$mo)o=~W89^0X+&!;GbzrkfrYb9dM`-~}sCi!j1diFOK5pdVXEyov z?wq)=i!K4{(crRnK&+DP(BuZeaog0EKB+e0%dYX^sI7cQudx}s>v~`p8j)ASo}EZo zLmiGw9JHw|IsoPRzGzZXyql#Um^V;)umOtCHMDP~Y#)^Z9LwCx%op+KUfNtpDO|cC zC6VEE-V4NDD?u#$t6j7eY$705Ee+zFKY0V1nj>gB*>B&27p;V;PZp7Q=ZHyi+$%+B zv=koazLcwJd$Rl-K{-h3M!RI+n!F)vOS9v;dGnqMvEm6sbW$`ZWJln=&VZz-I5h!E zA-0gi2g(m_Efo1d@xzTS`-xbK+i!4`8Fo{dL+?SpWJaT+7B!fpo6uXV1^pCK0k|GByj;0?ENNaM`nZUxYr#^l@LiS>?uBW+#dEsj zDbREM9pt1;T_Ac4K-;k9QOw3U_?%tm$=Kj6IfVup?8t1TukgA^6SEh|)zS4$*i)Vmz`RE;UkP$;7cE?b5a8!&4V zOCOQPkzS9IOL*f&X%?pR(+kq13avatWo|HfscH6RkXtp);1Fw^HeFg3yqyqVDBwkf z)1$g3Y|B@|3uj5G%e~+2g1^_=ZLhG!I=})Joj?I>%y4I? zPS-;o0Ce6n+@u#crqCf^2veK}7ld^8s{~$5n@}&htCiwrBKwMRe%A zcAk+=3l@PZnFPJ1$`(^4xlTxgUhJ%gp6lSCL9s1+2=_?oSYb-%#po2;?Nhd(Z0eH& zwIhY6dXw~c7s3=>JYUPsrH!{&*@k+Zc@T9DC7D9#f}--Em{S?ANmkdR!Ex)BN-T8G zHM5dSF_^r5@!Bq-(^TmRze`E;>D-AL3 zs>+`NxhYflHaOip?HZd$>DaIy*=!q@9sc9Bgmyvf@H{QwQu#vdb> zr#u?=OEHb*^<-U?7^#aOZB;gZDr9w%MbB9`pWh?gwFfV8^70frY!oC4;UOQyy^*Gygr6*kHM7Vc0M-(Z+OsEN1c!cJ8w)7!NWX8c}`D+xIqOt!QphrXld%x$}t zt?fP#UXC6`#>0WZMuzC4YtO^Qxzca5G1wLgvdeMWN*oUKgi?&(`Pw?Dp0;TT;G5K7 zFyhAo-sC_FpAADk7u>YdK1q$f|YG4!rZfjtz`hZ8%!AE+}}}Nmm5DoG=jI1~midHr7V6 zRNQ@kwT#?JTj64E-o|P2d>~m5dOEHOYl7Y}PAZ6ac6-08$K$ex@@9J;1h~RJe<-*$ z01nJWPy_|7ggU63M3^%NP!V&fLA@5Mk?rzs3|a@wT%m>U%(6v7sSgI!-FqQJX4`sA zVSV8#=f;z6?+vBOD@B`HmSoj9IB88YwJYeTX_wc|J$rISG%5XXP|(pxQ2c_meHjUWF(^q>pz%&9jc&^LXn{_qzMfh&?$oUF%$_r{>Qk~9 z&axsw9CK>IDXS#m*F^Thpc}pM=@^fSKXbZaW}>7Sz{(2Cqhx~f!&!xFI5x5h3?uRg zekIfOh6o-^ywn|VeTzXb?WyWM*Oztuws$4++UjwflolwiL?Fu&F*V5O6V(7sh6+C) za=3>>;tm5-kO6rF2yQ6bal3N2C|H$@E5RgOwt0#z#mo>~4@?jfEn;ZHp8(v3@|$T= zp|Uc&B%5L^firg^uI1vh+2L2B`D$!SND0)Vc!*qL=Pj5aKScFGV&IY%eQcL^6^rj( zi#^yi&CiyhpR4YGB2Uf4TX`=~s>|1LM>~5OA(YDQoY?rBWw%_zOab}~3arxiStv5@ zK8AhQ>rDAP1@dYG9$>zjZV5bEo0yfi93mv5PyyZ^#4jQssgu;AMPA&^=~FYyiN>Bi zhv>;zpPpjDtcs0B+e>~HSwmdtR1=P!*A}DiJe+)p0uWhZqOkRZIG0cyQ5oP23^j5ZdJ)WzNZ z++)P;z2n>4i&uig)6g*QdMK`C^wi-5vDK-DabMVO2C^~ZYWQ+7K_4Zm6iVh(52^Ls zK;Dse9U*Y2BMf%}!VO~&&0~-h0@LJL+Gbyqv-!F%NLwm!ZvapF*&aNcjtMaaEEE|; zFqV7B(vM9zS;}rNc!1>1%G0`p9a$A2eybjL0Wmww!Jh9$k4Smg07@OldH_*CuD<{V z4G1Q_CaoJ;U&CB-OI>PoK)a5xs%A`^7l}UW_2A?lzG03Q2zkhB3<9`>fDX2K@12AW zmE8*&c)AKF9Khhn59VZNPQd;&{B17Xm~9865&LEkGUo@yQ&CAGC?7s)F*p5!8}Gd7oO+^~6T zJ{yJ>_JSRgO+z;C3n*m~p$=|% z><^_TaIrSOn}&bBGeU#e22D8NC^M=+1dylpXw`)~Ow2*Po3qsC0+DKp`Q9bd zrO(v(qM}5{FV*r)1u*&@Y#c%%b1!9!os3b~MMrQf->H|uycg#tfW0mPWk&a?b<%UF zmk=O5WW2yHaW}{MnHGZ?gu!b;D1mcZd&}>9?XjO*KYx_MwntSf7Lm2nCyV!tHXVZA zI{^KwZLCt?G8bwjC|>T|YOkt+Xf=??;1Q+hyg3rNt3noj?<)IEHB^Kr0|1tT1X)ev zCYvdRgSd8r`zTjdLv{_jw;XtR6Tyun%C=fCyF99jpr_DYs9NKDC2>@;5O|hZ9OY~&yVa`l9S<1Kq0Xz2+`(o;-!vQC z=L*gMo9?YAcL~m$y9B!1J|qgMfZ{gO;=tn?NXzBS<95__2>Q7D(Q#1K^`qi7*4=j- z8yy92(q@@40n4hR&&YVwGfl~ac2l}GQo1b0kh zti|meJg4g$Bs(mJms}C7$Jvqm%okS|7z>|A%G<{RJ&z`ag0Y}0Yf50!H%agz3o7@^ z(&`!#Y-S%CE^x~hONl0O8BspeN#2oFu${1wAY{EO*n9V;9{AN`nv*RF;$$b$Ytx5} zN#>5+PNSobUCe~V4RT-lYoiC*K#9U|ixz&i2eI!-x=KR&3VVAgsKt2)=fO4!OiNhj z&oj8%Cww&@T>68nFyle)ou_~#lfiP#LS7Mb1R*WxYNo@Fle36`(tCvY-H|>$MMNU6 z!;_Ypt3D-j3Agvmv`Rea!5BYe@K@oltC~%hI}Rc=0cRGX{V`5*({l=XSNA9}%lFwv zqE9|QVH9rW%W}_g7u%LQr>@10As)?C(=flaLqBX1czGI*B4`L2Fcm<@nkiY&MYk$_ ztChL!y%=5c-J;ymkwf(bX6xGI7u)S&{Oab?{X$=Ai5)qLok$;Ri8Z~@d}8U#ydBD& zk6Q3jrqLP~PS4?z+J|(34_-g&F@2}q2ZwrrGDfExD1pYMAy0;gqCJJ*Mo<>4Yn9;S zGv9jV2}i!ek$z%F#0#&Zk=PILy)npR$+m+bYjNQ2hz+Nt6o0v*N=oJT`>ZjbwUTA{#o-iW?mUlirgG zl;?}8esQ5p7Ert*7o7#SR5KJ$1^{=JF|x9R#oS?F>W*N?P5ihCZcSpZ-b2PdSPv4n zTSvE*s}?iYvh@NFMe2Au*YJjHuWGGb?Hwv;jo`@Lb3IPWQr|g=doEi@frn^yYiKXx zuht>`dMx*527Dpz@k=LC6sdldAravekvrVW>(XlC{+_y|_)3=p&?TGucB#E}gbuGc z!$dzznz??0AUdEgsukdpsRmx*L+R!YWk?^zVaIB_0JDz0+0^S7@giPtyR+kUB`mjK z^i_!!tK8tec~8W~C(RyV7vYNYs@c6%o#!3PF_9rGqvf2J&xGx;w}_f{Vtm3hUTSP6 z4az;!)mgKGU2U5tzrx1qVybf!WPnX#gK|3ze~`NQ-XsLlv5S>egel$Qc@8k?6l zLvEvKS#+!626X1i;5Nt#j;!s)c=6q5Xdwx+iNeTg`d!(kIH76nww zH0(FVoeDnvXifWt;(~!Ps+Wh~q!iyaf(YLuCY^EgvLm!0#3M9fOA8so5UUfe3n zD>8mc&7$Qu^)g8x=swUrtUEUl&5gK$?x@mCPMFD+1~$}{1aRv2!toTI4ZV>CmR;N<@^|H>&pZRUWr7)%ERCqi>5he#ByCgS z7sXwE@e+(=&_dt9V^ZfM5e^+s^rlcmmWP55gySJzgB?7iEAv$_dymg;Gu>Y8dS-}* zN9Y#eGufizJ$a4HfCM&MEb1?OWhT=4!qz)f-_m=Ji#3qWA9G{u^?6gJ9`GYMOtJ-~ zQcCdwQ@z$H9%@Ytas@6xlX0U#Eer6i21Zjvw{CM0(x!ZF?>76TGF81ed4eL47iQ3p zJkS1ocla9_5TY$Ea%5NQ0S2DrkFe@!aG0kp z12I6m8H7h4LeDgdy{+pwBQkin3!6JH9U&9_sSTZ;XtB9Fo|1dmlA2%ki!)7QVTDNx ze9yQe&yi6i$OGZY#Ut0c1DdvHTi`b3x3*@9?oFVb+s^(dkwDlc)DSE=@|cE+cI_!o zNvQ;(OM^|@RntILQv&ttUI2rpcQkni?bnK;ugiL2<3X9Ufo3^6RBsP2HJeKiS}_^M z-eWYCJ8Oxi7mX&AuhZTF{|@Y>m^|Tg!jAWfl3ucfjjFkJUoh;1jyl>X8lAC|60@g< zGp|H%sJ))Zd?&dJVhTPyrwmMEp74U;lHROUtGFYp)Wc>1KK0S)nZDeLl+@$gY!#z9 z0(BsUH>j~CMWxZV@8)_IqcHrrC`h|<$pO`LR-Ll81dB(UkU!|xlL5i}I&@B_k4L!NJRojSvQ%oZ4(8|S`5L+9#E1|)UgaH^Ew6J& zw01&lJ*5D*!!`iHcf@Q$vP(~iAYy&IWT?{vy<5!Ww&Wh)3Nm(gylpf>b$y=pw6{PQ z6AS(6*SmuNK9}S5TGqHU;=Lw$4?$b>6?YQQ^P|#LlXZ36$N4-w*j#FIRzih_)806w zv`Y;O-{8jG zLHCv}TwrHNU6NI?iv#gcWw`Y1k(Ap&hR&Ni%>omTh|D460juG|_fqZg%`(d^8yjM2 zWcb!-ZHM6PGT$gk*d0h(=i0CzOOuU{zz`f%H|r{rzUS@}z# z?7GQ$@Mw%$Vdd^I<;F8@h0caxbC@_ty}s4Qp^4Y3knb%b;vF;AlmgVVe2+x)$+~tC zORvvR2(A{lb!fXN64)@%Ain@QaKS)u-hHut#YUlWf~_l}eZ09MEetumvlVNm5sixJ zJ_82vNO0;H-dd7w>Rr5|l~!D7kmubLqcQ8C6CoW{5+xKUsaP?Y`HJxRk>uLqNYEQw z>M1_MjmC}HdJhBjAc`m-cN*LfFv9K>5u%TRx&gXZRX6~%6h6J%dt>sV41ss&>AqEc zC8(C790fN7_?Q^wRZyJ}I7=8cvYs!B8q_lM(H^e7rMC=xX!88MtSv-*Wa~-++}0Ty zCr(g|t?ZoFtIxQNl%TO-&ZvQ3W9@0Zw}qC<1y{>H>Z@=8eW@CRe4z$mW)(^1rE(Y+ zqL1Z;05}<~cE6e9H}|w&EC+hnqt~18%6;g{uj1m6Fg65_dsHZsys-yfK8CRbltaYQhV*MQpdG`v>~J05rI($>z~C#TGPcrW?!P$6x;_u|2O z@;snkbBjFwZXcg(a({V`$)dZ2AKcb9SUQHlJUA}ZV`nGL+cg$F0K*hqtZET4DCxFs zy?79fRwuPLW383Cq25R6N%go!`hqOWS@(G|RE?uaZ0vi_5m3`aP9x@?j4A+F$>tmd z-R_k=A+W78D5*j7$7gj3i`qpPIh-fNS-AP^Jvf=Qr^e=}#@c3YP?K#+ZN0biR>~L$A3uW-18Y%Pgz+ROZvs}o3qiiVhsDIv<21c1 z-jI|h&x-=nZQlzRdxn7t#?C48?p=BNq4a|2%F6j|tt?(ij2c5YWP)~jLKB=AQgP49 zz@rVy@;J!FKldJ1^gBWG3n`lA3{cI-QYb+w4azZW+x~(aHB}m3iJ{%?5R;wY+kQN6 zN^&If6c@H-E>t=3h*uyVwl=a_gt4&7zQhOZTtYhyj0~BB>3LI4G>-aSjN~9`D{6^6 zpx!k0HRjf%ljlq1BF{B!2a6UpCh9#Y#o&@KlP-)xUP`F~6E={=$FwB7=)`Tp7W2@0 zoq5~3me?cEmEP^80)!bf;sc3R_5y(~m%JX6i18*=EAwh6C-V%HIVyY&HJplw8z*0G`OL(hCl-#7sQr6V1&(zlADBTtG5s~)j zrKb9nMR4TZyuCmZNA;wTl*hCP%|J&*V4BkeuM)u$%|?mCWepqBSI){SFh(^ylX z;2D!XZC1X1qd3e8r0usp3C8mdhaL*ziHRPR?&iGpNKNiX@2fVP`R7ZAmJ`f^M*-EobW&*4tQfkyT$F?p>#t}h)9bxwG&Ky+81 zt%h>N!rkDH8Lb(cB7+t!HWFl)$G#knuXrnVkSGD`ZL;LZVg|*W;z+~2HCw#tCtCX4 zUn*>LRb0OXXu3yJ!x}2#{!Rm0&1m0~Q?%;$gJtwIoJnXGX_ZO=AY16+LPxbqEzujF zo8T4zP6W)08*RA1KVi+_xikW_9Y{%JB&4}GmI&kaYBH$NL>|43bI6!?9r{=o3+_!n zh$=+bcX6z;;LmX4DJqFyOP|~$<Eye!&JIkHl#! zB-JT<%bGxr^L2;DTjn>`Rk%2NOaY=q*|10h!mk$1wee-(83&7AEUi!KMV(7%kho~JU)Rn!+#%?Sw#j|~xA69yuq@dZ8-(Y>+WNs9NjqFi&Nk_bcR z7+9SnUi#W?-|C9fO1@-6GkGibYLAs>+zINQi@D^do^p$cgAm=~0Y#*ezJAAPzVIHvGn!|SoRK1Mm%Ec>^`IUFKS?jz z*GMMn#a@^utaM^Jc{8VFY_%N3l*>0{f`s1hz=p?X?U&5LZZllH0pV z%9&4-jVXetxx8N908FC76MwK%9_A05*9zdM>0Lvi-1LKSxiaVn%@13jFD6L|b{>wc z7YLM{M_oNQiGw4!?YlSnBCDB1>bd$g%Z%f)Z6Reb9A&mWnUle3%!#nxYaV}EF5J73 z4HN+I^q#BT!Z_#MJ*(OGz?%rPm70y;Gl5_PceA!vZbia+3$lsNYUdg>$wJ8(A`(V~ zC;e=U=p}pCJuI8;Ox$WOWHEjF)E=rg7M7tj_C##Yn<;u;pupiS+d1*rn)vD5J!&(& z$N5~`k~y7P<_$hec%4bMs_l3BR}(>fMDqZo_B6Ez%o^X}OPET;&Q?MN8S|yiw^d-z zwIRFd4HTi+Lwbuf{Ia|8kfypHyKzaQmkvCu_hLgli~^|gp>c*k+{}8yuL7{NkN2c& zuop`qJ79xP7o}}-@MUv(-eo;xe5AP`=0cN2eubi(_Dl%aL5wX~8a8xkfmIRj3Tvix zbx#^w+bn<#(64a;o+P^p&GJDtJnw*(;%l1FC=9__VE}YqZBuMR3Paq!cZ{q}<)ca+ znh!Y83@3+hVM5i;9ul&RyuxP|5eH;E^dcu=Y03Gi>Gn2^khe$5YV#%{X7|lz3_{I2 zi$_ZSQXvkPI&OxM;Hgau!y9?20|j&a@);?FZrf=udL+fs19@k$XmMn+kEZa6+9G)B zYlHX5wfR(^=4D_%+eaxyb$}6q?_CaJhE@hqFV_hMCCJm`qvscWkefrKl56ko1wD0A z<}OAq-=K|_Eg#l>v8*Zig2$wi1~Ac!9>i=%#KW6tiWx<)SM(BNrz^YDCx~qQmfk#k z!Iq^H?O^Tws(sM|#S52`3(kLgl`^Wr*Pb?nlF!(srk;Z`+$6UD)1@Bh6IJ z%G*>4(T=7(qnx6)l4{)RYv1ELPZY{6|7;?UzCUE4+MPTD?w5(NarGWNd0`UGI>Qi{ zLNmFM%H1%iS}R2S@VWwwiN=UVI9&T#kvCODP8OR*sm270)(B<*jnUcIA`mvU+>Kw0{P zNSU>qtNm8a4%}ZBLMT?`!#jo9MMa5f4X3>V7nX3YGrS#a?s04g zm<#XvkCdSE@a38%+SA6hNDa zn!;0>kkU;$?g7smOu-RKs`%bJTp4{)dQokiN|k!vaXxDXq>#64#|!6l2!!EVNp`}I zgtC2R{4JJGK?Y{4=zBLvDFRy?dhs&VfOjN7njT;31i=f0t^t}w)#iSW{mOCA$~hNV z zB&4f$zO<4m!@b8O%L=z!6v%Oe2C9lrL(WA&6N0r*JuD757wqLZkcVj?8-LxrSEvJ1cl)Mf?u9#doV1?YRkEbIQQeE_Zs;C_s#0td~%R;;x2s+`Nlb^XnBU1L#NDRRUaDkp0R~z zVpR`|@g`Iy1AB}q7oES%Y1KmZ;)I?MVr?WFal__AWONNknK?jWO=ySY*9P#bhd+HW zeUpqNHHa_$ICkmhtX^h|X}>FIToP5oakOia$0>AD{Njw3iD#ebaf?cKIz6zN*fX7! zvgR#Ya6zMe((;Rv7$ z1TaReBb9MMV#$5eU_`HdgW_53IakAG zxsuC!9NQ+sdg52sWG4Nbm0AE{oVC%VQ4nz@M2J$W2er@j-XIY|>?^#P;8&X4te!MV znAV`J8Dgze!jspp)=kt#&FJ9^IYl;#SL(f4ma)*{PuB21ovXD2V4REwN3`k8s6 z+z|V`7dvY%S9X$^nW6LWZFYM=JZ-es(*u{~PR(K>xAk%-blB`J^aa#Kst!K&BJd?V zYlH#LH#NLZLEl@M;!+?5Y~@mw62Xy;2E~CO7 zqCfLPJYcg~5J|_3ofJz>>MLk}K`{>@kj^N!wJ)ExW^0=GGvo&>V}ac+dnZL0kB*)z zRv*0-Dw$NCvH~IlZ3QLMa+)ED7wMw_MVnb2JTZAq>6joii)bj6!h*Xx-v{WxFE_m zGehSV1kYR;ne~Y1oy3cWHCPF>6kxrNftBz`D*y&05iv5B<8fM#qt66AW0pDrHc3F- z1TZ&u2OPq=?XsjQ3SJJ;xilQ_W+Mi9Omz-OaEqQIIPRlaO+5Y%%<76{YgUd6o|=!E z?JDc^J`Nqh=f5nNQ>P?A=H2V!Dz~={M;ni3jGYbM+m-_(;e9|>kc~8Dqw_AH^Sl(C{(m*cNVc)!6_dLTYRnUU6z}agWQ)*YnDt{QaXpe9!8Eng#HDZG5 zN!D1LRHO@ocf3)g_ilUjInZ;HOrVOL%5GyTA3Exh z&r^_~MN$Ea3raa>Zm!czfe9ZWBe1abj-cb$rfKgcon&>I;9jz^T2lFmVD?|#P)@ui?@ziGu2Wb^Nfjs5cYzy zF{?32S!V8wseoXqoaYV@J7OrU&Q-h|j=TAYw@+1^bHFE#tTlQ16h#7EtlFOPdRpUC zRm_#Ub@H~yGqNcOhGe?VX5~V%KxM@&6WFc$Y{ZRWnhG>(b%NIBLK?G#%Jj?>b00tQ zP}*!m(Pf2t4Sctq+ipZDy7ugm%Q6jjws83Q*oe`Vyc6m6< zFC$^%WdJR^V+k@uJw4I4oep`KQ+8gM%#$4z82smByVXlu$L~ ze(7Yx92ULa-I{4D4}2??voG%M1m|frGvGO*4Oi%6Xr)2Wf>dTXz;L^0Zb&9r%&6Rw z;OfGfx|Jvem94<8EfQjTZ7#l@Y_iyn>rB$N)M%j1%~|zwb6>niY_UCia~ZD{wi&=u zuw@3~m5`A#iX0Kp0uF({AsfTg(+(PcvAStP{EKVz(+7t&pi9M4)G&}^P?L!G^ig^5 z3XzH?Qzg%DuE@L=>Wv&Infk@T7G_63Enbj)IoD|~9D6HI7uXUVLpRNxbt28Fbg_2{ zp1SH(r*SCr8t+N6JRi<0G|+kqXOA8E;hSIFTS;rzvf(z4%!a*Mz)`cq_@&}LIxo^r zJ)U;FwR<9-Nrx`3{g=VpJ-CcSpm zC;~5B_m#6e80SRYQ+|(9H^ue|ZybSeT~nre-~|`o4ATvfb#T3Rk;BsW!iip-<5g2v zwmHNBE;a>&y&N5K!bbAf(oA-YH>@nOXT_T^I1y7X^3a*z>O-QL+aU?O z)&L>9u!IPLU@Rbhk@qT}7TS%tFS=b<;~hd|amMzw8V2bebVobwf^MrxESY$^OO#*6 z%(0F(a46xOc-*@a?O=@2V^8%`zr6wVtZiZ^9=k>XGHc=&b>@RI5>uJfg|jFhd7wl6nNYCEevwE44<(tlAKAlPh8hA2;Zxc}!(wDBJ$19EV z2{kaU5yqOpQIygJ?~r<`14RXw^1b0BjF)z;vGX`3RE!M|xH%NTd8@=Rt2;(upBksl zR*}oK5lWpZ=oG%7v_r+H$Cf-`Lk}jw9Pwr;x0WRh(7ewXTQSa%_DE}YyBYl@0t1+? zz3bD=q7L&Q%zYsOp|*_Y zY+k<}-c|?jcj7F^iH!mVD;5?FSRQj$tISU}+0m*YhhBE4cDeZ(K0KfcLRlJVq`p@? z#6_V5?SUzr?X|jZw!vSRyUoI;YdNN{M1}fQE_!jnBc8Rj#@xL&30LM`yz`3>PQEv~ zjoUZ(_hY9#o!JDfGCJ+@@peQy0Pqoc7CEtzGj6?kX-Xs=Q)_m%3<;`cI*-~o7zya& zIFsKXwUTmPO6ZGbUc{3{K3vfd0-rL!XMHaljaXw=tsDS(Fu6iKMbAYl?@5wL`Lgxd+(=zIN8ADafg~ElpAzNOGHO?sMYESI|9@d=<2R%cv#xS<`AZ{|R z9a*#DdYFXStUxI1fmVshcB&h>zLMj2K-yIM$YWh>1eozX*akYy;?_q|==1U*aVMq> z?lGWlLgyVG?15M6kc#S@c5ft$Ee60VkAF; z2_RV`Ida5B-PDuoV+X;cHXY|C=5QGyg8bh&^k2K#{<`q0>^0fD!xzhSmo_C^D zkGPYz_QcE54?GATnzs++Oi7{x5eoMKLK{(&MXo|-I7`^J3ezrTO=qr;2+JMI+K+fc zmR!n*#9yF%@Ae1}A7_jGMT!OkZXFJ{Z3;lG!XBvkn=XJze8tz}^%z%EkJ)&pp zYN$u*_8Og_`somyj;wM<%j#1Xc_3Z=j%zt1KuXTy$~4k~DPr@|*YPd|t9TTM9SWP_ zVmE3R&_>2iXVu%&VmBxWDki1o4PdpX^vqi^*J~d3GmHl8(RrQMBLK%|>I$&xfe3Wh z2!}6tUos@t2tP+NsbYX#U4jZ>g6pDot-8MFP#v;+o$poqtkYY3#RZ&}i#Jc7y9>@O zGE7!CF@#j;F%Oh}&x6LUM>{OBjh!`T(%DWtr`PvPX%L$a<<2YYqINoLF+Ep=8!A?{ z5{JF|a$rO+uvC_$;H4~kA5XzlvszU(E<7`S5twaMTqH3nfG^3wx13~dS_R@IAD?VE zlg(Ny;B!_R4}hHO#Uo>IeLk%kVnfzt##MO-wX+MSBCoo#!-$h$eFu8A=uCO}U>uf( z(A-nH-TTec!w8aWIs)m_En6LR_uU()<*4?$@pPzIkZBWqwUt&YG%xC+hKi;K-c9@Y z+6AP)$)X&W6C7Zugu{l6>E|01DKKRhk)-}qkyZg)mmllOddMDkUyr7AKQp^Vyj0G} zCL8KWwWa7nPuqy4POt~9U!;70iq#XSGG2;5A3i{$*ht+osMZ-06DHbi5UgjnRaadCf9G5d*omvA!guK>bS(@^!po@=12y}KDxwdBX~6a_~pGF}&{ zB0vS_0CPxKp#;3}#MIYJ%JE!^`!b!pJ>c2Gh1E_v3#7UbAV2rWpeAu;QROYMt_18? zh>suoA|^Wf1k%7zS8k0&8kP`;s9_7c5FG=);9K@7ju35lz}$H?49{>+#SSxFmqUXk zs%i*lQ}m@EJ0%;k?YXd9O7~RDqiV{nex$O7H9n%pLf8}U38%e5lj}aotUWUISsGs# z9KI&JgGWxmh*PBM55VPB%6S#uP4Bytz_1$h_lB~rydRL&(;^IwvwhmH^xkD@7@pq6R&9K`WSJN79HPlXlGr-(*w3ap95bJ<-HV;94o4tr?s<>p`5SMN4vMQ& z1=0&te(|g1(i#mbqk(5lJS!oR6HOpbi_1zYpzo`4R}F#3#R?#(Pe1t z;d#VcNWRiWld$or=QEZ^68nfuup1J)lXf{6jyFYn11*BFk2RD;dw{cC9;pt}+N#Af z8{wsR1iWk<)P}r3d-^ zdfkv|#$S;ih+J9*A)Nr)GfvxVsWK;S6b1>KeOw#c9=ut7CRjHz3lxc+leQ8u{9a`P zM`TWzlUNKn(MuUrQr@c**}`XF>}!+FB}yW!{!1Qby#56|P6H>B6TIXl$|+tZlKMW+ z+~Qa7dg`DO;4Q(kEur>}csLcUaMw6^y=$s(5YV!8y0L=TDBbgosOL%E#e>|O$~8fg z*L8H^_MXocW;)R=xw*S4*n1eN#Lr7RPiuTEW|417=fPR{J26BwGnKKC#l2F5%j=l6 z_d2HD4ITCqCLD^c&~r_G;3=dJ;m%kS_q7^`SU3hbaR_Qw!3Q&m71Tn=DP}`zIAOy@N|nxB?06*DT>|9j2#~(O7$8O`ASb$NQ0c9 zJy>6|jakDHrwqw?Yre`A=Ho^cnC`7;vi&Y-B(ssL_XbYKN0t_2mepDw+^lQn>80cX z32y?9fh&-C6W7{V3#mr#ZVR=7-m3Cg`nuSbaedy55%J&FO{`m1;%B zalU9SF;Abz8lZ!mY50bURHvj|at8!myNev6o>$fDxQHfKw0PGB6GkO?gb`}I_IOxt zVSP(Y%q%;WOU%<|dHPDSe*$a)sL`_u7Z4a#cR82d#|W%e()o-tjtRzlWs;NQ@vS+i z2xH3|Fl_gOJAAa8vsaTX8%}~PVez1+9*u>HZZTg-n^#RZ$Za&y3sq_xaXA#zp%Hp@2TZHU%`W9t)O8`bwE$Y zIGO+>-i(uL!DD8CXJQ59R~LH1_$V|ps$3qKy)EyuzIJ$GetAORG+gC*3i<#qgDiuu zl+xbP#_dyEb9#d4BB+gynQFWk4=|q(K9fZiPjsBRAPaj9L|~Qu5=y0^HGtPKBwwot z48Fc$ZFHA#BYo@CE6Oe=QFlekc1)loN5%e{OyCNN4J-+e@5Bm|>6z5CV&(!z>>cik zH_|L3II`G2M^N1p{H$#G1&Yo@4o`r*czN0Q*s>@r9I*#$v#nXUxeQgyrEZ1pv^hXp zWc)Qszl=0fsL8nI3fSh%y6AeUknXS6@R_}r$Yx^1c5JY){Hg{Gp+!+Sgn%?E*gN3+|CcowcfCGOy0ZQbtvlP z49YFI^Yw;c_Q^3lxdI%Gu&u%uW0x}L4RuIW3wcz!Pq-O8?ooLQ1?&67#XoV$-I1QV z@tEypk;A`u0k|h5Xq`1;H@j;$9$7I5)#O@!CRR-o1(9jR{)}Vc+{LLcy5F#sCuH~-WLvyPdM#Tj z?;XHyKd#Gqf_}#vUKZk{giX~}W!avW>7y|B4veldPmnL|Cia#Jujh4zrkz2$@zWp@ z=Zd#yTm_GWQFm_}d2djFA3fE^#+9?+XcBupi<-pE6zCloSrhK(AxL1zac=L-hb-QW zGTp1U@qn@1MasKRDd{w+e0zD?fcrEaXjGfWu)#IQ^Bj63B{KwrZy!FEBGfn&SdHeu zw{I@-aE0>$M*4fNRM}M`HEH9y(>0&x0zJM#4x~5!@Q|JGotUqO;tW{tTyTJ8<(%z} zvjD6B){(gHD->B9Vn>+_ah8z1p=&)f^;5ydErbQ25P5ta=`$PitU=C}_hOTtmZF?f z-GHr~-WImfT+i@Hc+J)8D!6_mu@gE%xhPr$2d7&F9!S;~e!x=Gg*4^dw9DoIy-%|c zE}ZD$t+CFdYXKkwSW?bRAiTMUl9^?J&qEAI^w=eTC1 zKVY#Xd+k|X?|twR`o)XX^6P*j3ZUg%-=TSb0fT+0;Rgn!@}4^D%h){xS{L^lSwlRo zMBQiMV{P^zdwR81HlK6!bjE=5v)Y9?^AUPs9W-zN*&QPrEI|0~J*!9)4O_penNGFt zDmyRgEF_2*mb{Z#8Ch7&Pj&e$VQ7kNgdK@6-#D93~pQ$|2RFL z1KwbjJsmdpQ<>V^E;dDVY4tZH+8_f*dT0R%U5{SVwO1tb3?~}Z5|OtSB$!2kK3grB z1vWF4utd8J9@osBKunw&vh!0kgzof~doI8!aDWfEM1nC6wB&%_+=g@UY|@lMKx6vT zBW*BpU~d=?1~j4yF%`2zG=Qp>)T+a#*XmZq=7=;2Gbz-#qeKHl_MFaiCs%Na?vNY8 zE7yl4DdkPLfKP^ZL~hTNZO-p6xr}v$DN*m1>&>ViT%i!t-UHFAGh?OUJGF&+%(Xz> z2k$EUbVg3+fhIQQRH3wl5Hio(9P1crP|QSQAbtj@MV2FOXirG?#(P z#jS*U0kf5X_7UmMJT7IfE(uHkO7O0P2d9NW_5ln6e+iSuO7@5xiS9Y}E7s+|hZx3( z4|4{lk_wWY`OSL~9-5<4C&x@W^f;HGV`%D4%w;(;;Fu9PQ;I*N^JiKv<_f@9Ah{KYFyvi7SHT72Hkrwc0}{@aqUM-OGLLu#ydJ=6fhonV)X?mE^Qu;FrZi%o^dr70 zA?(@feK3Gxkn7~|3Q9PwF^`J{30X0noy{8Y|F=(^xBlSYq6% zD+KAA%BTO36fQ7X|Z_vruj4sI^@e3 zq%UJ$iyQVRMr)+L5{4~FCHYGky3Kom!%|ePk2Vn;be{~X9G$66_hvj`0ZQ(RzHvG0 zVXcFeo}+%4{8}?-3!2qmy<6c0rUqmd8xW@SYzU!fjE6Vay9K+aEr~;Zc7tmXF3-li zVtRArK|vOYE!pEo^Tr5dS+Mt71C#}4rnO$dBn}?Uy#szP)Wz2nqdb{lpo@C0YWXcj z4OOeb(#fP?VmUINUBab>JiiWzdFX7-s`A>=8Ic8~1)HOtc^f@fTKCKe7+}C9>N&yf zXaT*!d@Rybql;-nf*K`WWtdI~=JAefBe)W{EruX=!uClFP(|P}P#+BPmf~>ZPCP6Y z($TlEA!wH=)&7#65GuiyRBU8p&#}nUJmD3!lZonw7&`P?yrB)^1&8HZ#7kk$XAxM^ zpygvHHV?$sU%$;m6WVJQ}ep@4ZZvDcMJ8-cS3M>rZOBsSMWiE-_xVk~zE!OuCQ{%vh{&GePF`5PJ!XyVa zHu(@$S1w8d>PQVUw-^T>47C_kUW-LR#WuTi+tY+}_NsQ*u1t%&9#HF5u2+m;j9Gx# z!b~LU;K3kuxIQznuX=AW4c|ICd`(Puz zU0|@*N4^jU?^1iQcslM1YK@*w*2@}-HQ<4MLM_CXjl4)#ia{~qvlI5l*3Bh7`-JjD z8?aX?C!Q*Fyi$MHMBqO5fX--Oa)m`+LBG{WYYwlim&v-u5@wNDuy}fSw;r$=UbiA11+@2c=95qm@ZvBD6UxvOQRy(fe)j#frcZ#=!(iQgdkCM8#Tgbpe^ zK@4uldEveT*|MY9cw(CGbs#s@)-LSUin#ew@k_xK1QG=GeGO-A6oejPZ%gySq9?b~ z%lApFmOiSiynRA$_IidBU9l{S zjDwF)y4AMNFG4sP0y|a1?g$pVPIIHQ*0|d2NT&pb0i>g9i>2Q3{$~Lh$?l*gWw}Q&~zP(34h^b=eA2#az*l- zFK*vi8fD2WVb?43r)N*m9~d!>ym;1X-EvRUMCbx-3Mu(1+tUJ9!-u@p^X_r0!9o?N z&Re&j>?L{%ev&A(T^HBI#B@82ONRXX$w7lY0yJLR-7SUFlJx1w+_3HB;IXJTb2GJp z^C&or`_=0je2kkMX!hO}zC@{fT&xEp;n*?FVu|#cQOHaerJlJ#6Yn(CM3=q3l%W87 z(P-q+H2cypD`75sUzyGs_LQ22Jwh{jV&b;1>0va=xLTT?wAD!`ozNqdVMN~?yU?l! zkK?5I*&A8DEC$ow(kySp?nx~pBP2}3130y@k=%#tx|7A?)w96V;``=3^=Wpg$r^@y zr)3n}@VtEI0qGiScWm1zCP!bFGU zpMJ&Hy@*F{+bxkocYNVlh)s;Ry*5NeJW9rFBTV$_ofV zaAnIoyNAQgoe2V4m;qThm<^{^af}F{$z?jy#l=2^!joa)8rFPuQ%YsjqyZobg!O_ zdc9;s=Hf7X$p&?b1Dzl%1k9%1^CivGFKL_>gO-8cOb^ob35CYMIoR&}`Fa9T41+qr zWdyJ0@JTMe07$re=4LRN8wPJt)x+I5(FwDFAB}b4KpKFqu;R=Ej_1~lsE=%L-hzqr zEI__ysFLfeS;>L4WmSP(>v}d#2g@g*Q_059cDLi4UiNt0+uSp?+|LM87>a)v@+nV<8_UTHM&f z)YuoDwh0R?RiYja!z!^uaL}tR@RT5fcWk8N{ptt~GBjxehg_2NDxN+&GwfJ>10|NZ z`{d=F8cArgDs;Vgjv0WU0KM@rtXmV5F!Gssc@&)H0=$xo+B5Aw9T6-SS};vDPvbRN z245T=Eer*AzauO?E$atPAQ!JDCb4xAXT!iA7$ekJF3}zF5?9^iI>+6TsutG#lmYLH zfqQ2f-hAP2xPo@cONz^D!uz4+UKitv&WJodiAinedP68~L%YUs!U=7cqm=q8JkQwZ zS*f3SzUWGp&~r?p_tfUGh^c!$;*$5IFH>#J(;=jT#=wD+GEI?Ub~P$+(4?jz*(Jq0 zu*>%zX;J&&I6ac)tmT9=ndtdI;j~1!aKo%?0YC$ z$<#%pwQqxuDBi}xRb$kg7@EGfXeGg%KmyV&uK*v(;FyI9g=}hR2`o}Dn%Wt;R~)Z) z-#bxD+kmmLSMI_3njnt|F(ToFx_}Q}iL~E) zArF$D)l@BTGnE!msH*8>fD?|l4?D9!G1apB7(=)z6VfgL+>*=56Z5K-Dj_y7UncV< zr?CpTQ`z0~jz$ft^LLe*X!mG#bw~vL5{!`by~mextpfrJT^O=#h60_4;akgtv7L*B zj}YKFy*l9Wi(yx-e1NYb+3uj^U1}Sg*bu?EuGg($Dn8+Z2x0+Xb}N;&W?2Z(2diiA zrbUbPR_n1w&BLMhoO?L^K^p1^v}NE7M6#sCv5mc|M}u6oE`23hmDy|)_EPU%T+`bb zGtP%4?_J+dH%b#XY6)R;hp+{9mM?9DzO(^d-dh%UvWk~^Om4;FgNM`^w(^%Zb-cUs zD!22+k~^D2;sIC*Xsl(xVO9;&o>`kE!}Cs2g&3iV+C_Zwbo{n$NckuP!RT`8XkJ1Q zYQT=Lc?v@VO~9+CCgv6t+002btrAwWMz@DZB{gd~;sWYE$| z@FZsI;utuxHlKCQd*w&)DEUUN^^h2tuZ}X7jR|kGk=^IqDwz5JFRtzIojGw^Lu8(g zy*S?IruF;@>$W=0X6osCs}B%RS!<9*yNS{&TL1%ueOI*Q3J}F1YPE2zPuM+4Rbe3= zrqg3jMKbiQ1HM%3C7Yy2`~dw8V@F3`Xd|z)=FB~HHm4=9Ky`u>Ti{mMhssPoc+0z{0Qyf^m7gc{`Gmp2Mu z-YhA`3y%R6^;>mc6Jf|rP-B}o7yL_{)UbQ%t_0p!Bhs%Mo5A{BnCC+=Uam+BFw|AR z)?LVICd`x-b}zA|c%9>U44~4e$Y2B0b6tZ*cWVHpFt(TE(QG32-laTwDpLXAw7XD_ z#7z6ts)t$dQ0RJu)oqq@3C^w+uIo(?He>9ZF$r!vv*A2h-sHFH93cppo!QeczI}2p zoWTV|tPN_B&5{n)yEg1LT{h8Of|F}X{O!dIwUj!U@!HzLFOg{U`T`Z6#cM-cnpAO( z+Ly$`jt!5})wpq?CooCv0d<3O$!q7lH;^_@ph_v}UImaX9?5IsVaI%&<>Q6QXD z9n$z%xSDg_T9y|9%Lcf$-vO*vb8%G=-HUch&T)PQyhw7=*EgQHz8*{udd8;4Y8Wy) zD{D(CH@Z2dR5UwaYnStCpNAEkr7}oVy@$!B7XBFC+|v#WlgQD!d=^0;5MMr%L!U}^EQbvY>uKzML0LTkA`BKOYL1IB($=c+^gvYBlq2bH{sAv zmj^*TW@Lrr9?zK(V=XA=l6!qag*o3v(_vP3(p zm?Lb8@x9@oYD1?XU@&AVfYrL>suxrTul?jqSZi#~XKSQ&39ogYGowmdr6W=5_8 z%)zLgBxplM5;WZ=pp5g2KzkAvOfO~*p6O)?rl7*Xwe+B_mCY3dzaAk5WdyFl?hVVw z1Wzv6@OhKX#1+7)kTb+0)Ha|Byh2mARy|4pFe)XMZBUf(Nin#m6}NuBy1w=6dYza) zf$ug8J)k{z*2q?0E4Y+2hOSf9xlw?&BQtFO2$do-Bo{?(L&P?qP~Jz6vLCPYaE_da zddEH}#}|wZ#H!_JT`2TM4Q<7Xx4U|bGw7{@j#J(fdLc(7qzjsc;!=j9v2OhaGjF|r zxgcO*>Y`=bAVgaxskiwa||8H|!Z3Ud?4PNn{G z8&;`cFxf!`fN{%u`ffTDFzd;iz_3mf1%86pL|P-p{Ytg4mB`BaRLtf8g@BMV6bBgI zmpP_i=7@pIjV&^vW+Bk{Lo4Wd&(mB-t{;uxU+SE@C7_2(D`&kCg{UPYTzh9(2E!Rp z$EFG^Ps(VnA#sji8~Pc!Qq>H$@sw%84pLRaBl4Fimx_}22o@XVp=_ez77?Sf1`fV? zzV~9bE=eioe$20NbBrQ6P5IOfboPV7C-1=wABi%Ty;~>KR(&Lu;@*bl^I~&e`;^p` zrrd**0Ca5U)^cwqOwL)M(z!AoJRGMj0=+s{^9f<5DW@Rx*nAxG-jnv^5?lA?3oN7_ z$ajU{56quyWVd@|@XH>3*)x}}k8j7{3niuZ6nU@r#VE|sc;RWan?*F2ZB^MYSc?*_ zXcw)|3!w!Y5d~pBM<}Z5-+!ks!5(Im8mRSPdvge0QI4`IgioS%2wS!ILuJjjS2dt3 zp}Es7=D-EGPr zU@&aa?U7fBjzDo0c5%=#hsCvUPympGzR#h{IT^BMESA*7eD_)OD>Y7%e6Rt;00nia zsnKOwp{i((YkeT8MYpl=o@!FR<&R^;z2m{Z_REcTWQlnl{%wD!< zJy94%(o6Wu9hzD!y=Q*dqM2QCk%o!1^#nDTj)tX&m3(P*Dl@s0oJJWOw1ceU)tlDA z4jm!CrmN||F|$`wOf_(w9#oo=f+7W~)v1_4@zy|g z24HrSfevY4^14sKU*Hj|82Lk>ez1mSR#tH@4m2vDm{Zqz+*Dz(`a;~2WJ}^4x$n}u zdTng8pA^};ft|`pnO~vSTBA9ViYRO(JKPZfb0IA_9^buFGl=1V!XA;SYc@(dSxuqWI zXsZu-O1|qo%q8jFem<@`#x_b_QF7k(ynqb_G3bu@Zn2(}4ETmT=7p#+4DM_mRU_)y zr*f~Mtk`cMiQ+Ar7q7OjmUX;i)Mr(2gL2cvtISVAF0-{C)B5aL9N^r9t`et*a6xW7 z34A8ympZnSgkqk8xv-@%VY8OkczkJLmpX_eO{y=wAXJ6*nE?P0$CM;JdauskJZ(#q zdFyKLgr*ym42oF6btMOsou0P(UL9~g#EgW1HcCwkMBS?7%D%N@Ezt)@))7Zy`C9aq zE601~*H4Y|bJ_{|bZ5H?$Ry7Az0vCe4Sj74iaq{H>fNOtzSh6wkzkTrDU#S6TVQ%5 z{90v8vId%`^kU&PItTf>nS)fUZKLRTV-4(*Enmh%e^iX-I61Fv=+&k=wlN77ZVP4r zm_5;XEuEBP7B#EKQmZ*laH}&=%^vkem)~sjo$h-{+)7NC1m(t1iHomBnQdvbdndaz zD4EsU!_QIX+{^PV5JUAS50Tk8iz-tWQk*NCc$ zc4%+?;Z_E1DnNAz3e{V>NpgE9>;R3@M53k+5tWjiV-ogQ-djH|X`?8n>+HTw7;P(= z&GD4Pfk701I{Mgj>vg~*xp&v>9m=Os6k>~n69UK}+b2CIZB7Olb(}$rR=CW~%;ROq zyDlhPIm${8O;Gx<)FE@abKbqu7y~x}f=e?xrGH0Yl4F(gV`&o%3`1;-fe zT>~A%1A8=sxhDwPDmmV&H&3AP9SsmY8!E2Ielsbw&kS#c?KNAQ)j7`u>^(=|aj~Cy zr)9ZX6lCBB6>1sbspF^06piiJD-F;2xmhl^=po~1g) z8}pR(<*dEprpPo~X^?8j9EJ{H1WkN4M1z!42-@Z-P1?Ogc>8!vVofYT9(S zB$$&9SiUyPcm@v?g>I-*TN&YMgrY7wiHh6rhM9Ty@aZ0uBAG5z!2lBQQdV!O&xiIo+<9kn|Enj@QqRLVv(Jr7=-nxY^CioDfdAt<~@MzA6&bvX=e z)e{}I$SOiO9Zc1hhZu;bUn-yeC8<0Y7$`cL0C>ej{1b|Q2Rt%hNFOEfDJjCY~ zSj;&TPG|sd@FFALy926-EY%dlp^-%uu<4B56D|ydCEa_9?j}g1tX( zdVL3&Zbx$;$RZ0{=L|Z;GZ7Y7!iIo%t65EvgU0A~Ffv*XxpO7?LR*%Qh*t{`3P+)zq;3@C1Q)jDx``DDAX)O=t-;4GlV`?z%T^()oaV|J|o z+$8qMN%TkwWRr2vlIeAu*gDo&HG_xyWU;J|J}T9i&S7zxK7H)%Ekn~Pn4FCcdM`z$ zRxVd!1ePj}vYa#6E7no;Q+b3Xl2Hw8$_6HRZ*y+Qn^>&OulBbOJ*t zP#}yQg^zAL1=w6=wjSD9PE#QT*q>JC#6A&bDd9B}3Ay2Hf-J z-X6mWBMh_}>xJD5m|uo9R-3U4Anv+j@3meOO{TKWfL-qk&ro>PL@$#l57aas4&RIn zHE8S6@jM)M;WJw1P2|`?qdFAo8Sr^8Pu$JRm(+Wi*NOEhHiHE-0!u|l8Z5O0DU z@1tGHU5DU2#h0ab&hv~iIbn-R{qCZkC-)>8NTs^RZ?< zxmqmdeyS*u=N5J~6s-j$9$c!V`W}I~D-8Hcakp2#GfVaWiqY)2Fb(!d#1!E$if(+4 zHRw{<6VMZoPox6IZ0CuETf%!gzWx?0Wn`YRE0POuA@GAQe~7>Qf%BsA>zf$$zH7AZ zD?~Ghk~gHRl=1}ek3Fc z({YgFtY=+KkfS9*o*uPc6U2zPI_7MB5fqGo+>BJVYC+gy#tAr|{ag^AZ0jlNig}tyx|}Ua3wx&nm2@g!wf2P5+_g3>%DFF?zb`J z$%1do-JwE`!cCivE&corc(_GTJb~%b&SDNr-$KqyXXi%`p$Xp@zXH{*ZYURuxC55HHPFm~NDr8>AX!6k9>D_v?d&_tMG_3^aQMekK_-aPEWim~9lU@;16 ziim0S_e>th9 z+lTj_+r51ZF)v(?mg;PVUihPqt1p4x_gCl8*Ka-KP7-R_i5Wo9$B~iFO)dq5a7ou? zvjZCV@68wMm>1Oqs&b#3gz-?{6y%aEz~#>Ndj>6C{*Yp8LALpMLITkv1?=~7lpZRT zSE0hm_(^+ERkDH(#9d_Zu!f!Noe4R1MX`idUU=~40Z{bbQx8Ufwa|F? z)`BIpHzKFcq- zRJ^E*gI|&#kR}CzcquvBb!_2_8PI2Cdui`6yEvHVj^4&gJ)*@$uAp`6eqGXhV`#wm znuB9yKxc;eHXxg~Hka|GRc7H0RYc_-GcAg2@D|6I?9EIxRFyVvYqoMIvb2eq``nhP zb^?jcMXPvOwJJFHxyi;pueTH?{DwNUej3 zP9y386$m|)EDotCa@%l!1=33Piu=)Z;-Kr$96O%y6PbK@Z*8+U8X45Zy5b~Yt+0Gk z$`V?p%5Ka&`AQ6Gsmq=mVW&jodBBs6iDOP#VWQa`q7SL{G0#V-0BoWT&JLD$W$1fJ- zWM=ARhw7I>44+fbOLTQFgl^b5e>n%~?BE%O{`@tAL2L6-2!v}yHuYZ$)tlzWl|$zH zBV6Yy8yU5Z?dqAbWb10#^4wS~E6DDn3JcjmSAW+fdV#P+&w%fc01i+#uV@z(9XB=$ zE77WDoU4hFMj9VSU z-cy-$fZ$_AFzCB{oUU^QQf}R3HVzotuB||ibbViDFV@-tK5Yp1%S24N3(O5hi`eGb z(2Ya2WpHmNs>*KGxqM`EMhG4CFyrij=9)YdO4o~p?Sgl+WsK54Om!5m(~jr0neOV< zY5=+d1zopxd0eri`YEdHQ+JtRP{ZA4ME)eOI-sdIg^8RBU+o%hRq`TP*qp>In{p&s z9->ahF)kdGRw$j3!d%jcMuyd~F-Y<@r?NhE*cb4+tzReIi;bsxy`2sZCq0(g>e;<= zFpZlA=AgjK!z#b%?VZ{!UPziQ@)71a1SS>PNnKB!-KQyFjuV41U{0e4Tv$N2^_hRKT15R49Y1k*Po(-Ty0Ps=?}NM#&4$=_xn zh?Z6-#2baWCHH+5K(UhfLOSm43w*;xR5?ioNlthEI`nPW;hFHu3@SOs2z$S)gqIeB zFQ^%I#Yp8Q&m_z`4mP~0cV_IYg^H0Vc?FFeI)rU5;;tTO(9VmXxWsRT{7WI{E5RSD zr!CoCGC*{GK|5DA{UduRzk=KWHF z2+QYcDsRAd>DhIY(RN{*8Wm&tY}*J|xEFV)N*{$Sj_{;PqUjUJW{+Td5{tNxv)=Nk zF>el<$y`8<)Pf<^2=B2@lZChmS(vioX!*rJ!!2?lJR=d}uAzpRh&#)p@;zRm(cqW3oo&?ls-2`pahf}KF_9MJ?L9;k7Mertu8hGrSsW>=yvql z!V+Y?6kn0@5b%3kD?yYxJ9koHZff*iws?@V8XX@Ol-VOqDe~8abA(ni zH&=(Wd|S!1^cr1F7OoCRV`=0i5Eql{Wq`Ugjj!6iRH%h9FzT1%wQ-!!gq1Y~9;K(1uHn7!U zi^^F9$=gTyTApufjx#anL>-cKi{@4{Q*rrK$)vPNEY?C3AhA{`JmLhmdifyU9$3$@ zOrSI+7u*?)a-$+PS}R3uxKKBP=Pe;!KX{Fy$3zJ(X{64LzzR#jR|>sxG_sTuv3$7i zvRsYf6nANQ@@%nvyqdy~p(0+_K>AMA!j>CKX^Ic^_7Gm{vjSR>$}!njz6VV;g<|A> zrthFIfYkxD(KUkw9*NN!hR`FK2Sd}dl!1a8EjZB3uFPXD*(zRefRE~Rhq`k!&TLMU z7?a#I;2TiWu!ft}q?w0#`>?w&#-&&v$!PD4Lm6xv8kvtl^J6wKa1YQFv!*S0aGpbj zo|qUqORDUFA__y~XFwrZWWc(kZ&RyW-&t7CB4Pp+M(T0Yv~3o_0z*8n2(yvLH3K*p zg<_8Mq=_SmxBZbBq^S^`G_0Itx312a*v(qZT8=kAAQzN!QsjY22WNm5v)LQqDbX{&n_A|Yjo$_RjT1(9XiSg-YZxbBxk%3l)A`eD7xt7bJN75ub*PJ*vbniW`rXoVuGcFXxu^7+U@NL2XfL9R~GI@K8E=cyfk@vPEy8)S| zGT$9eumf!Y*yzh}MFKt*zlWAxyN58F{kC z4TOFSFH32Jmpl_u??QWFbRA5Yz*(pJLOL@0vR<+)U%Zleu8}r5DOKkf#)zScszt{q zv=0St9jHT_EpIgAl+Q%?_Ki?k)MSr#2m^Mc`5{X1V_UN`vh0xseAwsV&G&SwKy4Rf z`FZJO8jP12!B()5GXt^}N{CsP^mX4x#`Yrw$6<;)_vWkxYO75ugi>4~bdQzpreK3< zRD8r9SNtHTv}3PB(7LCgz=<Pq#N_^twPOE82{y7F`z8aN>L?a{yKXM=3Ggd<73-nLrxrMF0V#av3wr*gk;9ip zMbo!&hp|-jdTo-D32ffVwzVQsdJ^S!s7bo(GhgJDy2|1G%cHCve`jRxUR&Br0}z!% z&Fv~!cthqAoD`Ssub!(%E=L+MVwYa0j6U5;Z&B!m=fyVZ#!OLbEs#MdB@lkWh_J`| z{M^T&>mF+t=g9)sdRPnbZg)E+8PSQw!HU}oZc)`3mgz5cSK(+ z7OoYysX4i^6Kb6nvWhn%w@_KiYoUDSRZoEZ@hgm$!nj1dJ{fb9CP(;W9&(|>zxVhW9E1lhdEWrEd1oqyj=tIV-it_LQ zEhBlwAhwYj1EfiIGRIzZbh}gvj~Irzg5}+@OA#SCIVkp)aL+Va`z${gT329c3n+T+ z%n_|sz$jRoEY_ar(+3cIq4895@kroNE(mc`LX^fC*1SE|bvMkMSK=L1&85LLGHmJT z(CL#~sp7mcQaoCshVArL&wRYpQjLY4)~U&oCtA~aXBU?Yszu#JbUvNcHU&dsd~C2OqxXBAqVfP zL93^+X*g@I57xF`APLH{urSw}qxlr$#Z_~yy}`})1{4l0aDVZbC-fZ{tmNL*QPhBF znKf0oljgp#?F9pzPS0c^mLnZQpE%YIxW_rZXAnl&tpIhhoAK$9e|f}qqG8$I4;iAt z)t&6IrQ*vcO2F9qULPKwtE;4#E|5Rjp(YOcQ=}O7p4kA1cjqu|&RV&B+%|e{YVb0d zfonnFvDDen#ofDjz4&OKZ*2l*X<%i?dGPCcFLTY^Hq75bB5oxOzDPxx^Hkd9tXQ$? z#j{I{e)Uc>-AmXGY9t$$=vfIevY@?OpWV_^(9T0)={RN@=XnYam4a*%`x*x4se8Wh zvL>H#2F{d)$ZW`ajch?<&W}wAH99k%EalE4<-~>rkbV;NO1w%gDpFUrSJ3rhnzTbG zDZEUZ1D_9ph1YdCzX9zd$ixu_M64cx)_F14^!6-0(>I=wYCyY!E4@UBLJ@9fIFwa` zY3}#-)i|0nx%ImZzw24eJ(-jSc)kw@5&OM&>^Z8Bw~MV=2;b4mh8A<{3RRg`54S1d zE?UBppV1ukJ|5^({A=6865$0Phc?li4?A{ERH_Mz!^tLVU{nELcc^3q|~9HRogDQW!Jh5QiYJ0 zChUC2%}3iw1$nU3GyGn(7VYv1|7j9q55GL(S8E62kWmbpDPe0A;zPVFCzQ0964mmg z32d*cW4u&S)H*>XS%Afx?nb=RJ6{1RT9(dXB=>Ws;7l|gBkzhgI!@L2WIO2axxw^^ z=oB+yW2@+Mc)KfGQ+>$wax8X=7nH)F^6ISvj?8j)9tfo_SOGmL=u7UI#TD+C(A&1o zfXVZGkucs`*QgS{vbKV9U?qaPymj?`*cc=9mEZB#rz zOc7FA>n5q$pog-LV*C_o&QLjaAv0h2yW(&zT|_c;-;8_1AOYjTC$(ZA{BmY|--D_o z;J_FQ#1%E5y-Ihqc;L2u(wkwD?o$SO1)k}NP$_3L^nj)?0qan%`xQus#xnqc&K5l3 z2pF-6d}aY9OFG~sIt!VXid*zt-G*Oikw@I=kiZ2M&QNykR5vyx23G=1viU%jN=yI( z#GS-DO+Hl!IyHJ85Fomku#4>@*z=snz-xSc&3NF?-XNKb$+dXKL&o=3 zsgW0i)wabcLd``TZ7t7b8q#0hTQ>+Jgf$#{B*qRzOM=0Iw89mIu3`Pkph7!+#K;wg z1kJlLUdP46!!Y4c>16&-KZEbxC^9;7u6IJonid( zdw>okrWm%3v6RU1#*eT5oRpx1V&(}poVC2D%a(i(=w#gkG$~e9Chvh5GF!jtwd&b) zpnb}vQV*U5yq2AsBt}|r?&{$aOa|gkT@;=)Xg0^`YxAcEy0WaGgF3WWJ1`1YPs{nl zY4Zw&FtE>o2MG^O;}N51*?UuMvG_zPiU*B!U%V!2r#jqqc}9J}DZzl=`Vwg8s>p+g z&`pkD+TMGx)4Q-rU1CF({4Q}l&vFjM(!v$5*mpQO41rt6V<-R=iDCq6E-RI~%$mc~ z$MBTw84)uJ3CHjmYh*7j#rBI;SQmZs?kYRQfk#!Ltx+W0;tn0S&y{n1uzioji?Ilc zodI%=U!-Y6%_v<}lY))QF@~-XkqP>cK<=Ikr&2`pp2U?P6O4^CCdln-UESx>`(v;r?I^t77)+_WLnCUmHZPYfn zVatq6BxzbAiBUv4l4e&}GW?|y(w9mOwOc*3?>vJAhdCk?JM3Yus`WJSCJ^+#icGF* zNIQ#tknxz+Cb|Cp#=R9zNhW;DIvC?!=UO}xJjlg_?O89E*_4=V5 zZyi`O(i<`3E}n2r2i6=2X6YrKCiB2Dg_(z)Jf;xOscu|FN{(XPRb_&Gd_?c9=eXFD z*bLftweOrU5Xt<#(V9DVz^Ihca5`pvq;6Jko+_DI>joC2UJSW=ZPJS(IV??LPwmM@ zGYQiWzYHbbxwP2_0$uhLXov@&>1!Ib1k?v!$1QK7tvExngh@Dpxr~#x9-O)tUI#ue zu`AQ8N04nb>_*ndy|w$5%A{ThH73E9dPHzmdTm{bcDL2Vz#14QOvlv_OMSIcJrS3Nm7XGNh%FOWs#X5 zf?jLCy*gr{HUX9q^L|c5i%e`&OqU9mIsvhe+Ymc<7tqaEk1~wJkeBf;lMkV%)W!Pv@H4W$y)BrzJbVPwLCCsPI*kSI|>J<_qo3apwW}{l* zVQqDjJI-!tvB=YtUoH`Rxnxm9qF=Y&K&MSk3yXz&k*FCW#LE(AW0#Rko?w;NTp*L$8N=~wnw16jAENv z+Ij<@bVwk#cBt#|OVK_RN}VB-PEGfxf@i*dU5@JOGk#+Z_T<2g;O$~QC`o)Hr)9nQ zxV!V!yr)IrlPzw(E_KLOP`n1?cJ^k0-Kz6SccLEvEzOA@p_F+W5F}Q|@q4IPY1hHU zy-zK6Lu4GDJ|-~rj<$WR8oI&TU696pjfclTTic)x=B{+OG}qpv*Ys`?1Xplw->B3x zi=K5SuB-GceYeNPqwKewe$n7>7gqcHPECFAgzw=qkmGz~qK-imxN*SX>sy6@T^p7Y zcczK=*zQp1SSE@fw`|tB3D}lRpTMJ#cP-u0%QC9jLyOpEmjjbNeJFQG@2O13J(&&i z=V))MYceKLE}slSDX&!-$_oP@cTi+W^q{L@G%ebQhk{(&Xg4W6)Ot zK~K%%DYLvsK&escuV}k4a_3E<_zUYGntmBj%IQubjFmDId1L1^)e7%WwBi&a{k7qv zgz+3h0%?DloI<5UPrx|d!o_8UJTRrifR1Ykb?8tm@V=+BrIwLwbQe#D)I^1n`>2#D&Yi; ziCv}2+o;zTI3t*Z5!}1*E}vbdjHsZemWmiP)=RWKp;M-|qTU4+a=JC9m5Yu_0eE$& zrdeS8qPy?T#>#ZgdEZ1_CTSe7NtbNe6v@2$Wlk$pAD6g&2@-IRlsyQk(gbvGVWxKEs{mqM4I0GxL-Aq%gSZLb^X;apUd9o1T8z1i1WepTPAt3v5Rr5Xf6C8PSFC(1n=^Fuuj-tMHr<$e{gkuWn9Lm1~{; zr4w{{7Oo=4F%AV9P8Bm3+-tDgn-!ht8bpC>en0PH;bf-;&STTMVN*Mn9zAW%Y@@38 z2vabx>(ND)41(YeF)yVLqwz!6ryLpqW?-?XZuRs`IzmR%yxcN2I8rpJuewosuQRo& zOYlG#j1r`guF|y-=E1ACx7q0Df>PHrg=jRQf8q7QRksT>_(6tM)B z;~UXY#SCBunQ`RI<@Y#!_pC2jq$9ZBKCBS1Ygn2ENKDA%sqX5jd+}aiOK!)$;(6^W z=N98@a{9o0)itqZWc7)+I9RI2d0fEoRy{0xp$#ZBGIgpl9rLSZT+@ z^Wi?%S&`>c0&+E20R$b+$x;0x)Kg=m-cm(IDUO=y$m1A(kNW{r!$V8T$Mkr;OSwFT zVqbdcx)5mk$ z=IS{@TP=bkeGOz*DCNS6d^y7Yo*eg$(pmfgdp2Z8OOH$9AsrEC`ys#j1+je^$$-Vuvv+9?qtHZS!Z zA8s98KJ328E2A)c&n>O@uJjb|9F+=tg5LxRZ`V^=-ELh{jWgClCJNwu(-ZIETZV`9 zymSlEP_>@%rRO>`yk$m*4=2}Ta@eT z4>}t{UO(O;uMPM0h@g&x_G|GQS$nKgbi`F9rl1d~KnTV%SNI+W%_%ShY94SsI6Gp8 zBC2@VY}YbN-LplOY)t|z8j>6LR``kxgu29$G0+iYK?zaxjw?s=$(&SY!d3dHB|1Jh zL`#UffO1nv12RRf6^$!3m8gU1!Fy$ckBIU;zgV%SBa@@>2t5`#hG;}xv5Zm_GbY7k zjNnB3skF4$0E;wwS=pOQR-wibgM80Z3Wt&gAo;l|zCo-^F;qywcU;O7XfGBX?HEjxGjH8gkrO5W1e{4fFH7hu48*qWAW;wH}rDRzJU{)CznO zn*R5v#W3_04HAN@+QSw`sv_KAtJbH%%e$p*cuR&GgfdgR!@IhX^ zIjKfSJB+j)noeX2Bgf$gp#imm;ABwecx!VJ3=j0>09dd0nl7d70G$Cn;kW!Y`nES% z0iQ(zd)iZd83kIv20RisrL&bB7BO!fgc`FRKcJ+f7gX|6u0q(9e232u#io2Lq-WFK zMGz8&2~q-+M#0E2`jUmzt?9;#^XfRlXUI57(gz_&Wx}TeedAm&05jk*OIaE!lDs%R zdpg%RJc$+Qed%^6`*=7VpM!VbQb$G_LSlspp=yNgtOzV}iA;`Av}Z(B+>*NYQ6B{p zi-Dmu$L0k$Y(m`;*$%VtlYL5h4|`Pb&g&+0=7ZBaoBn ztH(*%x1s&_=I&HpBq9I?>E2tIy8>hq_u*yV;UpxJhvdy2%-t&RR&E#(#owr1-Eh$k zjT5tNxXi%o;>qY9-#!x1Sm$D6Ol~pJQHmdMCJG4Q6QTJ`=K7)N$cZlbjo+(bi>H7J zuR0>?;;F>wyH_DOkcTIW#xW-t)*-nC(&}&eo^9Myn!*`nF<;+_#_ofBIq_DboGu%H zvx?ZGz#cbuwiISO)b0nzoXr%-xf-hBt`yH_V5;8urKY^WGZ>OYlRiht3BaM4ezgqC zhmrEYyURk3`Dpto2kS(f#LzTO6SmBtQdxVCRIML(`YC9_o)jy_X1pTv>1o>F$0CR3 zJ4%C%q|Eb;~^fNvjYVCYo~Oo#f(d|U5&w6iOdHw89`?dM;(cK_1;uF zf~O5p&hvOY6e0OiMtpk8m!AweL`>96x#%qP3WkftqN%73Q!gEgCI}~cwQtL8z@~NC zUA=e5g`Jaig7Z08?-(@&-DpJil@?CIgUz}V7QLR!T!VGNN)BY|6!HlifL>%b@e)3u zc&jb1O&Cgq+#gW^N-3z#pf+?FV(SZoZq&-la7gbrJ}GxZPsb-K1d}drDXxu3EGL2? zj?tGvT>NS#TniXgtoFr_b zbOzWiHrZDGrBpp6XhB^|gBNAzL+P%?W_%foTn=exh4TOb1%G|hkMgf^G1mb zL2uy|C&LlmJ77cxNlu3iy4MXXZK2j>d35i&#q`CbtmT~JgTSpPwjB*K5LT{!OJgXF z#5s`6OQn-@QcvOXG>weeN5;xDi`r0yUqURM$%p~MOWzQWT=4-6;OtA76JEVLz#StY z)w30<2)cTV%%YC=KxG*;al^-F7Tsf@jEn)X6X1ze57=;@KYEAoMxBa`GW><4LWa;Y zb~=EW5hCFCDA#E_#I`=bl6~Gb|N9IX)eDQBUxyFud+5%u94u)N&PjYx@ZC z6{ak12_+6nZPjZI2Fp=$+9eTmiHknBf$@W^r7$<4?_HF1&zT^vi}P^G#nsq@>T@0# zHqxhDQ5TX$f)iDLIdu~8-o?f>8$YJ9>hj_lt+WEllbxYPCoUqZ8cI=eBQ*z>#~b`M zHA)O4U~^uMOb%#gG}MLNCf;*%CpM=g<}qWied}-Jge>u-ZoG}{8oUJ!mQTA7IivgW zhGvtAo6}=v!Mf>!0NNJHxOM_J4Cz6@NM9*<%c03+N;ln=x-Irb8jRruYS@It;|qWE za3_>0p*87(FuXX_Ak)sY(NONSgR-xJR#=~bOK4V%&$JD^m`yyMzA)t(65^KrX}d9>jrv2n0!)nX%Yf&{Gk z1kqLMZn3YK3LqOsgWWQ#TiI*I3GgW;zg&zAF_=A*>bukdfKb|anDc0#W+3_)x0zj} zj?3fF4SoI|^;;b)NI7^=RE*&r^)Q`!5si@=nFD#vd7@yd%kw>gJEG>}V@DWqm$tb# zaC;AmkI0A~ka;VBKgRc(7cp0*I+sA>rmshZsi%+MVznmJsti%%xZl01u)62R$7Y*V)CCg_$;C&(rUX^~hk9e%@ zP>jMit9g2DJbDF{IO5{Zci)t#m4~3RlHkK~;4t!pRIQ$&BAaJUp2zs)%}HJ&%*Azg zHzLgB1H*jsF!ltTun#S?q#wrc#z?CHV$?aN~J()9Bjn8v6{szz|60ywO+oc7(%24!WM74Fzdf1Pj3|BAhuD z^s&_ySl?B5>agjsdJ$PY20iAkd#!sK1V!;KTO-J(iw5OAfwuNa8s}leeVqn76OXVP zo?Gf%ITK-^K=AHDlF^acG$J1QvbK&>k5+iRM~Wrs4!3hdFN@Afdmo2+>}*&!JRVqJ z@O}HrWI}Lk4qh05QuN~Qn6zX@n-1;jI6CE~YN>DE-4kEqEEYpLsKz!n5u6D~%CdRSMdA#I<8(Celjln309a z;4oHt?U{Q|Ngpd{M`PP5=8nXL&EK!TF*L7suMxAB2}!j=1Yv2qhZR-PsHdXoOApdV`C3}@nQ|tam>OD6 zO84Z0%I?WCG=_&72;Jc8WK?QGNI|z~96)+GvuXUEI1_FbAcET<3={a}`p78QE{sQ* zR*yv@9q)Ky%K&;5EbT}^z0h_kGSgR6Cp4lJw1CnF4s(38?eN0qYV1A1xECn%4uJ+h zb(mx?ZZY%awTpB6@knr1y5i0~dWU8b{rN{bEysgZ+Bw`9Qq1h$Gdj2`I2* z#n{KR&+`V&UD*_}5Tc8NV+H+zlv7TR`mJsd4Q6H0;G;oU$gIgTKjukS+Uj{o}leXE|n|UZO@+J-w9)Lb13e=lat!%;8=*^Y)&Jsl-!%7%=2WThs#{^A@MVkLFfV{l!TEm+o|`J@RKm@4{uVJD52ecn*rHriyuq=fxZy zvyIVR1(a>Hda^!>9evP~8*E?(%=9%?F~FBqwkSgto5r0Ar`kT3^~@$PysS`XOA{+$ z^R?{~FrCLdb6vCO19@#`E}5|!bWV84X(#xXR*x}L+D*3j9m4u7xq!I1tGK}`WhCFR z)P-3E+dwT^(R3M)xWkn^)Ru;l#kNV}@%A=a=}FFDkU$!wZF#7QxW$m`oB_|^o!UG{ ztFo7EP0bv`qhrsy7POH$2`*yp8Y%q{crKRNGj#U(w2qy>M||~?l(agKL3Sn3?wQKO z5xJY05oxVci1X;esWAV}KyvZoI`C;FEi{at?#l6I*lav|LK93*M5;DneC!Oj3ud5V zlPg}8Q*vxu(eCu<%BourZzoL^;F470Z2cip)Z6Ex*{Nf`FxKMaLIN+<+|kX66Hv4SqhW;Tsy zgT{W8y^z>~lmjNn`>+f8#`vu?g}&FMtU2gTXj+M~*6mDoNl-)~2%vKcCdwy^EY>z0qnBN1wN(S63s;RN-mN=74B0re!ZJx#l2+RnH#yrmscCB_ zGHJ#n>}6r9RGP#XykNbw@PKabSPfTu!srpBy+b}pg<*cDsMJTJ`IZ*aj#8^~vbW{9 z_zh={LjXJ@3a4w!bHZFkeuMOKQ_IFhKo}=u40s$T7Rd>=;jJ@2SKUm9l*cLIPaF>? zukDaHP=@IuiQSFBn&?r(jczOy z+d=P`fW+j%$1CzsMK~HAfXN~&p?P!U9#c06yqH|<=*#=^3iZpY_M_5xH83W75uIDp zL^;Rco+0^!>GT=FTk==ckJQa!&27|&y!&|=3!NrWri;Dqts|B&%D=>F3Pe+H7K?pu zTAFo`oDYh&oLi(ZC}wcoQ0N;ULarE;bT=U-@Ul&ROh15A+1UftYf*iQ|j3*18vdZ zMqF*1eFmiObwsmG9WQtuzhqCrBvFFKL#?{yUQD4>D4tPxLOlCCyQx-%7*24Xw#s|s zl2&j9dXvipY3tmq%oY4rx;dL&K>C1bd;O|7E1*!z@?OrqB|bNtq;Yk8i2&`iN*5gc z#NZ0i7%a;$RiTQ>IT5+=)X|i1_m)_@0W~_UA#PQjGYq0i)>;}OpA?TQLM*;F^m^|u zmY>%up_pa(L~#_{17ld*2hZE94{Y7D%hWECUnxvJw^FpxyYuvMa~6D~9D6U3DJvVQ z$5G<=N@a>zQHkV=ul4C@;{;Ec*eY8*t~Bdlt+D}xTxs(KK`~a9fUe1arw<%LIcm=i zh715QP_$@3raZC(GVpltC}b#f%>1po(PeiTbaf9g*D1jWM?5DcZ0~wbu_n4&jFR`7 z^g>8p402ViXv5~!-!~rqoIzBRCD0=u(=C)v#!3xBK{I<8!o~S z0kt(L!Ezi1mB|FOSC1J%;)XPssWOwiwG*Bd(QY=!$aru=oho4*HTcHBdKTfV(BEd| zwY+YbT2>7^<&n~QR))SnToNcTmxl=yU)7e?P#QeKXNRE+qT1x#gXlzi@w_q6 z^wri2+T3@emt(eRB(!T};VZ=tJrwuURzm6)YT;?KdApZG3-mjy0X9%Q?pk=5uBOaF zkyo_})_Q5CK-qhd`egPMUX6CBmEwEAFqoUHWV&ApnL6}=l50aiWshC!~adafsx(@6~D?0cn}P4ix)a3*GVNt?U^ z$Ai){r{}&_PHpyp@4><=nOD~fhb1VUJKI@o9F6usrjH&b@FwxoV|pj)=*@~7Fe*E# zG1D?(Rv1UR+%e_GM+%hhq*k)Lr44$j#a8M}44#?#Vkiw{YnZZ>gg5Kxi?)QBhh^PY z?#sqfM`kJ@54_25roj2s6uq1WSTKt+S@;hY?x>{_y=JLgI0cmpDd-`gRL)PmGzdpfLEyD=Oxj9hFo@r2R1o^F_^Nc)#r zkG{-;X%=*R&pIEa6Va{Zt7E#3^Dt(T=sT4sz@s2|>s*+2Hw0a5!y4L4NU5$>Q5)%5 z*cw(kn(zJjHjFhn87||y8e;AVQJr%|AuX8=ah^vGm6Gbb*)hx=*f6~!|euII?ZpwJz<0UW%w&`blsfJs@Y&$#RDdsSo4wy(}%mv}f_ zP6zRp_;zZqp4;$F9p~aP#Ht;FVI12F3-x8t6fBsm;*A%0d+;vKs@X6ep%BP(4dlz& zXMnbI1#{~ySlmw03N;fClpw1&= zC&t$rd~ukwDy4S5IFFV~M)2Ty(`AguO;I&E`@XdjZtmd$!sGVJJ4H9~h_cw@L{=|g zei|5#m(?KyreIJt;sJZPi@~YvyyE>sb@I_!%!I;HK}^a7?5~Vw{9pd3Z}1 zjvV#IJ6@q)E*^lfW?JzvY&70@q%FC)40SbL^K7a&o(3o(aTnXDzbRr#KJqvaIuA!; zhFaPoF9zVqm}--HR|xQGJ+UIRmYEFF-!wr!AElNs9EbtEn||ls$)MEHjYnEIqnLyVIKn(dDuCV8FYc_Bw&RO9t=i6#vb-jpW?O1oH&=zAS z5vO%WO45~dvAb5WIDN)+f4Q|qyj|MS-IKUK_mWiomA>TH>B>tl)6_9J$nvhnb9S8! zxQOc!j&?vKc3l_C%LZo=yLHYYSzvaT9S6aLttu9qaKeqoNA%#1tog`7kRMGl$^?u= zpCP+wbR|&Uqx9o41&wzUG*l77%)FxMG}?|2qbFiyrs#la zgP4e!MMfr0qBkbzpw=8X_@=YkD0g4j;p-X|9bzpdhQubU99=-t&Q0ui5SomA%3cjS zmLRzBrb}?C*>fMYJG$#*AWSahoaUm=NI~@BQVn0X#(l$0sv4o^CQM9(e6PS9w0*O^ zOJ80uB)n1{eZ!g~@8Gdazl>WE7=9Zo8s|-wRn$N-&hKnQeRj3ll;#yrIh5x^jOoHi zv_82-ebM>wT^n!qX30fm(+X=pow25%3W=nS&hQ@O*WyIg!Dumi?+vmhDg>%~F9y}Y zOWXIj2Hu-e%{RiFev3AA()H<P^>a?l}PR_c%GtfIOsUtaQmLY0P-1ZJQriywR9ad*ta_o%~ z*DXRN^ge|!!xbn&0IpF23X*sL``#OL4a+wJ3_j0VmQ1=mxwR$71sI-6y=1Z@th+c= zg~_oPe$g^H>LP363}RNA=|rc<#ndMzifORxgnH3E&Wk-^R;gh zJ*<;^7?>RDxa-IAjK?v}c;mcvS6HP)t-2T6Y@IyXh!GRpPZ%gbf%TX=Z{15cWxegH zBU=RRa9h10t zU%{yD=z}vJy<=UmyE1w@A_gx-axrR2PseQt);z@;%eqE_6c9G? zt#rQ`^&97XF|Q!9NjPkt7Qe2wa!JkCTa!M;E5gxlSFlR2OS5tRvP=I@MSJMRbSU8TV-o zz@YJA7b7h;w{XRDc^plEHsL`UH0yH@W&3UMY72O|0MNCqjye8*0m*d+9rCW&cAS81 zgIxI_zbV?&@>gyyAM76j1?5yY!SkxU}Ofn z>Qdljrkh@yjgA=BF+B6Zig*a`krn1=(Cg7E6U=u9M!KXxPYT1(-A_ zw-Q?}X>!Xn7O<~!*0do<7ZreEWO?o->4teJ;$YcF5~6;A7c-Ae)vYtz%{K6DgZi4Yb# zz?{Pose7sB1KD@XE#N{I43mMG@6uDMz1wKc@(}Z2F&foQ;o-D7%(?hG3IK_dtZfan zvpwPWLY^}*J!WA5uH_fr1D)D~YdG+Xj)+16&y)?B8edC+hdJoI&)1^zmtE3wd8+ql z;rt=?qxDHA=j0s)4@^m0fh!8pdR>_o*Q%Y*lob{M7=;0^sa()oS%41RHj(Q(1fEG4 z$e)uJ@sj2|1@(PSvUm~Jx8peo7+j%iy2m6nkBx-uFsfW>hB+3{X`_4z+Pj1q_HmcJ zz<5%6G933FMuzh~d>O|(hG5Na?AZZo4Z+y4aH;`Dh-znrHxJ0cJS=j=WZz1j1B`fD z(7NHTpNLK04HG?gm$a_LXWEm4QcbsqYXbOsUUs_PESI7l)$K#ThnceLq$dR|I6T*I zur-@qPt!}YLdV9jC<)INqGbd8I{VV}%?>}srHO4u8l;EAsv6)n;rZ!#b1-=^$yeNyAxdyYRZ*i3z;bNTHDWNlNSSm=Z z&?3C)%GQxEr1J_A+#hzbx!3~iqW~j#Rxd-R!yIl(=vl0x!w#&os}7S{jK_&yaQe75 zD8K_s2ogDezL!-4erffXwtC&IYc|OE<IL(IxlUHac5_r$R!;m3T*pS3M&wBIS z(7=E;JndXQ({h&+sCSE)FYW<%7*L%Y@r)z^=*F$)(97+R@O@ldz^@>va|a&vyJUKx zpzI)P?-rgYWbdnSn=o#_3YmmfU)bg%mUfP+0j=PC7z826239A`hWK`0A?J01rq(_1 zsfCyRrI*o{UWRIm3sj3~of>2As(MZ@mv`?48QyEsls@ZSkm~e@il918OK9~T%sC;# zvxqqzV@KGXr!S{DE8?C4YyRcezy@D=nq@=~ zW9w4~OA!%RXm7by7zhO|gD;M|ZuOe0UcW6tLw-US+b|BbV*3K1dgGA|!rb&4RL`SE ziW?cJZsF$YFgi6+vQSpNsBU`^Q_jpyyB@kd>ArBWV-(>MK?gMkw)3_(43ya+69-|q z3Qg~S2(x$83Zf7Uz+3WtwDh6-UsB-K11SQRbn4HCXEdE+rk8Lm!`)0Mkf9nf`5wGe zQ*_i9-`;fKa; z1eife)8gU)41C!KV+A1Hu2yZHJKHK@Kv?|J>=n@Iy?w+YE~ShIZ|8a0)|1z#p=@uP z_n7Adhg3+?)lVUfM@ND8wmg(s#O#_2aMDOD)d4F83?9xiP17|wB9sd*J9vbsEIbd< z;_cC*7%vd^@lN!0t)}CuOxB|qrK4kr+P&wM{Omci zt0!xb6=Z4aPoXuhI)!ZVWTZID1-H8AY)DUH@}zJ5?bDR@n7wcZlVuu1JM3-&hf3Iv%TFwSGGptbo6#3!38Bals zdz0GY+|6r`xB;);{3qBk&U)v(m(0>E4imgw3@$Q<+bohkB0WRz6+pz110Zp1!K9X& z-84HNEb4n_Z)d0)4sq7r@xGLa*J>TdRd8K0yfWbTjz^o}YG}fwNA%d7>XpO`g8{_!6H6`dEe>KL z=RIb+mj&ZDH9y1&0G-jTmN9Mb-swpXy+*3qoq~s&u(o)%tWWv&9YBhWdjnIh8fU7T@ z5h8%6>SVx$C5`-*&zWgWT>*!_-h8>TdkU6?_wta{x5W3|U59}+nXUB%a6f&Imezek zMO|kD5HU$%*XSB)p0>7n*K6R825ZXf*s0qBN+fu>dXYiHG`*(eiTp@+YM;Ji2$4vE z4JJ2sA8&|@x;lx~E2nS4{7bOVL3xszSvn*{*=Z||=+Bwc2&sk!E>INH-pq5G>%h4k z#bP~qi?ikFSyItuuO8rwZn9J5+*fK57QLug{;y%l6WiMfoCs*?DwgxKU$G+4XjTCb zUg=TcDVGKs$sU|FMx4o1ACoS>lVn3S?=v{A$vDL7(>vP2l!gKoD_svKkWF1de5V-q z=;(A70bfz&!Xuu*6o#VW#_)GDBzG`y*s~B3Z)4isr#XBKBZ(#PtH`0WZmijxZV&)#Js0Oc{TT14NMEedIsR8GG{p* zhNckcVa=JKADrX6jlgYC?M``8hKqStYj?(BSs)M1A%wZw^PaK=NUVW2HUN3T@PmCl z(72@!ulPkhed{%ZnTAbEM+E~@L-RPhXa?M05SI(Ui|Qw5ZDCG`UQ|3cd>b;H&$hhA zye~t5We!RO13~O*#p$Y@w=L`)(nJv~J!MUZjY|Y};4*5ndAShh%aM8tdR!Mg^mZ2u zO~o!=9vE7U1hJ4N9^59HDzl`Lw@!+MDNoM&t$8tnza;zhvM5{d7@V;Cf`8Q_XF zX%0vRucqf=3{gv4y@UC3*5{$W^|On7ro`7yu;1Un!oCdahczz*PjC)Il7e3PooY#m zy=ETpI0*MlQXUG)nVMo!hK3OWFNBHEaN>i8gU4bn05uQ#)vA0=sn)Qm0p0~Uq z*+qJan$#hcp_+gR;k8#9WC%`2%+7>x>qOxCq(YzZbs93|6|aeiVc|SKZeNgbgDVK7 zi)7BXYK^&#J=__{oklmTSAAzx08HYt11~FD5n4UYC``wmvD5Zj)n$#-x_n5ID&^cH z`bcwLSoqtM4Rq@#>xHG<2lSMg1?hP~S{dQIYx7dIgW|;uWu%iEmWO*-$IY$V>tsG}gKrmez}O z2g?5BL}SgtsMQp zc|$bJll9y#E^CEaXe3_R;*bXcUiHX*MX?pn?x6|_Pd^_$ZP^hZ!k1izV%F=>okaTP zy{U>Q1B;usp3ab{K6+8SGOI7lXJF5{FEW%Yd6d|ERT z*M=p0l=iZ{(N;s|3JgD*~FYk(iV8^$ya=|$>MwE(k4c6aTf znypGOwx{}fU1G~Ejys#(0Y+T#)K_ak~@xwz5?ve#Ff+-$VpXaP_8)R0ufXl&W; z-4MhgiLwr=RQN>%j>|1(KI2wo9>MJ<=3oeY(_7EO@*dn{O*(Dd7vhjN3L#vrfKq*s zk5w|?J!CX4)x;I78PKcBXq=+90O6h3O}YHx0o^6((}H$6lFUK~>a=jqWRvDj7-E~u1xwq9k(+iH_!RHw@8+)9IjBU7# zjVsi1c~Ua{^Ede|D(uyss%lANmw<4Lv*sgNy4?4lWKI-yZLIk$#?90?tllHO606E^ z^M`cwn%@i3PAgU~=fH&=Z-&W-*M9KOszS31CIQ;;IA68TA)`Lj4bsD{t1F#HUAz!} z(14N->z*RSIFlGMm%gma8fUPn^HLWE*ChRBDdc2_mN%S2Cd=82+KMl)iy|}|U!Fa) zNRq3Ej84qyH0>2E?G{`-_gqq|SbC$2Z}vrA*QHs*8zi6(m34{9X=og+d{LKA0;93* z?xxCF$X~mX5~XP_57RQgraH9d(j^+v_f8A+u>29aGJ#-)1r=z%*tG)i0ZBJNH`cQRi#J^s~eoi($f{Y+QrT;=G55 zrx3LOMh~9hYokeKwq|f^j-u&`$#=xHk74mV z#-j3`1l;m_q}yFSa`Fl#T?>Zoc5_A&2qt+ZCB;2-CR4O@&n04m-+i^nhAH>yBpqr;Aj zo+EZV?v+#uD|wGPdH1#)(v)hB@D%1=9Mcr>#XTMlE*gCk2^8;M($T)?o8-9U;5p0& z_|GykBwKou-e>@2KColDaq?Qw^fHB~WeY3fZfBZ#4VRz*3k}-k2^3u1Qrsk7>E4lJ zOn8I5o`F737!GrjRY?}pR|5^K+E4qv)#iyD0^Wz$^jy<EYPHnbi6;v270!HUMzk zuu;13G@E0gSyz+5lh8#E;1vr2c6hf&d~D+PA`bm(4DRkd(19l=>wpWnBS!}&RFTyB z>r?=hM&TqzLh#eZM#iUQ=nz=$P6_)6bk{h8Ft)2NLpTwJCQ_ljp>%``fY06@j8aZr zoM}`UUD^WJ^C}+^2^0568L`__#nbFqiV-&o5J-6$+{S4|JOBeJXkvbo6`VU0h)Sll zoFW1<0u*=e+$Wx@5$}5!!cf67xk^zRX~pmgi-NK=(6>kmMZ;C4q}#|sF!}*XNWHGq z;;}gE=}~mN0bY3G1HQPBsV&<^EzjR;1Xq9DfVM}nZ$&2`4o}4taiMbePDVzSc8|A; zS?^Ie0)%foTXB2v)Bw*pX{aYLniwzAJo9D~^XPfc z@5Mghg(|&ZT^rGh=hH>GgEZIEDHf`xYKw8CBOMwY{#>u*;YbbI)8TS?LeFfpQtFP9 zFOWVh^Uv313(0QLYxG2Hz~g9D9k1uo#X6z~Mr^1J>|v%TB}js`)xUO&~deeaQbY@-ht$Q3#WOylZv z*03HYC?QOk&Q$XDG%9>ageJmZk0xy#eQ8xS)Axm$rk$TY!j#2#>$j7tnB9SBho`Wi z&T)4n^rmsby?`v79f4Hd$cQ!Kkc!vxxho=$@-Z0ZlX%o>`l8LT32JoYr8H$IarL4K znBN>b^67}CkBB|>CL}{yPFshqzCFhk0hWcM0lFT@)wM#HCfS6jkg1mEkDqzNwDnO0 zR>*rIt^z^QrEgfB=9RA~Z-})%q#)N)@#}WR;$_6XyJR#BLGxJdF^T4rH(|ifK?d4V zF1;ZNG2dvip0#9olu18UR2HJ-Rf@%^$a(j=S?mHNkQUP#!n=34Hl8Z-OR|91H}76< zVd~?Ihb^hkpi?=bYfb0?!6aTL4x7yMWF0?kl~*%mfOur3CIj6k3#!xL7S-gyfvXJ! z44@N4V$1JMtHGchXQ(@v%i}`1eamstqzJxAFD87BFo4!zMz(;-Z2j?YL6gidgINT! zTMHwuI>tMaJcmnE0CR!ogiTCu1AqloVV{!~og!qLjuhbrvl&8&CaflG`ykU;2%{a9 zCt){<60{M>9W4SElUw6}%x#Lh^bQr)3kzvdG8L@2+Vdtvq+vh)Vs>voq=9 zum|{D%jDS`IehudcQKse<&)Jx!*};2nTZ?X2L;fJWyL0eSLGf(lKapLA}b%_EoY)%EOAr9U*lb$r!hOz$|~<(p;AvxE?zKAxRw z&xb0#t`xw0_O4CsLT}`i!Ah8;hi)x6$(+LZCWu2RY%!UTaJttX#p%ga0#do9&UHAb zdr9kv-e_5ewgmy@E0XPNf z-J8-)tR^+lJuVf?N1k`mNzisq?ssq}^`_3*7n8SDjI-Rko!$WF6Thk;dGRuQ7^1Qv z_A#N>dF=~tR2(K6Lxd)WaV^p3I<7Lwkq&3#@dCZkqUJ4LD-8fgM1xD6MOoO|JbCLH zGc>ksm&hE+p{_3PRZEayG0^ps1$0kJM|OqBj6vM2FH3fZ&*UxxelZF}1CA66qPR#S zc<>^C4B~CS(|nlk3b0fjuLJ9_bHx$c(PhGdO%<|caO_1FV;(LeoxHY=T0DhGwlB{_ zzC2^QI7ri@P6?mKQ6Vz6cRZYRN^{LEhkOc8O9(njxx#qD;9j-+^o}w1V?mTAFIs{F(>FnC zS%8IkJCjjyt~U$=vs~d*>{$V`1|aHeeTCG5t2Md$D)^Q0Ys4LS_hw0GEAG)SDYuS0 z7ZEcbI^N|NqzX=g8{iAPhVzLN$&gaT!t@vQ?3(HYW6}u&4icuUx#4NM+;stRT=OII z(({z&8wqfTK9Mu8#x>Joi;;OU12vlucR*2^U&=$0UK9&@^khQ8UONEWP8_BdBtq`P zb$$skwKC1>b7KBDXd;TT*K2b!OwHa?^g@HzzR2}X6angbFL7kqE2=2AhzDOqx7j@~ z*0ff}+UW9tTxafiy{r=69p~8kOo9Wsa{MV%J;dX4_s1JM;^|yg)C#;1mdxiQwE zfYzz^0Inw3@1pi>`5YD{wpf@QEphnv9e_R-4C*dTFPJyNOs|wxRr>B19x1FIZ(;R<-$v|pkreQ#*(?-_S4c81q@YdLjRs$@Hp+xgot1SHRu zS@Z1BIbEh`HhB1ISmMaaA1S#6b-oU1YFyk?t0z-s+LX`Q{AXGQfO7gh z_B3zwE`L{<&JSu(=z$;&07~nu1Nc=vS;Ii51QBW^ytgD0sRbC*(5vz4aNh8m45CYj zjVOVqn>^xt+>J{@_t2jswi2B?WS=sqjkDIE!gakVLpB~Fc)}8QD#@#Nqz~y)Amn4_ z&=~KgIEzw&)$LA&x%VQ7joFuiR81`ymdIWtr@Agvxi>vgs(o6skDo`08u41_)f4b( zMGqW>=IzbPUt4h%}@^&Bv&#yN`5W8H)>qc=e@S#hZwOTPI z2IK;j+ZpvF-8^}?4GbHyQ)-POK$=(?^@37Sr|JY~n5#?_ophDbU%hf_k=|u8iwip* zpUl=EMtY@~rL8-{s~Id(Os&Zeltp*LyIV=4W0-}y5ylMY$&8U7HZ?Hb#tu0tz-V(g z^^0dla3zKTtOT426z_1XoH}G|J8`pbw!M zpDVJTyXu^4R3B!l-riR-f zpCjTz5Jr3rhKK!j`w_QxT{@#I7W$@j88=YH*d-UepePxk!+EZbe0z%|ai;Z1M`ks0 z;bF>I3S=f(u%67`T=FyM@UC^xRG6(|KwJO=)T?y?=qoHM9zr8P8GAY>B%fQF!IxFprD;EV^jwM?K8r6~(czOa_x3@q z$g3>xy9r{a@qF(YBxzjB)jax7HF|Y~o`6WIC{q-XV13 zKyvWqQ$7XZ*B%V0LPM{S8u*m&-oqZ4lVU%CGI(XLPcVRBSQ`DbhHHdmI8NRmdb^}@ z8tdX?({s557N})H0<}if8=^N{N*A?H^%qqpf2FhAu=@D5i%V7|)LOUjgxcXt!9K_7 z)qT!n#@q+NWD5XN_~;pfM{4j~RbxUJB-#eR2JX9h|hRA@r(cyfl#7Tvo((_Zj&G6on~@ia%kXieW8vwb&u2jL8k z>?MonZc3gRJ4}X;g9^?TnKQziCug#m+}Q!V_BN)?;StmcF|NCdn?d`YB*kM88{Y@x zyFM=Qa>w(D7o%&wSHxaw3LOEV;}3`+8k+GI-vbc3<(ejSI=yniElpzSl8!QdSJFBY z7eJ&_(nga)a6IUtSF{DXoILjI-Q$~TuaFT>Rqd6YRS>OHCaveR&?I!lJ@h7wGxh*w zrcw$F{K)8CXBF+7K1hii<@XA!9|li!cN3ouYtxj*fX?|y`YMW1c-hwCENLZz$Mh51 z+q3E=D&eb$-K?3+XKE%&ry`r_+AFG2Y0im6z0ZOk34y{DvDG95ibEDw6}hhDpQ`znYREO@h-W)gb|81`q1n6hYR{)fbPEYzU^Rv$ zoP!Zq-8EN`V^cABVLpmp07r}&2D1%*o;}?P8JQVHY_B^=3m#Ymr&U# zm3Uq~yK=TIQ8#-K(dyNT^LFiQw!%ZolKJVgg2{_?FmZ1lVt+>UlJ*r+W)F^qDZbr7 zp-i3DgeUL7SC=D6+~(;?ysohpj~F|xqs;6;kF>0|ef|n2TFJRxU=_VB3plvXfcdcn zDb59J0?mRLPhHCNG|mRFTt^e$RZPumadw$IMnJ03(~O>*ddSh-tfvNnJSIF-k30|r z`H<|@VI8Vl>#oJ*kd-p31j{oTX@_PRMXVW54m{@}l8f_mF2l(Lu~wn#=ZDJ4xkGP} z%t8Gult_K($sx8+7)xr+$Xc|)^x=8T5wUO1?Q`x*Q%Y4qw~2Lz*Y7=kM1vsF?5Ik1 z>TF0=<7ch@2Gq;pYSMSc*K9Khp2HyUgn&D&*O^z0qwe*goyNkrdLHww4Eakc zU&FSoBU`j(mEt|)_hc6^Q7o`fVjK?;(o~PZH_SQ$7HhA|R!I3yxK1AD4>@rR@vIP^*1(r*&put- zo#;w@kpQtx+p6I2@eG5?d!2}HZPa4TO3$RN+Qb2SNz;X-SCVY>X?fZe!shS|M$pd8 zZqwF2RG1Dw%84+EYe`zVKft_nk3wwGRxU|wN%Tk8<~k-aTRKZDpom8?V06|8 z$Kk-$%nTwu>x{stniBWkorhSycLhO%efUrhh~n+YSwRYuiW{3?OOwcyzguxj-g-X6 zrLTLz9#MDIDQ|bXQ97v^X%?^=-^ydSC++tf_|+`GQT9nE$_*4Ohw${$H&3oN6CORW zsU2@A;tMRE^@@7T1J->>*XU2426SWtW?b6S@h(LLh4AwTZVAz#CN(@ix?L`^H-7bA zVwNillPg?6c`FV05+??crQw2lxX|{NIB1+7){_`DUTRaS2Q6e3SYEIgdsK{ZG;gj+ z59T4|v(8|q3#wx8^O&7*psJUnrc%WEn6wM~?6BjCP4)zLy&%2v^e)!@`Knb)?dGye z%>l(qAkO)^oR&U#AfsIN#;P#)_{FngKLMS{O?z!=^BzA~el^d5#Y8j81k@g}*)$l| zvC9^0>|-&z(*g93N~IYxnvNF_x}-cy?76%qo`fp|Jk3|Jm5SMG4T!M=+%Hk`I_+8Q zhy>A2S9bM_vMFM0gXxj1s!M3(hAbX)$nAW-6?FhPK*qmt4|~ns^3IweG$dn=2GD|9 zjZD)vNUhndrIpJXuG!1>(09D`;e_ncTUQwAFWFqaWUJJ&SGvu~ce&IUGmg)a_MSHM z1n?sr(T=VM5E%ds1)VP`>}6=KIa#Dlor_t&G8ai41J5?YdwU0RizSu3c%@_L95pXd=Ril7RjKJIw#BQaR;H!m^kAvT z9uHT0C<;@iV<$3Ew)EoB)q=uWK2v_X!y8wqF0o_STy(Y!=}J838(Npk8C=C+EKEp; zP40-SAwo~1U7OdOBJo87pIeI1RMts^0L7c-qv(vYUDDl?sOVSxrbQw$25q>QCMk;p zvvIA`j>DcZU81i-;VO*{Z;{B`CFm86op>-0mw6nLV1xM}RzmVA52^+vMWH_Cs}3f7 zC9l|A5g?Os6ey<9Zr)OGE4J#YEUM_c2!POlJ?~eq77;|b9+#L>(M5xJ%{$s84H)L_ zRt2vys^x@0Z+tQlt-*1-(c&7^*F zIbd_%DiHze7mgqm$3$E(r?4F+W-39ut8QJhqc5KxzGsvazy@-T1UES0n78xBa#Q2> z!A$RCPr*|@L#&{;%`=?!)+3>yID|Ko^2sGN5QNM0mcDmZye~Jrs~nGe;yJ9+h}7&| zo|xTazZ9XU_MlJ#DY&X=PomT#pmk+ap(c^8V*qIA#;$^vMNf+EAd6S9>RFikUM@o6 z@OIFa#bc9B3wqJAyT>u~8f=Xx`x%hWz0`~+=N&Ik`(-kgR_Wo%6s>XbNXMB=AO*Pe zdpR3Vjmo}k3;MDR_L3}H?J?S$&dzd!VA?UHGrf~2hs(${71LD}>N0|-bJ&`za+NaW z@M=j59su)R5^>FF;c$nvEe1pbl@W{-7N>RG4#_-t5(e_GZt8bv`_Oi!4DzFu10(TB?$6%ge%kTu9s)6jKiMMuEBEw_6rYdDcu|3d~?j~=WwAo+S zLw{098f{s{SdtC_wW*nJtUymqUgzfIt7I+F+ueO4)v(XTH?3T{1%ZdvF{rW&$sC|d z(-u)4#JeJ^*2Jc53?~ZR|8HC48WD&zE}cMfY(Q-+XK~@uqdrv z&Mp;`+X~ndt{tvUNWD~%MM89TZx6kKR&1fVv9T3YfO~$;R^W!H#=* zb5PeAf;k{DA&e4=DeU>IAl5tEsy>^VwX}x_PBX=IKR~LhISA}KfWA9xEgh0iBP=oDU2C0?hW%9c~&j^NCS@}(dpG;};s}i0x zFsHl00qnu8iw%f}w`llm?k3gkp~98((Zdx1+EHqpdwx`>^r4#pd~R-a6U>7*uTDd< z-w7+dH;r$6G_`zXkSA>DO!hs@s!>c$&&?-T+g&q-?^SPtlJM35aNlgMzt^2I8DgMi z&jJHuyny-M8+Pdg)ZoVY&o>}EuztvXW~@ZjBOE?BKH_&lN<8zt5unG_uk{8`0v&}!-XfBtJ5Dr_ zIXJ*%KN|}W5m6uIWgRjuT5vph(6O%Xsp;N3Z)LdWxktc}P^6sXOR?4rH)MAg_THKz zVJSX!qJa<^n5v9>CW>+uY;18)m}LDzp{^T)k|78WM3qQ%_eIwwV}S9>Y$Nj`Y+C^V z(52y4lY6;<%sNh_B455+o1!+XmYlS?nUazy?cBwA-KUjy0?CmVv`I!pt}t?P8Svs> zu&INIKzW#PKhPw3M$x|H``!({;m9t2HA%DgTwWv1J9J2U)zAHfj^zgWTg#n8lO?Cd zea1xT$L?xv6DkJr-mRbIGdKxE6acZeZ(%bv=WVoJB)$@(ZZFYe@UFD?u(O2a1YW0g zCqGQ<$H<)xs);<>FEDg!LL%il8lN@U+UWMNaACyC^CX=~)!UXEL0fv@c>q}D+58^w zbCRlTY%sM@4wpiNIK0p)$ee{P<=Xewz0*0})Od0I0pdRND>k%BUX`S}n7e0~Lc6#Q zF@q_L{nD94NDLzZX&4`kDW>!*$6)-&#x zikB5~Q9gUGBU_zPr+PviUtYbz5t^PG;}MQU;iiE zR0At?XYRhUMb~F5tew}d+jOfPi{2z1db)egE{34j*~wrrxUV`%of!jpS^%q@WGLr8 z?&-CH&~(-w(H(tC^Jpz1`+!j?<}r&C`ex~jUHI73Wp;Gtj?~t&W-zq8tF!%h=%tD37(P&oU%|%6sfN{dgH?8oSZ(PH$K>)r zVY68j7nK{JCd+xe_ZY)NrqE{`4iRb9V2PDyqiM?OM#!07W~GTVp#1MD zp?wKwf}q>!#){em`}!&q63QI{#L(pU$yi`djVX9$R-B2$GJd0Cp zyR0QPpJNOJuWLdgvv!Z13LA*oz2-LuXWFZDuQ;qEh9fyM6KI&+>t>!bfNUET*erxb6-{=)e5z=NxKdn*>Hi0W*dO% z#k%$bcdmU0R>996zjJ2f+1k!*K18tsh4W&AG?cP_v>lkdB86cO`ShtAlEm5cZsn$f z#2wQyxFTOPG_i7rqcp6&&M`?mW-<~9NRBzbsJ=98M(rat21cP!d&~mthXZc4P?1tO zJ<*cj0xVu5&l(_K&yBm$I&4Kca}8CgjeD2s@PG-Em0yC(1szY*c+XYxa>DXf{Oa6W zP~+;CPcQPZrN8t@)HFvzgxjF3)AD<7)4hq{DZcwMj^xX@5mTup_lo0sh)n|osPR0# zTc11}HHUSE{{|nEN@58`ds%>d?gW(50?Z<{|F zybhE)uL5Gm7I@^twaSR`ETq>&W(LIv_EZ|)8?`b8OUV!{@Rx?eqpv(y*-0jSybmk} z`*coh83MuQ$uat{-(r{_szS~S!ii@)n$-rOymAANlXKrCKTiZ*xaR6E?q#t^W!p=> zSZ&vU!`Oc74?Hg@qm#9B8=vqIxlA&wA?Fo8RCwElt@`9Wta-ww&Vo9=B4B$QsIUrM zOU(Hk*WI3R%t&D2DHFb%#cQo#d)QbOj0-Q!W*_LF(V^^dhpxRA$ifB}WQU6kG;Jj! zdGEI3Z6volg3RmPDE>{(61ER8d`P`w862F;$&TrE@hzpsH35iqI_fQiYNvZTUa95l zfa)MZwk#+O-m4Kr*P z0aE#e&d%8@^HGMl#O#=IH8mVtM>9)_%vqUz7>g;T7`eSrBO#b<60}e+y58Pi&dE+& zvPesT2_(LQefMAk_Pv=ENGH)ZJ?f^;XeAZ=ybjb0G?!zbpMnKdP!$bY=?N3S>^XL~ zVNsHGZv@r_hq8>J1~GYErFo`zoZ@kUh}qMaH&|izJgzHUcafmY(vO?L*AkVP2v(B4 z31>2;=vwhg;xyW&_)9saFXfOXIKL5B=vH@jczC z9vwZVIKUNEpfZclzKYa?C%&;*T`W?@;g75G#SreXm3L!}C$YZqxjJs9N^59Z54Ni? zXOHngc5i};(?@mDd%+&qCOr12-BfGrZ8r~WhbXlTCOnTE?#EI=hVCng#bYjq(vUi_ zk9sH(TKm##r=e1hv#k^rlGKhWMAa=E&mm~R=~2j)i-p^;yB>SBU5HiyY?X>Z$WmPP zY!=ou&b!67c3w3ahy`birRv1vt&w!9*sk%lVh^x!!=;4>vMZ-LJF+jI9J&+2u5h69 zI?ScN(8POsus0GZ*ZcG9&>tIER3{KUzEh!`D%)*jBtM)d?Qg8DL?781ZR*>RV8U9v zRJ6iOVu|8*O}%*7vZxQWayD;hJqh0+x+6uOM5^4lI`CGp;XFPVAILYVZ(#AYk8{(T z>6OO;p4b=L2j}3r@7*L%d$f~5q{&;-yY!)JHw-Dt7u>IyO4@@Fb+aNL2)Kg03nEPl zVrxV91AI9WkIb-NSTd>aNJy|U*IuMX(wnY6L&?oNg4#p195Sp+;;UU6mwA>4`v@OL z9?;xF7$E3!SP!iuFxTN+!`V)!VIeS9^aq($y~I7qYHu3zZZ8<43X_mVsWK;Mz#^Hc z1_*@UhGp%_E*=7PzG5Gd>hd_Y4hy_=YvbOg&KK(A)nmTuw8Ie{;lj0yta=YBS_>ke#$%L z(TTZK30zKlIJv>Ym97qaq%}gA! zp%ylqd@J}Io8?j<`TA`jQ}aRJ-I2Ye>i2Mlg3OlMBr@dqP_O!7s$rNfTVKi_Y?qO=P*ti)E7MQ8xg*Sxq6*!qs5dxFq#v zZn4AROlLH_nL|jNg#P_VZU)m(Y$T+Vr z5@bJS25tc?^TEz%MM;n+cW^859G0|%U121&GBESen_64)viI8i&1BtHU*_2>-yW~U z5{;TMFQM31q-6yOG(&Zez1P~+x7q`*9c7u!fZpaBQggt2?FjqK(jVoEF|YPp-?;?o zrFLM_rrQE8ZD$u!Hz<;{Dw@E$)U$^`$!FQaGuFZUYL+*|B94oNah!th1-l!u6M4;? z6#EgyEs12UJS?=t>V91HD%UdjxzEC|MAy?tF+!AAOr6`kcP&(}1}vmdh1^bhQWT%E z3^ZN73g1V$2TSGS3sshS>9plQO-~U?t&x?AU}!Z4hR66$x0&t1CB06Ip;I>}8&2GW z@Sf<-AjW-Cfg2HflSpTL>F_K?Jfs9%;HFxJ^cT;2pVIl4bQ@4|we(3{vEAtTD7UW1p>uL?8)_-^ zYjfQ9co5?5NnmL=5rwt>XWhHTd)M@c_?fkzFar2XZk5#ZOfcLc7`BHYBwS_GZvr5~ zT&j-EyR7P=1GQ1dF{wvTL&po%XGE!2sGYD1N#=q3_yuh8oVbQll$<&DJ8hbRTk!3B zRxz?3FUvt0CJqNlsD$uAV|YJTQnR_7Y<&V_m`W|~bYe@9x73eWTN6>=Y6Tm@K>CVO zjLT0BmAAJry~uqRxL$F=4fhGfD-DJ%`=hGr!orDj;C>j?_RU7 zko)l zsgtAOZNDZKPtmwpROVth2|E`BVtcg?F^~mq>n2aOXkKzkFGaTxY+v~+F{7J#9vJ~F zY0_E(_lyU^-TjJ*#kNeO$#1O2s*Dy!Gbiu%pbl!v0n;Jw*}Nzh14C!9R|;xM-gn1Y zDF@py9b|WXP5d6PwwE5l=%;mRpVmF{S)+OCY6{TO@1>9%QjdciL-QdF+ZAE7c0wk@ zBg?{o)#IZV3y*o;+eh{qUoE{MG=+?m!DTv=FnY#5m6P#+`gJleS?r(yO3`tjmxpY& ztIB`cVNHv0`Qcj1YkfZlyaBdjEkL}MC>!kcG!ipDOpASw%NV1eZh;&RI;&(7?`f+u z6J%H#-TKTS3^d>Khd``G_})6bTPXDe8ur$d0It{L1)UCnMC|-%T4(YBrjWmZhnG|o z@8LaA@m}HVf}_=xVC3s(TY2mCbdm6YLRRoG@pe>aT;8SQ?NH`>nn^=#g7a#PWYZ06 zv`M;evhi*%TZ~?FxTfH)Zs}X1SWK*7q_&$B3N+9ms}up;L$JBh+RHav^c3I_6T^tdM!nk@oM#9! zJQA1hu=ARfj#loNnmdJ)IOOflNV#vC!0L|%?ShO&B&2P;Dw66hjsnXLh{shk^g^GT z*~*{=1r#u0YZ1mPOMM#GedB%U1X&5H=XeMVE^u6X?y^Z%MFav!W zEOykRJoTlW$(MG<;ztzw3g@`qgMLp%R?%$1(G@PSt=-XL>PbIap{;Pf?4oBmmN0nv zN?~}p?0R0rc073y1o^Udv{}))lbXvhj zJ>DnSIXuF+9GlRV?kXZcrJWOZJl!X515(t$MI8)O|NcCu(aoyLpMM9A1fG(3m83x!X!P zqT}m(M;O7<`bMW|0G4-&rSwHv+0rPB4g0g6;-_RJYbq@3KB|l4Lh(A+NFubb_}Rnq zXnpI?uGnzLvyDY9c${js79gA7tQkJyAkf@Xvqr->0Xyl!j`v<3HN3OnWnCeU?3%#V zII!0WBw|O{i3T(XT{zDNeY!xnrDVb45k9Xh=>RZdp*uFQ-gYEN?Lk?Lhk9n)c7`zt zJ9XGGQ90>wP(=s_AZ}J6{AJ}VNl=mJUil;$| zK&REd#1K9e;isc8qEl3P%prmShaqD35)b6wijGEwiZ9^i*~-``Y4JY0=si%U*RXOIqM7=Zbg#B?P_#9D5>iHN9JKi?`>s&2KwS15@ja*+f5F-_3nD_#y1h)+rTo2Q9LKkzVSH?a zd283JZ$d`lJ-omk$iiyFnRwL)yw%mzv~B+CfhJYA4$Kxo*P3XU$ed?<4Z&i?a9Ru{fEPL{T<@%Z-H}mX2@dRaa+MMYE6Qte)SToNQ ze``Diii%6IhY!8q#7W!EV7nJ+ARO^{x=MxgL$ww{B%?<=^*C)&ofWoUa)iSq2BWdq z;4wqQ%$SlLkmsQhY{oL@BB603vUnf{yB$zXQJtj=@Zu z^L<>|*6S|ziXon%g0Z2Pk^y67$C=s7e5hy_t@mIRXx^Z^`PmF>j1Q0{2;^~RDf6ag z=*;UP08^zG*1EVw%_TN9aU_n1CFFfGNd72dUq7TMes4Kca$z^@Lbcujs~AGLn9>7H z(2xev=AIfXHK}dko6;b!00rX0O2HEG}>-ho)6KXfRE!^g>z( z4&LCRpS-S+ql8CpaeXofl1n(6nDZs9FzTU|U z3<&p=mxP420WXdFg$_|rZ;*`&9y4~`WgMEKjY>q!bp#?K^r^}C;Q>@oOAJ1YEv_9@`{`rRVG(QJwd$#(RXpA$)1~Vamof zsShxsA5@EBwAm^h>tW^)KOd)>^qhJMjQl`Hkc|82W-BpA7f7$4O&dW^bD7KbERgd> zzOhIb<5EA#ey4>?$EOaR?*!eC>4D87sudMpUkIUMv@l?a?`y2Xmw4b}cmURS(rr>t zsY4(6TTQskYS50l^BCfr02(Ig7Xe)2*X8FY1$ewNQ{t?_LwW$fZWex;v+puz!%%Np zVVIulrs7C=$ck1bPd|7|B<9{G;ALKj|CtAUkqHO#T!iNWYUi3nA3z+hdV%c~(cqEO zq$Dwc5hp2(x*WZw5xoaKY4$Rzn`~Jdqg4wnBRDrEJjCya&BhZl!2)$xAJQPd5gYMV zwy8+cnsdL13_){V7AjT2TyZR{v~-Vp*|m|T!L7^^jrGQ^{o2gvC0*Wg#D;^Em;fQM z3f(9(U#}t^B|HdF7pzy5ZBn$XaV367F)taVaA@BG77QVTo0&98Og}^x6N&5hDtBd0 zg+;p2)6sIG!=VNy2CyYZ_Mjh7-}rM-1P+9C?BTOM8RS6@->14N50*H)(@GIKHSQ8h zi8JQiz0`5N$}L{aXv7J5*?N-=Qc&-$4iF_`BRsekdrgtk# zgZ)}q2<`1RPSIPHJK}y#_QGp7 za;(?=n1KQeQ{5NetH!P(+2UYvJT5~+`!vr#U$x$T?h=IrYYQD=k?Ll78kkN|LC4$^ zDajZX`Vz%k0@)XrPWu@~+UU;KMrigpZhKYqtLW>r=L3$Lv84HQIHo`redK8n^g4Nk z>?0C9lBq{3R;-k;@}GKCek#N%_$JEfO?WmA;nr*HIbrc5zXLBjF!osKCPr+1gbI=B z?sLHRPAX)Cy3CHtT{pduAy^WDln9>1V6)Oa8h(D9#=VLAjIuZNiCJ?Vy1z&MsL{qf z4y+C`nGhdbW2Ot0AlF@7GF{_>!MSOny00pn$IOXzZZ!c& zFcB0UP-^damu`o?dN0O0vE$6uv$te}-Xciiv_|U&6yr(S(lg=`8-bBWV z2vhT!<+5j)RwM&EqjhH8y_qdVwB4gf+hMq*2qBaAGIER{*#o?fS6XHM3<=&P}m9 zv=MiTHKN8fJUST9&FZ!BIqV&>PSGtEzR|fud7)uomz{7+v|88hBYXz>rUJJh2U;bt z%!;<72sQziP){I;PH;zdObjgy=#k+&rZGBlk5>uYnr`|EXC$W%&R1E2B0PvvUKP#r zcnWlG{#s1i^BF35fDwYv12nPs7IE>617FG!|5$#H#m*h-m2VH2z#teAGCsyWk!MDE zTUEr+0aWDUBHDVq35>Zf59G9nhI3!9dRv!l3#w12l35@4L2PHwMX;R>PU=Y6fqsP2Q4x$R6S4pjaaIMgyw^O*0;`L z^qA|^i}LmJe4BU!YKSxUrC!*VdgY@gk3wY`uT+-&I-l^lj8C(8V3(S-NrB(1hsHKr zW73H`HI?sLn^yoNdc&zIz2CwE29{+;cCpZn*=MB)a&*X#XYAXK z_oQXnEY!i=8WL!`C!F46(-1i6+SC~>sCKz-k!$Q5 z2s1b%n7nRc0*WMXw^XH}=xzpuNDe`lMr6 zh;A(K;S=~tRz;R zUrCSe20euj_a4aS3wPAB&GgcRh1Q_=b{Pv(HhT(!4vFU4oFU-7+`;2j^3&(8u^TJB zSCWr>LySp+UfI(gImvc8lPR9;TUThDL4P9sq_=zGR;CFBToL>PWV3AiM5$DSQr`S0 zAG}vIhfL_E%&q;0{JT9-;Y>tDo zP*Kr3gBjIcx-3!k*`BwUngZo7DR@{pWYQ$%3@p?LnaS>C+$E9^<2mMKOf}@dLhYy` zn$XjcYeZwuqYr#z)gy* zfC3W!L@Y6QatT_BT?QtC%uy;c-IxhNtm0|(tHWv!ICm$T)L0-t6YQINL_9@MEM@Fb zAl_B3EeR{@GOev7I5fGLP8$%kLuT>t23?2C4C5ghG-yi+Rr=!kGTy3tLuEQ9)e+z; zT&Rd@Hn==wM(uU)HRUF#>dQ>u0pu-@OP%DnmY9g;28A^uB&xR@TocUosFi~XP1iu# zt86J|8B#+YD32sDuxIWS@|0J~6&I#y$&(3L=?m8)0jeYFd{>Wndd9iZpU!a`u!6gF zmL=8zT^7^fbVB#|i(*9#TRg9BR>o{oHjrQ{i+yZbUWTjs)U{qZ8^0JJ3Kuym9cnqo zv`XreBz3Ka%54BT2ue29D1sgZPhQum?;M@nbvoQdq}06j?&a!iwoDzEH%spak% zp7RiddNQ~*_eiXdulA)G-x^ed^!5XB=%#UQm&Xt9l;vgcsDMV0m6e}TujLJ`8h^@% z^d%oY)uo};!Nvkq6SY!~r+g=9rZ^%NzWxAc`V6Npsbn7=nM~wp;2hrUz7j0j0wDiY zSH*(J#AS~*6GdB*6kQSI2##4Dq=1;TY&J~|_*mj(biAI^42wngzxG)bdW+URRB#d8 zbyP6ic}^!)ntjT_)luc7*DpE;NZTeJjG>;8E4o@(FOh}C=z=Yp@OfqMso~2j2+KOL zS=xQWRF%oBM&5#lcMLA*s@95YlMKdDsgrDp63^zQ0a+E#n2`AqXNIbl7h)Y~i0Dfz zaxXx14SFdqNPw~GM(ALd8Rng2Y*y~lLT>Pe#%^OhNY=*ZS>zj<4ZzSWn_cm+tZYV% z8`NDxQoPQ>VOLjrOKXee+n{xB8k;P-iqSbc^IojLkb+m+X4{oA&Z73cV|kuJ?sKX( zQr0okdRPVzZ|At>BEz82&lwO*O3v8`js(b1+5k2kuBb?=qP*UFRmp&mjaO@!i(YpZ z3Up?OSl)>XbM~+qG3^j7-i$Yiwp56fPXUiLygif_?Yn03wMGi@5#%@Kz+$lx);KQB zjZ@`)y&6RLP<7fb7FX4~)GdBh=sP_}eSTn2#EJPdYaI}-m0d}uu~db}<@CsVRx%Z$ zJb^`tj?VCWIn8-6ng9J?*ip1;nw#2$^TKtY#n+%!oZ82*U+LzgoLp zVP17(Rama*dP&DB2gr?AdBG))XI4~gRl*~gN=xd8N1pRQuh!}&)Nds?Ti!fKY$>jJ z?5!B8J{M<(3~la=`R0k&D|P~6M{v`g2#?3Qr08Y=m*{VON$S1&vX9{NwTlk3n1+am zyH8yzsilBG!+Z2e_IoQJ>&kW?&7e zV!vzAa>y%R(iR3uS8`ZG5)a(RaUFBMELjs|G+n|BO$|r1&qZGGr9FEuyYYB@oozQm za#P08kjWG}$lXDjyHgJvki$q8!%cXUS||)a>8koX@&HEN05UXQ4N`I>b8hbz8ty7R z4zCH+tTUk}w$fpm?`@#%1LzFUt_MVvoL=5K%h~rdBLPg!QQ{rF+_l0J0or_sy;dX| zRBimux$**Oco7!zEpTrz$`zTc-c7TbFg!MLeodZNOC3_=4lGYh8j* zP@)e;T@WN1=glOp;+!87T4y3g#xhZKCKv(77Mh-n&YEA>vmK_x#XvNxb?!2DxouH$ zbstYg_l(I`jiB1tK(4d{5C} z!rz?J3DeW-SDp;s##67!Ln9}~*M?qds^Xe!nQ=T3(}_?0{7b(+R_Cs{k*>xE#)bPP zpnwk6mUcleV%}SlRRa!E)|I!Q@E+>BFh^FA#0O%5aL%E!$vSXO!o@B)oT z+_5>Tw=-2d6^P&R`5eK8n<~ZgoQ#$&T76(N`%xYtnBvs<;BDxCx5g=Nk>+;~1>sB7vTD)&abu=;_P#9Megx0E$X zBrj+?ts%w`n-N<@s+g&$V^CyBLg6^+xxR{v9GsH5irh1;UTPxQjoWyx8r&V-PX?Y< z>9jsA*)+Y>NSo_5mOW>9)KyunnW>z6+9gAck%l|~Dm%%cQv22k{2aB=K!Gn z%IMrxpX5f1RKRFo1xG+<310I?81=w8$m_)1LXNo1Ya6@nGb=ivz6xdXi0;KqUnklP z2~T^?@krp!ZFpE*%tbGgr&J_PE}CNH6;m!notb_4$M)qPJh}#AfxQSst(->})PO4u z!4(>D*4Lt4?67NYUAhGr>tI#~4-ib1I&Olsyjga3oYfxxxK&TdN2nCn2VP>}*hFBo} z80cxj$=HZr__#rE1Y1W54(91RibCvQaAmRaXVEBFj<*ws@5Z$O%@7lz*_+gsMzQyj7jgz5AsGe-4 z8lt%35L(<2Og>dg{Y<0ZqOpRgzc3nqscTThEpFahO(4X6310E?9?nMAz7vQX7z$Bc z?9~uvbKTp_?XCqBqrzu!OIq10(wDYa+T_y-@B$`msO)n2yT{v03IhlIU@O zC3J=}-GGB5?Tj%MxLE-MCWh^_XK;ud{f^9MD+vsYaW{hs?+)~WZ&V*$Erq_=9`R~U zA8Xo@v?5#fvDT}j1_zPcO?i-hbY%Y-Xh9E`!T9wm8%IVusMGnz1TG{-9yV#pGFnP@ zU5m2JE1OcSnoWL3O19bw0&gHW25c#>OxYVri#Z_OV1b#Ri-2I<1sY3r3hj2}IIQZL zjxfq&brb{kj>@ep2XD+Mnip0_RGFzVK@?6%`w(!|1{0Dfy82?lUtn8}m~2HnG*KWC zZHnN+p|orvp}`XbZ_1Ua6TcSVD?e6l?c|+?XdQ`Q5D%llnUW_#Ubjnc&horAx5#8? zAf_Y~vUQQv@F~`CRtt8d<5_DnM`qk3vo1;UU9zLlhxtxAiWTBXZ9!&^2~7mc#@@ZR zgKTw9nl1{06%BZx8dVtnZtOY~nP?@YWLKeIzHVVA;Xnf(^QghdNtJL~;G`NPLr91k zc-GK-Hnz~o;)pOlt&^$kLKvQ{+d=sPB62qICSeYWb=@EG<6@*SR22@K>R4>O0C*k4 zFQQ4NCBZ`$pFXg;Hy~Ry786ie`VilOlsR6Jgy?Z4&%DDx!iTCRCJHceRRJylo-a0A zVZ2TQjq@sf;c)ew7L`;v{ER%HLkSb~p(7K*b(cChdfMQVmyAv{rP@+fhng7htlk() z_~Uk8w;F!~z5wb;NYA0&0<}{$Rvou_`i<6QMXLat;X#PY1^8UigqP{L3SaRdP*dwb zc@*lZ=|+Jpyn86PtO!(7pyq%GP-yUFpwg#-ISpkNyoOB{N6*(nBsFQA0m5+wfashf z+eFx3U3P$*DS&HJPpj)~%BvV!r7=w^ihR@jKmhl23}#>mFP19casz`g3Z=YNO$&s$ z_sZ#w9uhDEWelJaOL)o@0zdgrL3#}K^z>xv*|5;&y7#$S@q=)p_m(8_LKhxxL6eV} z>V)F!N_#WQRB0*6M8hvfQg$yO4VG>>)m-q^J{6|Z7baCW^HLK{o8;I}z_nXcu~}P2Zdakqt28tV7N&x`c0PLR1ZeY?g{_HQ2J>b4Tj_o3sp*_@W9*D$ z=f1KIgFU2gM@rCdu}Z=LWU$wJvUgS}Qu)BP-Wy2El2^OAi*#FC@J3jcEFXrxRXsT- zmr6KCeY1SnzOdp?resZ5NjRM9MqkE081z~WaF&eb7r2&XEciGwj5EX*CmmBJiXTyB z6C(z0CLphnG*y^}z1(mc1tFVoh7FR41qZ*e&7kx|P`TiQb7{mn!8Z$-ub@&r03TIn zR`F0bu`4@K7_6D8dQpjm9(xj%K70Ba64OQa?JJ`f9x0$)D50{Q5OYL?V{PkhD!WPf z1n0PFY>(1gjOWE8qJ1>$E7IO}bXy|JLyYjt21n-cEwvO?$2=5jpuoDgj`t9sr??0{ z0-An={>%Xu5LWpx9xWR~>GT4jvErIPRm!8wN{dKYUT9_4ahPU%H!$!>eMTd#Qim4q zat%@!TAYMmNFaCiT%!yD0QN*eyo_#r!^i-(P#&T=8!yn2%6P+*0=ocWJz}o=)m)tV zv74PWbMAW&9UN2fJ%VPL+`UwKCitbG!Iy%IcbDO0-RtF6{S)Ygtayv{96ti&drsRs zxcreW)cIz@g0L1dVV1nWe#=6bX*oz0~BYT0kyn2%(Q`ED`X7ppb=ir>(_{lzVU@Yh*ZHzdeZ3DZ8nDIe+( zzhc2`DrjwsXrszfMOB7~^(0jEymNr|9ibALea&zbYk`fz+WV->9vCpZ!NO+8pkJ4B zcnCHYDZN7}&J$S@y0d-u7ks`39r0UQ-oaVTxrBPnBuubmL`;b?oDYo?Bpmwcz+Y{X zEUV3p=gMpp7(v|)-UZ027YDc!Wg`!c3Z5BFD1aB9x6-6Nr>NIM;MGx{To&|JpVrmA zr8w*yXPOwm9l=#a%3i^!pnG@;eR?mJ8PG--WA{!CJH+X!ixDIGCfl25UQH78I_MfB zB5v=$gIePxu-`_J@g@7gX4MOpfD4cIjq+ci!Hbrv4_G}VlJlIK}vV}0HJo`jb60qE{cXPQd z$Z|+V$2yqSaJyc{K|c>Pfd3@q_CONYi8DG;Q!i~CUYYme>5BFhLW?SL(A$g&#Nrhc zlxf&a_VzS4&sfMKxUkB0=Eli;I8e7)Cs^KO4TutYKHDMlD7&<^Bdf6a(RsZWwNJ3! zU>{M!xprpr5Vmz}tznyZ+^IU|oSH(Jpe?L>x<{u$w+VvM7~n`C=&L=pl4&ljXO#!D zvX8`5V4~JWHQ#!ZnX!`(xP(qIUr2VpeJhbK4Ud%^ZM>yniH}VM1U=WL0phZlJ4D-7 ze8-?#%;foV2OuJtj8ruc(lj*61kM|M0KIj&!Z8Htder4)-R>wMaMVY-EKg;84tQ3? zZ*VY+y{f5D->brEj>%Vn_15^Fx1MnN(-wMFh_Env2X6r+JH`=)nHeDIJx?&UpTp*o z?Uq{|Z(c=1h)}bxS&&x2N`tf(4@CJKl(+v@x&+)2LpImxilN2i{ zb_|RQ#WNQ3t^-0T8r%-a;>&efef`9dNEzEuYigt?)v}H;#y0OBdrdxbu9Tj6{`iI9 zbhccJF2ATTMcOPIl$PVsC!X9V`jB7HFv>X|4xVQ3*h|RB1TtYhCQt@rTD?a|RL0o{ zcvRh!Q6ty-Vr{08AI^2%V|n!@;j=FZ*%KjIsZ(?3(ifwD2_D~Q&Zkqy<@Tg5i=uSu z8a0gv;d0G-Fl}u}lt%T1z0Dktlnxh(=dYj`O**w6z6?H+Ehq)+tp{Dz<@2a0A4Tv5 zMCJq?h%A&Qb!0~uT0$qC<4OGcItEn3!ZAP0t6&I!@70^oRjU_(Atws@ic8_ZH$8-H zRVq7DH$-c&s}!@Z3dV4iW3YHVEU_AetnpI7O9yQpnCNTP<*~=_Ws&1Udg)4&VtflW zv^PTvXi9h(<)fU)wgdBZS_Jk)Tp zHJC2u$pDA6*3+=@uFUpliM_0nh=VJUBilrd<;O5Qm6?o>=e7yIb5$GZN&$<8U}*{OHF<8-*rP3&x} zW=~^|W_U+DO}b2s5JHI8Zm-~=CI;2z>P}N>n@f#k+EEC6#iew>qMoO|x7`i+Zl`LH zqmfIYI5Y>XTNQ|YyeU~R@Qirf+||r3RJu5(I~^X!5}?LRG?H8 zSZ+R*3^wDHA=uew8gf}uH8~>*)l<L!s0_?Z&BWwYw)yIwekd;Y$p_(ImWyb2b2#5KD?q#@SkP4z=r!bE7KF9}X`I@t)$f z&+93;j5f463w$AML)MLno}w=AHlG2$(Kk_Jb%U$DDIH`W+3g0TGy|vXZY@55{y?SX z7K0;cZM5}4IyD2NsdDY=BD`J35Y~en^a@g?ohZ4xkw@L)H217*GFOFZ@HNR(5vh9C z^Ma9kP>i5)s95|>V3Vf2oE5Rf*~`~9)U=(9#t3!@JE`x*rZwUDyyyMvr2*dRiCR6G z0q?gx>vtMaWGY}Jl|{xVqD=BKL=8#K9M-%mu$<&AtR`3wo2?kA9^*rru5>I7xJs7x zHH`M-z2O)ti|)4OL6;j)&!`{L}wxoc{n6jMUOfIlZCz-3@^&&TXSmv1$qp%rD}`GK|*_DhlQ0&D?b+Boz_ zi5;Yu_Kf(2yxx;|!YRA`z9mrYGaV=yL*&A+OdJT4ahrAXlG|KcE_V$|*QJ_v>d{sT z^L9OkT9nhgeW1#9_&-Lc1ULf@;C(7R_*kEXp~RHgU9 z?Ks|W?x>I{DG3IN5T_I(2M%YUHITlSvy2QF2B|Ncx%o~nrePb*n>&bDDrOlJOPv{V z{0&suJ&+=V#nwc7<^rU7@dBT|E|>(xx03X*J#u%qRw)cZDav9al^cyQ06{>$zsn;p zdElniX@hw6h=K#So~AStBEG8aqeYZj1)cTIHt@#TY`bJ`Q=dnoa;?qJB|IEBonzE= z5?t8!0UTHRTtp3vX_qvvyW153t1L35QCx>fAv}}=uy~Gy8;{>S$oHln-@WGyOLN6J zm09g<`oikx zb2@nfy?OLdH{LeAn^as`>v}9ec{$+robat!!4f%tc<2CM9tv|S10$o6Gyvhac``Vu zJY65CVNgmSLI(~%=@cQZa6&1o&1}MUhnLjM=N()lR1nmS1=c&qL^8UA+Z4}5M2={| zQ#Dgvg-S^ZsE0>K&jMcFK5U&QMnsZ)F|o?~7F=w)N_zhjab*IMgDUI!3>&vUd97~1 z%IXJ-yB-kFsCgnwiVo{-DU>{RA#Ocwk~V^)t1YT`|M}Syqed6+Bl?`L}TOk?BTp8_(X%v)Uj3lfoZE|Zf-V)xcjpm7+pO&K1g@~ zrT_!H=iR87WhFN1Z|*!8vVEu7MQcdI*k7tSX#%h<-rhb~O68QsC|%J!%fS|75ZYbj zC=$u{6eqJsI$vuiJRK_IxU$@3)tQmoWBvhr6DFh`zi7gam6)flpBRl2uAsWjYZt#|1XhhPEp|^BIF~zXNpVK6WH;#5qZSMc z3&tLg6MW2-^_Z^DRk37;Jo$zWXHbS}^Z|%p))LU~DYd}h{=kLDqZ@9YEYqrtaC%FQyk&1LeYdXLUu zoNT#ci!;;<88y_)R+ZfnF-kX!Tch6P=dKii-=S0o*{xdO)jnd3sGYYTz zl#VVsg@~vLA6^mCWnOQZT1iL8q(T_PzKY0#YV3EiZRi781 zcxF9q+&pMXPr+rzANQL(+zOyQXNWSaE1Og(OXs^*5!(6q=IN4SbD}6iv=NlqLtju| zeE0-RV(R3%t(S9Sr1rqAy)s|EC514f3G)*|B9aob0a@|q{h;It#OjsW9i<+VWZ1rl z?rSsTBAP6|pYrQ~Jibcid8M@q5!;PD{ zH!B^y+RJrZ0Yhp+dqz)SH!qdDgw=X9e4|f*IeHw;ZnM#HpYL-tFIDQ5vFq5ohRf8hguXJ%h39M2K1HI@Nbll7@r(7BWUo0P zb{!fEj`u4Gi56z2vW?JpD2zDxwLz*i<0 z({ng9{@T;bYwT+0RnDEnSPx~36{~0GHQdA_x^o5j}F0; zeIqKsBRp`u&zrLxmud_!f%z30XVKCkcFVy&u7(xN+1xJer2-+^jW;vsZc%-6QPP*u zbEh*mt6ZRCTDn6DfmqJ9Ua{(?YOd+S+>e|rajWr2B!xLc1d3$(+5#u?`7!Z}8n2p@ z^Pg#xuM_*8T+4cM!()kACk}^+Z6}K47OqXbEvWJ%H3X!$gO~UOFQAWfZXYx1hyb`Z zEAhl=Es`+quV1{UryE_U4-b5XB;S@0cIK1jC-=IiXSQTVAH^dgLb#M*aQBYPJ+Ni# z=Pg_p80O+#@D?Wo`(bolS)Qi?%1*{y6oF0$Xp!&PQ7kn@pXg(J3s}XHJ-#e$@5H=M z@KMw*E0Z%1%IlR?LwD6954PcyEn8qGkT8_gSt!tAd?b*z5ZHU3Wc?PI92RIW(u@_D zjd`ztuSZ`l+4DAzBBKK|lh=m5Iy-=hq1bN=FLAkQ(7_2Id5E$y+*#Ay=Gc&OP1%Of zVV0&8fmdp=Xr82tlPJ_-#mQx$8!G7O<2aLf?OooQoOEu2h8HEFBAR$+z7^@V(4>Pk z&t`q>f&xmnIrFbM{|h1;8Bh$X0`5aOu}1?-jq|Ag0Blfkij)v1s?&%t0?T!N@DaH z)hB~K2;0foNIL?dvI*^b zY%~krhj@MRnk9MEjvk6~jnO^P=Lc5U9O|_;{+Mwb$>BkhNC1@0EDCXv8Y&2?T{Vb4 z)y2|4VhMxA6uDIC?7|nCjvgKllUP7s4fWFy~3W76804->NBpQ%?!AD0n zrGt+R{0hpN+xfJi09m3{eFs)uv18Uyd&^vsJKBs9Lw0I2>@{5MvPBjxwTj1!$jJ{g9~_ zKtuH84okZpST2-KMz8T^2$$#h6K=?p&c3wmNUAH*J#%1JHP7r;^ru=csbxpt=-HCi zqR2Z$#sQPmRynRIhmo~KW=C*RET@pJmEl9D;}fIeaL%fCq$LyCp1gG2og5Fvx4Kbf z_D!XxI6>Qcmor@oRF?MgU>XdlXSFh%`_%%mw%5*Kpq-*Hk3){X5=U)oj+YT&MFUUk z8t#!WP9hvg<{GMK8nMYS+fyNN1Iq%V7ZL7j1@o|J>H^*pVux|E6Eo9T)`=(#BZ9-1 zi%efGF6(pHiWiY1{hqRp%#=CzG4HXxhsyN&q$SmNqHB6a+|De{0X;?~GT7wODHT)6 zRJI>s6=zoH^p>PsT3!Y_*;EiKz76tYUcO3K7*R9WbFT1b*`1e^5&n`?3i-7y3M8Qg zE`o(1yZC=HmWc-N87(DnNWBS9CF`}uN1DJVKkX{$<;XQTW}jHq^aE(u-&JDCGv3`voz>>dM2vdr?0 zWVh2Br8_!IDS^WceUHK*&WH2%h%;njd9N;c&8l%nq=jtg?Z{0+NmXSVC`>;bFqtK` z83!0x5_I2$LXXI@fo!yJ1C}amPr`mV@4#Xo*kcfd1F_MI;s&#}t_yEP#nloWD>&ZX z1AZ@eF~&IrJ4eJN2Y$_dlO)2i%kEDloZ$7%kL2Voug(JXeo*30uZifn*#oldUeok5 z;hJPfPP?trtykd~#(nV4ZjK;#{8_YbvkGYoo9%9rWs%nj@4IO)xo4Er*9v6 z6fU`ECs3YDBG`3@75TWJZ?ZsjII~EV`jN;{9 zXqyRTiyQnUqrjJpCfh*Rp{@&fw>FGb3M0}l$|86k*>g0Wk|!ZALD`-d#-KW&E>0KylK`H7jb2girLoY=Q9gJ^zIQ!-`as?7#%z0A_$62H3{kM;=J6)pi4t7 zOBXnS?$z!uq8>xmvB^teQ#Hz-B^DOo zoldrr%<6*{S1f`sqUZaZ_g&Y;%jg3%U*9zWYA>TVtJN}hnQe1CdIDuK<@LgJvgg6B|p`oG6qQMcrMiM;4 z_o8P@ZpPK?@$sDKfu3-+`GE zwh#{a25*K=N!qYCj=Xk&>*8~?Wox&w;?=P##%9uf3DYUVp>FSl?clw(hgcOhT^VV! zZH#^umE{z<0(B2s6~)Tm#N|XfNAHOdNz}ANIS>Wea+}GRX(%xgr|pJAS=6RK;m1Ui zIAg?`PtZ8b8zLkdnh@3G**G7STfD?lgcmx&Hg!#XYi~yYdmnf|WjrjIeY&n-Q{Z$H z#YJL|gPnx#PL82AUg!As(79LXNxbw!6)_FM4zZ{QSBWP&&pJ|o$TN8CIa}B3TRPIz zQ)@y47bO&zd_yus#Zg5`puF-OTRxJh2UFEH$9#7YACX zFhIzXMWQ}e3({$qOh|wIuFwoy`$>T#iu>@08=$OX!BEs=QAn@{Y3D>d7g{Q$0mWwu z){Pz#SEj*-sY(kbC5!qj=jH1opoQ`a*t`IgHzIpzz&IQb0+TvVnl;IyBL#fR9K2UKKnaL+2H+ILL&itBZprwXJfH*ULTU91bf!j;*WHbuu>CI`wI!w0F3 znKT24?oX*7kAR7x2Mr7aMC(r!g4&(xSLmAgIoUS#;6-A^psu9Jh3h?Lku#HOTH%5vcwC&jH$0xa@;FUfpkC$_>(Kx6}^cTSSFE7lEP%SzV1E{Om|6mEvP z$HVcQZG|YQdx$70!hn-kHaDY&n#UwzySV!`RP(sKenE^?)!wutgtXIMqz%&gHj;O} z5jb}x$MS#_&>9opBlnZUcT148git@evW$nXWX<0WS5h?^AHEK-H}D#rKnC){Qn2T= zHrmQVf#&rgIj@r-6r%F$4n`4%XJgRwrK5gdV0hw!idsz{M5_5CNyxi^^J94@TtLiz zAql+0w06v9cBc+BDeYL(3j^!cAbBG@P1jz6f=%(X?BE$kVT5!%p2*1S<%wZaHv(V@ zSLC`xvmv8cMwxgbX!Z)=3Ccc>dAD_N%gxmIGSNNVod5Ij7v;>Bch8ByPa%&l-rGDs z8jEWn4%o$4htF`k9uI>15L+sXvO^ig%fXu-MSO#n+=7t12|*JclpETw;=N!n)qdLd zoTU-)EQXdjG4Z8%EC{qt@j0gw+K#^G!-2*y_ylwpGVJD+vxxXDR2%lT0!mt56r8Km zbEbV_;T8q{Na6vr6AcT-2=j~FvSt*pyg`h}%I)K9UsAD($9CSb9MNv!Wl!d`&uSg} z@hVMcyci}&0;rhtiKwzR%~y6tu(-0O>>21C(X-aYj0y)HR`pZ}%gHpengknYg4bA{ zH7j!1YPn6DC1^j%rEPzkIQVo>6DjA=FJ4eQnB|IP@PKg-V+cnbeYwQ$p_y-=%~*;7 z#sTPIa6f(}O2cFl>BmvH1CZrmn6?FS7O`o>`syWn3vp$P5GnNh~tkMZdF=wAIKn3a=dRM0o5NM6=OeZ~rrtzK#;vwklu+DnH zNI|JQRS{S+Vpzo}Gsdv6wX8vhJ7ttzbQvysj>qgb!^^?ysweFwK!_@vxAr8SMhxU~ za4MQT&UnyQQ4iFeY~H~&#qkcy4&#ZwfHYpseu19S+$AAjKHB#!hH<^*V!;SU8HXs@ zp;jldM(uK2xobEIFN+v9?V*bZtQHQc=&K<;H3GQ|e3#;D7J$|z-gwuzxT5r=xa9GR z1xR5R?sEf7RYgJEMpEF_%oZNEXNg4=Z~G-Uz|`%6P|yayBkW(GpCHO(5d2Tbdsf2M zqziR4PZQ<Sj9{+fV#12 z>n7+m_HcloF6TL@ZMjpfVBk3|7%|7Ff+|^-P@VOt91I&N=JP#z($z0sdDx>)BI$|> zSvC_dHe&XXaCE|gV)q5_jYrC*>;0Z>6z3-MT(hH=21T+1R5`2g2rV2lHklNL>DT=fn&4UU-53@>W$-w88WB@FH1}`YYy>_Q80Psxb zQ-5&`6Pk>X0_x$2+JW#lE)Vkfk>@+DWU_kC zSuJFl?CFYe8%U#1$;#+|66-aK?0v&-(mc4z%?m#pVqm^voMSSt(ski%OB*v3Hj(t z$fv%^xB1xP@f4KTzSW4TJy8sPJhnDH4?{QI^*RE_!=6zDJ&mS>0H8p+0$=FTdUg_M zlw02CukcYH=U@OS&l%FaS9s9Mv|M@}(KL+bX9|cGn&2;4cV%~VnWfocd{>9!EYwlQ z%_bw}_+AM7yG6D?=)NZx884jP;=r9RPIhq8!XYG7zLZ%Ibmc&udgIonfG{N}gainr z!(w`eWN%aF+Bcx5WPJYZw$(}vX%?YtXc1o)kv)rq(?wc#SPu}7mfmGlE9t|LOS)BEf+?_ZnJTz&=43WG z6LC~~{RAWw-;~eOGlM7g_I6-Ap5^rGcVx;BQJDxCIgL`VU=4Xp8nP{<5b@DlcN@ajLn+FmJrHVHYS92I~eAvzL`E?)j)PlG_!TU&zRwLZzhwHEmHn z5mT&(r4dgEC>`9NL(f*{p=WugujU3hL+nlIXd1`7cCI~ttC=Mu!1pqSXlJmiMmZTzvlGh$mdCFxUA3mj9s_a0M8c#OZRoNjyW zwy1b74X*v2N@0tZ<`u=>Kn#$&UwfMDbpv6u#;hUfPxs7JY4`xS_rx z=c9XUutjRUx})G!!49Eww9PP^O%c1PWFBJOB#;Yz4drS|todH;NU5vAA>ySPLxklh zf@xZYzIeeRP1bPL;liX?ChZYfiBqdcl7wj>`@m8`o=^D(A93^`j&jkVd4|}=i`)wz zOYY4Dria`lSdPyQk15|F)AsiAwLXS8JD3iCR>AaI8n}h>$u^-aOf8VjpuOFYTQ2~n zi%MYL;kDZH>6tEa@743clBotvty8>tqy$FJ{eXNNkP{yqOiLEROA+eO0z%1$!!sjCGZgl$cZ?^3)8n7>K1-8IHP-n zDm=tKpe=16OE!el-QND3MK<02kRCrG^b|!b2VP#=1n!w4eX_>3CD2JiSBw@;0b9|4 zZ7Q?H3rJ+j5-akZOOqGmJSHN`58Ffo z!Sg1Xb!v!pp{(pqS~k`9sY(q1iGeT|p-HFWy7|43_X7^*1+8Qq)ar?XD|ZWwtGE`G zyS`1v(*5PGFX=en9e`OB3& zPSm28vf`1F37BiN#Fv27x9n90SS$>orIQ5RRN}1EMWU??mUJ0seZ?eYvo&doOoSM( zNVagB)MQENNnj}ld2F5r2a>3dvo4>X*n)bG6_@LPGtXLJ;)3_s6WUi4`eu4yL0tXD zB>c5mS>@$Ra5|<@R9D(yOm=!fS#r1dieo&``woD*02{h+@rJ3&3urD(o{|!;$(;3* zauIqM&GV+8_Qv$8Jjt;mR&wYXJRtMKSPNANK-&<{hk|!vK+KR3*7hu-C}yh4&kW!_ z=o(lKFF+2a0#ULA)l!_GgIrhEd>a^Sb%ePO*nA-Xv`~(3V%b=aH4MgMk!7P$! zlN6~1+Ix^L_(0$hcK40ci_IP{)8uEbS1aE>L68pDY_;<4$gM%Ut&yJ8oI-|zJ7S7% zA4A+inQSsox>#fGh*{={cbkH(l&^J>@r{;F?yzp<8%={19lU&-S4(%i?39ew;%{$Z?NF>e)o85*oaL6F*=Qy7Hded+;m*()vY`a+8uT974tvQY zh(pO-nw{>$5jh0Z05k}8!3Am-0Ca%Xp3H%Z9!f@$Km$?g*#cfa zXxtw4GcNZKL8k+j8h8Z*gj@AQ-kHIgRW+m&_H(5{=W?(ESIxzcae&9Rb{n8`i=?J8JV$zs(AX%5 zL}W_PTNfiQ-_-~J<%mHTy5#3WHbzm>E9A#dE0=FmSKA82gM2#( zB95E)L&^a8lCt))^a+Q}J1={nOQWS;)Ywi?MY4QSxx9YW!!~t~Wfx_2EGr)6&aes) ztC+2my27rsB5lSC&AMSeW|+8n_hOBz$~bM)br!WYchk;?K$1MvKx4_62GI@Y3f8n5 zUbZJ{u={8;y|+Y<+|Kk)S4(pn|Fx3Wf{WC(nS#unI$mv}!H8wAW*uD0%K(?_nMkV%9`p3C!OkcU{ytuOR=3-Z;0aOZ-piwJLN#58FX_u>hrn}Ad6aU=j@FP&%<5Oeo;xrnT`Rpi02LjTCb|7Qstf*D(n-f!KIG3CMBtm_@Y9f z0rTbFCh-zYvj~r=F5_KZ+PhZON3VT=ny+~FjWx2cpD}TH)a!V9traj1wZ1okRlNac zY@L92wVcI~2`4ND$2^x3^w3ifAL7QoVc)D!GgU@8)?q^e;#ZsEyF0BCqy_;qyPhR= zWERNSR~pc!RlR`TyUD#Qk>2IJtmwUdth@#90^k`y6Ij2qvcgG{!zAMaj`w&^FXD1- zqNo@RFyioyM2^KM)|myWD4y{4oP1e{^kt>5I*MEdz8G_p=SI{k3jM^%phE{Mh08BW zBWpW-g2jFEu^8_OV0g)(T|vQvM}RDELBZ}Y2Cz2agv#?`A0{5wp!stIi;-dWn>~O! z!MG{_2F5vic#{0$g_@iNIn73!3OtuL1Ct7xg(lcQvndDTEaCS58~pik>63K9cHbi` zOM*lIBW0G8+to13A~Z2KRLqLo0jEyMK-7fNgNW7{sg*qhr%`4?s&bY>+OvSVj0`bIpygEzex1cfp4;+;#+w9?c_l%yElU?OD?n>a{P zKy4O79`LhH2p^HvLBT;|JA=n+an$<=`Ap#L@-uT-AA1%;gqX2cPi-%zQ$U|&4uQ+% zLK(h!^yY|7#A2=5m2Ai@vz z$;72Q`n2Mh5D82TG=i)L2NyLvh6sa?lRpAAdB($ayF^%*5fjfI;KMgUDBVlfq|dmq zNcZfKTh&{Mr@@5@?*-Cw-m?f!S%Q)EoO!t?_fS_4+iT3%19@T`^ohKq$Jc`QAb|o> zw{CjH2m%6t$pMdgPoy1C*G=c?)96=(_}bRDtn_hsMNq-QxVuXqP2WR6bl=b$jEQsuF?CKF1w<-nh7t&lqYAJF_}1$e}r+ z@#-bgAmv{F=Otq6%a1>$M(79C&l?zCKiwjvf}I?6Q2;Vr04F{n z9+zsG9KLI7%Ce_P(tUF_5;o&H3zoCY1DO({`!idh6G7a{7`#?y%>y93^ z$=guAiidIOnbC}K-J&a(15at6pk2%X7$2tB2`{55bAwpR(LPd1pxe!@>5(~%0&Mj1 zxosQ@ys-zBHo{VZTL$LIrtuh@5MI{UTp8U6c}1b~;`MczN?N~Et-u9CHFc%9lrwyO zDW|>16#NV=@=&;tUqv|jBf6J=lJc$$oeU%HoES`V6!~sz+hYVJ&D7@ilTK zt8re5Z2bNgXDj&*O_BeBnTdZZRal)C_ygKi^ab*ruMP)ec zJrIyzSyVg1SafgrSgi{TgfZV~VOd{|K8VMb0={Rxhb5|;PcZNxZuf{GF@eGy-g*|Z z0B0<3qAB!H-lv!TeFBlOYi4ZB5?WkAi zpu7}&Qk}*zPo3aygB2nR{A%A;K2VViW^ArxmRC?B3%6_+^&-NUkQ610)*d7CrcU%R zI^Jc!dm&HbAzR!_K=;FB^Y?;C-SG8O!amxL7bG~o!J-ueO2UafX+eU1?y8lBrLUj% zdcL9o40jl6wKklF<<3s%F{X9Ln9jRkHVI!GecWhdF*IrlQQJHEq8*wKVg*gXaq|U2 zl@Ia(KfZLJlkhwY*gBu5rWu^?VP3bl;M){~wRe)69^Q|)d$sUw_1W%u+AEA*s8Q4W5Sussc#7I=PTo>TYQk4o2OV*-ZhG?_~obC*|InoQ;v@+f#WPanl$4 zgaHz}QTefiR3jmj&uD2cNMS%aiJE2PN&?OGgFByN3{>(A+<21{5A$-oeEM3znQD+i8Oow?%WO5g_dVs9QzsGhPRuFrEy@_rPjIE+tRVdcg!g~=bp ztmA{hs#lthSj`JJU`KGky{PuOr_}@PagVQQ$Rj}AwN!oMQ3$d``+!kP-~pCIKdS@` zJM#=u-90kmRmOQdsF?4VP#|i?(YZ748oh1CxN$4x9lX-w5s)SV=EwUZbjZeIZv3>8 z?g5yX!pq}6XDM~F}+=2rd6++Qktj!1*T;R+dJwQPIFQGz@) z9w$on@Yt2i0xW4fG%PS0e_Ys??0&<5igHFog8C|IPl)?H=X#m#!!V{jSd~8J(KP>> zDY`K8t~YftR;Su}fJeQlvZWk*9is9L^wTc4H)-3`(OaGPURE^I_idYb;#0n*;N9M!a%z;bqF86 z#+uk|GZKPbq3qGtLnq=2$|j3qf@%z4RcIX5db#Q#n_G7FTA%Vm!#x*+6}3qrjBhmg19RqoczJemQr>DWxURHb6;X$lTqV`51PsGDS@94kuDVmc_ama zW~liI*-cHpDi9)Z@S-DJS%;-VKiL;xDhp#PZY&@sWtZX|dJ!oIwxMas&qcl5*i@|_ zz`VE?wRjDYE<@Xb)i-KzkSK3^O#loYa=IzncAF4~Em|5AaQ7lQ#J?ZnM}~$e=uUuPk9})GElOe( z2h|xV@^V)$ki1nL85KP=L2PBTWZ$5L7L2@V)3^6tD8fVWLel|pITq_^iS*e;f6I+W zo;Lcfx!$A%2o*n4m;tH|hj)v4`bLw{OgdncAF5E1hv_;fk(lCzIUCAbV1T9!cH`JD zGey446xxWSbI4s-0Hha5!g7ys0f!|;3eyqrkp*Fc1~kJl5^Onx#xd!7NNRRyOy|R1 zB9s>qXhO2CG4$qn2)~ME8JS8?JvQ^M58uqa|J2;W6ex6zY=V~9#baEya%ID4-!PcO)M__-()tJ* zj#SqnqDS=6KwN710c+N-UMD`%3-?e_>yd>)AKrfLRm?3V{Z-&4}xWgN!j; z%2tMMRlVNfi^u7wUTZdw^Kx}oTT3jBKo|8q-)Zr7uW7jM)UCAJursU)b;OG7v1Y24 zvsl=)Vi+q4jHLxg3kua03S60pTTAaGboC=dABSBFf?DFI}h!)IVF6<$w zqcbEn;XMV>L5kP0C*@Bz0A!@j?dClwC&aldbQfxS|iz-nHY>Q`5s^ zex63qkrAbk$AGM{;lsE&z%pIHEOny8y`2jgx^i$Z1_i$qzRZJdY}v$l14g5ToEBx? zt5@uF_m(sXqu;If;5;vRX22L{n;?Q754O1U(%$oN*&5;Z+KZ>in7Rzj7^j^2%)2Fl zQ{4-yNoMYS44a9T!~;+x;EVXw>R@A<$uw(6%h`mYS2UD2xiT4CB^ z>qeLR`qc}4*l#*tjJ|k~3jw0??7d>>nKuv#@i^CXYyplh2(%K$!TNZnG`p@e8)uI* z{h6%isc-oh$oK$I)+TZ`Y?1l<)uAdViJ{U2VlI(gyl&ov&ooyR3PB-lWAux z5QlYm0iKg@J&D?pMKgUH!|e7J7-MauauN=$#q7AST!Ctu)TO%SA$i8Lw)Q$2RUY;% z@(L#h8eAi5d8NDH%5X=N;Y!(v+-fkhXTf;3hN8`@q^E0Sv2U(N8Wdlnxl5a4Va@ZA z6jb04j%p2gZQ9LRqqJ{n;1=4wsDnCy6Q-VyRyGfhr6v=1?!v0J;d)ggBIg^=9VlP~ zf}Yn3ELPO9du!MPjgl4edg>JqD&wQkW2zy0CG%cB1M4dV2T(t?RqTy>yl=61uD5ds^d00dzcrk62(6V$9XAWecqZh=I;v#H z8)EmSxkje?c|@!!iy-<-$BUdEO>R9>sdiE;K=o6x$J33(bhd%Mb#1NKYj1N4geFek zZcE(;!lFgq^Ws_YL4I>`y zAEvRx-ng(_Y83FxLT?uL5|9Q?arTV0HYk1_ES^c-ybuRyg$M6;d?cZQ>n8B$1VBD8 z_eb$EFc)dD*wq=7E#32SCLKl!}GCs8c&ha8%k7S4}B=sPe809}f{4kYFn7u(0|Kl!^)TT`Y(P)Ese5 z>hya+0=HG~`QSiFaff%lydg!>u&p_u^Tl25CzWK$x+qT1<&0bgMlbPowS_7;ko8C$ z!#LflWAO7?WK?iaRTZ%Et+J}}**euEFFj<1J4Sn|&##_7Qf@CZ@c*xJrTD3R9tLBnlpFK;GS*IiR z=W15sWPyT>uOEYqky0q3Iy^6NycBxSG-Hf;`vVAl@NiDJ!UYe(9}btpiaAV`N3XZ^ z+5WM|&!X_2M@sFBfPwZNlcYT-wd&9m=C`Ol+h zAzV1Z3e`mGhuXM}OVrC-CR$!{WPAo@u*pCkj=MG1-kfZYT+0I6chy29Uk?(#h_^V= zgho)xR#T(19;9~;UlHr7O)T9D zNv%-?05^~A$6AykXdkwkNv*-eb|PsbEB7p5Ksk|jB4b*1?`!wG^`E@v@)u?xdU7C1KiA@g^L0}QeXKN0U`by?7esXVqrdC>(4&zR7|_# zmU8IV=52szPuC!1OD*g4nn53vY_-XIP6~z>M{i$-7<1O(rH1DdTSkR3$0pd0%ZEA}eW^~J3%0Np+< zhns$!L(q?20dN^Prq^D*dtIcWC!}s!{-WbfiN~_tM>OORRD12|=btJ(%8N>1@CssK~pvSqL$cD`q5_?T4TH74V>uLMaZ37neRtNDc z33kE}6T4I4Epwl|+a#N}_AdQb7Ks)n$@poj%j5=AE$)(Tx9%DaBO)db?$!~3nQjZ< zl2^G_@EB^DY!2KWtmQq@PTh1-DSepFWiK>=fD~_uEtCcsENC1bP@$bqA8?OTI)uMh z;O~jCrntspD%wU1vR(-)0O1S9q3dRw=t&zC*iFfG-VE^N88g%yKjgdn;KpkzIeb-&o+4g z?>Ls0sN+SJ`kcev)YB4DKZ*R()8$J~&pdc^y`D5-)deHJtqi;05$#Hv?Og-hS| zlr)*qBhnar;j_rK0gJG=O#@F{CWX2F@>! zQ7FQx*Vbg5m5!0!Me*v9^n|u5Ib6MywNwN^$D6SQgfMBNYsH2u6?h>%T-jrx2~I@- zXp6OYe&ez4WlqAAmzQJNMHj|Z^6an_wHpkiSMwFRg4J#L(>ifRk0EnXMX}3z^_(Ed z=5FKl!vNfK)XOmSoR~3TBjxycGucDA^J4%g>-M zKb0@gZvYA(V2y&D_iQ?Fb|+yrdaFrRKvUwI)S!N2VeV(@piene71w*17j6%{({@DN zM+OCoSEPZ7Rp+pkQBCHZIO|hp5f)8*j*Hl%3!(LRPS2@5mvaF8yAY`8g43u?;Ncf0r5Mbcs)|I;_WX_vWgt-nNb1L8NTso>8b;hJ&0^dBzmr+ z+JYDl(hzc1OrCbb^26+9k>c9LNAq~&Qu=Pt!QjEZKJj`))7$XWwr~?P*2Qu5h-)q+ z0Tg=4#q$VDqBNLb^knDis4-2M!D<UneYJB9153U0%>AoX($!Q2gR z$lPZWqz2a#{u(;H>)`cFRM_H?tn+ESm(*(L55{ifDZQ`&=oZYBqaw9%7ho{WXa&1` z-Uu zHOr#HHrdM9_~=1vvQd(E_>L6^YC^EiOX62Wl8HWoQ%VnOQRUyIP;|jxT+m7WHVbu^GQjxB=w_^{m^@;It>rs`ryp<)L=>o;+`|d<{{XuQRqyX+GDn zncThRv^+}B?djl45{oNHN2z;wO-S?5Xvg8f%S=V-(K4qBtq@Pom>0X;ixoK{!)t3> zqS}YyK@T2{A9*NbE|lJsk?$xuSm?fVHq#DC;;lhrWqa{qjtj}IG< z-P=+0+w9m)yzq_Xc=o`Kwu*%z&!p?QCy8M_wh8oSH{$qf8f%Gq>FWjvjq1ih(V}|K z=9L!Kzz(X+l>y!J_ECGskbNvH*uiSG?r++4Lr@K9F{VIy!_)wKb;`{eGj`S+DIHzm zFvWTrRS-!H5|_ON5>OTq0z>bJK_yg9j5D3|ZZY}2;Vzt_7elMn?>0fSkBiI^AM^>0 zG$?v?tYY)I3Mi5BFt&o*6Eam=>)cy@WG~+%O%a1z%6BxOIMb(^W?34um}dEIP|>1p z_c4c%GkAl%SMZIfe<2FXS+Jn;I0~SrEdA9WbuN&UN|&xGthJD`LDTwM4FNpeCfNf< zan*xUYk3wrYWc2E@L6ykCGIE%9^G!}J>4CZ#KNX^B(keJJL8;Hmq6@?VK05_K`>YI z>7Z5zmNuElgrW^Mr#GtXiZ7zqpa?Yx_e+>c&DO$EHppD90MmbW(M5?2HCTh0XOj)D z$Mg{iaJGr@17=gMF#zS`P#>7XJ)GQP;X4y|^>-2>ni%rJ2{L@n#ih4>*}&8L4XTEm z;pMr?yMjs+&Pu)wp~b*4TuPTz@sxVDfFkv9!EgXqOUx*y)paKcEv)Pw+V;E&UzJ-4 z3o5;P`(y_dom)~Kd0NU%yI!h|grP2=V4E7stm1ptk5g%-yq*^?FtggzAYDqkdN&>Xe3*ca!wz(=2a+)O zE_pIkwnW6OL1o@}H4%mw639C`Z@p0=R*3<& zV4{07Zk(w?E*#^lJ4{4JEVc~#G)m0L7C7$GlM4EwyrxVMFd!qldQo5zJE%L+sq!<4 zH!_rTir7=pANW3h5Tm^d$BAJjou!1~JDTbp{+{l3&GPmmB$TO_;nF@Vj;L zu888@t#y2xWd!cP%rQOz+Aew>EaLAJ?|Mqsd3>4QWLHn?JGZy>y^ErK@1k_Ap(PNu z#%!y6J=Z?ijZf#{WXC*(G-MuPjM&U3cY+rpy=jFu^o%i3OAOW@U1YQ8uKt&OXywYJQ0IES7IpB%c7<-8p58UHajRH(ZpDtSoGK zHdPsfBYT%qv?&#=+jLoWaj;Cfkd~ z--!yO@9S(2rp{*scy4N#GZ5p5fQ6ow**N<83(VJe zLgxmuUO+Zttjje;uM@7w_bI+QGpdTn<>a>T9LS^t67YSNdcj%O!CYv8>9NaOo#d{Y z#yoJFGSvfIpk=;rGGq@$ZW=s%RtylGDd(3b$#*aw%snGcoho(zIIP>JAnPgdG_cZ7>8W4PLQ1D)aJ=ZjQ{9cJ#8=tY7VA8-BfT_rS5V>&ZMkFm z1auaCp9dDVs~|nmSdUv3p-vlZA}$a^d3CcZtbMYVd-Fi~@wC4ss5gxLhF`!NhVo(p zm8#fIhk?AT(rpFh2^qzAsJn(?nJ9hR zlL{}nGmR5x`;nERcgfA{jwQ<{q$FREQrXn&9XHdhjoAVR3MF(QtI2$AlaVt7{!8}U zRVFqHQdIZMgJX-mLJ4wp^`XK+)j^r1n=*&=0(#^Es_2x^x%8A+x}$^KxUnS5>=>jE zjIc*VO;77i42Me$YXs)VF?{(kDPV~kY|bd~kd3Vcv!5)8+QvrZ@i@I)bG^cGeE(5u zb`?@aCVF8vs+(lE;2E4*`K z#6o$ajBmIbVq{ph8moxdjEg0P&+I^F_NAGj?K_WxYIBX`Ef=72M-M2%cu{L-&^Hxl zO*g9#=0#@=2}C%-3iC{at~AlZEwTuHT@~gW30(Q|9$C&2*Sn;1WAO&@Scp`Of!n(4 zI_7z=cgRyX4q|C9^Nlgf56`Ei?#R*>!kl|>Zl(>o@wO>%C75lOdK(^z3#ADX_d8+p z7~FOD$LEom8;_wdDV}*PtVH@NrN+}7@Oc1xQTmeLbh=*?d+Mt7CMWFTMa`R$5j0m&2B~OMMyxNRxA&q@C_mFiZW1NZQVqVsAUEz_*5~sZr zH3(aJrvg_sItS}BrD-Xu+Y81cqvTEMRO^R`i}(5+ft1q-oIz8bLB!PDn9R9)L?tCq zlKF$>+fHkE8<8V?!9zGrPZ#qB7ukkR0)0%t1KiBP=FUFvm_^Q>le%X*br zEf=_hkXSpoS`^JeZh_ZGlWHzHMW#`1NN9QtvCjlA)tn9rYOJ^-TsxIM5+DX@<524% zR2EDewuh`n+$I7cJuX_{S^d(xMvlwu#QEvmL)B`{=eQR1Xd8=jWw|eLd^qZ$r0|nc zrY}knrWB&6r?b);jB=T4#Stwjw$PUY7OQenJ0a3cA%ho#DH7_%;cgjbw|(i`NM)fcE`0mQY0-ST5@VlDJr`VdDV5_aih15{Zm0%5 z6D&Pt{Dgv;l;>4Bl_>W)#W7bz`KncbwHq?ln4Ep@r2=1=2D8i>bi}Jk12+UrW0W&l z5%tr%5QSEVIRIO4l^4!!ikL{*TjG7xunu;#8Wa&Taww;K@)w1?UvB8gTMyfy@kM;$mn$96IW~;$N*4js?n}$N+sJA16Cb@;%ZT5{obkP z(^pTMYjlt9oau6bU>iFYqY?2X!aGokO|t`oml81r%@k%CI__i<71k0Gfy54|aG@B1 zx$l{;CK=gFPvOpIxzW0FjPqLQs31DFP#62;oof-)sCLS`Z4fV?^N0kWTH0v3M|E>t z<-mCerHNHNuVgV$7b2R7;h_p3wY}uHeD4v=1F&*S+>wLOG84&*N4+D8qFg+yukdob zgdDPs7Iz?)F#K@^)s=#Yv2cs^a0{)=M!y3+%+$P5=QGzNxCpD)V9o$!fj#6SD)*3C zn%Li53lGy8a{yRG`?W47pGin3RAty6LcL>qGmJ(&(+kLy?kB)1XKKm856D9=LyEP0^3b!c^E$y!?kjDDayXE73j%m z(diG+Y~{Tt+CG{0k~P zAbDuz8#)N`oRi-3AZ0RS0DhQqLtuakd^YH>cM$C5b|IFe zlqTa%%}G*WWi;#-G}XSxfX{D*H9#B7A#b9GUUeH|>q~^=IzDo(a+qj2><2px5f*}j zJ4DKE^-kVFK;Ix2Gbw}~#Sn>+-1_{c0h8aY`q2uoyJ#JY;`#tlbX>>tV8_10jG#A$8}A zt||~`TboGKeV)c%;4kh8urNoJTyg9Uw2zrf+MDqx0xU5=xP08JSGnu&#$%+k1rB7Q zw_Ooxng^b8v=cDi#$$1^KDH{sVi2-nN(3S$h$bmxOn7)(lu^#&2^bU6 zo~5bNCfh`mSdbsjvcrrdd{EX|xg=sdb}LdW1x1FtvcxyhRY@DY3iv!g&b zuPnmGN(E=1&fwE^f=3SgN*R^V6+52r4)FQpQILxjZ370en<}a8hQUHOPQ5ZswxCit zBVfLHkrXG%*7U0OCD*ILb>!ouoy6WMig+=BkDz;ybfAUjfqPIj`@m21?mmP0;cnpZ977Rs8g3;UD9<$P$`?s)e|2glLLa`3WF{jD{mHWDwT}u%}318 zl$ntv+fx87Y+3z)*f5={+{w$8Ez0}R_5wKFf~h_<_K2p0y%e)%ZV(nu=Ma3Lk0a7J zIVfszR~&S#msbY{!rpBFh=rw^@kwU~z5uYK-g>G+^K{JrBUN3GUY@<%B@uh}3ba?i z=v9G@01Lx}q|w8eTym2hk$vgA$pRHVIiLjNjn-I&S!&d9)3pT<-$ovF_M3 z&x@5F3%YpdSGrmBAgP{Y8F49LNrCGF=Inr8?I{Yw)T@Ih4nnV~CjsHX={{ecohJ|d$xML`g-Bh2h(Dvq@CECZ4wqbSy=S2$ zK7hT8I8QVBor?CkRX)-3995HJE=aFO`#ep|BfRylI+ndqeD;JD;_*Ix z5lM>sC|POf0Z?E!A7+j~P6sH|UbrJZ*z93~mkq6tm)Ofx0V?86Z?U`zxgG_JKH)ml z+&$ElM%Ed^5)dl_JV8|C+zg|raDPMC)56dE8XF5~Q#wUMbHwm(gF#XdZ-Tz1~GaS>F1nb;uB%XRMS$k=Nr+E*TrCk)qxsR-y&^LQb~ zNH24ov>IbFO52)XfU+j(y46c-_*UW75g-{Kg99$i?tjfr2 zoHQF@<$*xDC=b}cp8$3rcRok0dphT z=BlIoNLeY9Cz1xBlNP1lyEDV$Op#@%9v&$~NbfDvMTNNugxC%7yF=^&Jj?I~1Q=rC zQ(7iorj6TIl{O-XyUX480Es5GZrdwpA0fs_VHYME*)(*$xRR9)_LO{``NF6`5|N@L zA)`g#9sBw)zW|YyGA$=&dk_^WfIZM@(g>$RltgCF6E|h4RTKhTv!(@eH|H7l3$bHH zfvop*4DS^H9tsY?DM5f^AzoAV>I4d3bv*=pR^6Vvqyy+AhS``RcAO#4y;zaUeP&Ll zpmwi|8GA^T1ufaYPNcMtjnVs&0$vipyJwXOwyg*XUi8L-`ewEco)*U{V1 z2b)&vd7BC4WI{ld)WXorg92f}*-DCWA_ah1m(i-B4UcRFci7tN_0UmVW*{vY@?a}2 z4YZvXy{n!vZX#_QMi!qLPRYcJi*bocs%W6a*^g$GP}#p1rj9PoSkx?p+R#=HDR5(Qjr z`I*DBVWFFYTIoX8F~2%i?oe!c%Z1@W&(86_^d%a-m*qo7v{?Xd+fX=@z5#XYVJK? zU+J(x=A!2m_ypf_pt6=Omg319-+3z|KzbWK?XRNIhzzCfcn~PoeEHGr!*F2N*Qo^d zdM0y1JruhL%)9MBR;>*}b-FywxNQ2J?!5(zPQT^Jh%}os4GYpyeYX>M@*q&)jomC0 z5SPBCU1`gXSMZ*ZTsG<1BA;NOg_S_c+|x7cQ6-#kY8!}g7HWLSX4}SM%Sv8keHW;; zAwm^f-3)hhmNT$Ul>yR^A3%3R_MJF%9*Do*Rq0B8%4MlDb}+Z54-XJ^{qZY!2#i2n zRt59IO`4AxjrKWN^e*xB%B#SVn+v>fF-aW4eG!B2o;6lEyxBE-1x1fRrIx}eq6Vp6 zI$W_zFRu+|U$_YSi&T~Evr4uKkNger=A2B$$u5Vix$@pGy`|Z(St!yU|wXHQ}-eF}#k-F#t} za%wm3VI@)2gHghSniKZ=Ar;9gFb$Xz(*iZp6NsT5L9vQ?I?s5NrotyAh6`@T(n0B} z{)4rfHWOs`Twe6#x|(hIT_OUcz>Cnjh{%n%vr1-;(<}jocH|;71d~BX(hH92UXBu& zJ7?ON2Sab2QVJFaJB!$vnf$PPQW)A3{F$X2Ke%-9d{G+VQ`~n0`YLR3X&3g0Vmpz! zQC0lHIRXfTAH#}ND>cXEG|ueigkA*45kV&dn4t>Hy`70Xex5p#7)2Gl*3VC(S($|s zN)IuRsg#ihK%8*^pG7j-&?(lLbQeJqHub%1zp}Fpcwk6YlM9A8gB(Wdr98H|Wc><; zRB`f*#5cy&@v&2Z3^4}{g0BpV@T}(aqsRRS)6bb;`_}QjY_Qkqsel$~`xpSWdKy=D zjXAE}Uh}-%EEg2x@OhQ9NH`cCm!gkZ)nw!8dyt#}q|pifz!01aGig|60nR)7jp(qh zW*To=EDk2!n=B51QCz4tW$`3c6@UjEsnpyI5e|c|a|jMmjS-Tghl8I%->RRT=d2Ji zk~=vh>*AC@aCEM~zC3k$8&+`dNsB^o3BJ6G854Y~5he*(Lup8NeU<15hrv@6uOh7* zhaOD4%=Po+v?8<6EHhzj0$Su4;~7qp_uQWK-trO_(6+3f_KlhPOQaHk=hwrryCPM4 zk|B}C4RfR3M_1IN2S7^&gh6I~4UCRY+-4t?kZXEAI3D&i97ffN$UJFM4w%O#n#Jqm zaPSSQf5OT%p#>G0L+Oq-YXdfTZUC;JHQp#la<-9ZT$+@#s^_c&+w2Z|3J+koNLQ#E z@<5?`uvS-9ix~VZ$h^96WFvYG{TMkhRL-A3*)9#=!+Yj4g71_-oN741M~;X}c4KM) zRpb@3!kbYz&JvQ>IveR(W0XGIn}EyZuf2laX@S=kKYP-4zUDGL)q_cXX3M&*-WP-muY?Pq^^Ntqf+vA@jGYRSqAn0?hjP4>Hk*RYQ*%()krKxiLNdU`su5ElkH?F z^0w2K(yBxXz%Ur*)ZC=``2s^c99Jk3)d6nu*wTS~Z)85o+}! zYC-O*K7J`e_)`|tkEGc~j9!$eZvYObgAoG&37AjBcw>28+3~77*X?m*?x=ZZhvc0CDQ6pIwn7no2lz6(4HfbD2JkY*+ ztqtw)FieTCrC#*x8J*Riqw8Y~O?y!>{o(ao&2A8eAw*4si#-1i2K7xWxls8EjO=;chv+vQGLm8u2w zEAOOtH`pXZPak#Dd-sTywJQOcmo*6As1n&TaYe_h+M8;|b~HJBF7K1purFFc1YsG$ zDdnk43D|)mho@!jla)!0Dm&M;l2}i?chm_mSE*vu)I)W%UM5$B^Ps``5E;GHQfYw8 zv9oozDYh7E0G^kj+H;%avGHbx@Ya@BWiQ)g3I$E`OiM&X#=&M*PyCJY<9-(}s3~H@ z-0H15;lB1IQD@YOuu^+(f^4$&6(7;0KW+mAw1oK&*OxT6V8wZZ zfH9PJ;)Amy>NBl7G(W1eWpc2!eG|iGqnwOUP3`5G{rVi$k=*bR#XQT^ker7N3o2M{ z@H~y?;Zg*xs_xp=W`K3ys^9cOz%beM<^~;T>NlQ%^%jky`izLVLHsS-Vw1{~MT&ZK zcu{#{3->y1)@MX!8fU`HU4TMbi=zcR6Kjw|2TzjNd}44F%^^6AACrpSYDh8d2A)Sz zyyav*<=RM00269_lMf6VVNgkr1sw*YpI6pdVY^v+HV(!$z9u>3P64Jdg_(TfO9?SN z@sf~ql-3?JPDTKwv; zLyHm)jGsaDs0Aog>G4AZlAaB!+B@vW9cArP`LHOH*fYsW0A4)bD;68R1z>Cr%m>Ft zEv>gWNyGhkrCKQkU^T+cV7!rDi*>&n^_Zd#rJ;lORsgW5ti*P8)lx*Cmy}OqUNSdF zNbl>FC>cjb425SE>~#iuhWX^86|_y7@~Hvt+vW@@BGkv=RU?k7oOR~!^OU1m5L)6RSerR8>SWuzB!UOC2zMar}v`tHi6GG^cbf>Ulev7 zJ}=^;XRC%Dg3q83-wzjOe$s(4HbPwbw6#T}G;=IzzHmj5FI>GGH!5cq$PQ&f8!+NM zAn91-sh8SAc(HLUf%DMNq$+#*fx) zd*ehMhR<58#*^ak0rKN3h{UwzeyD!`@p_eF&XN|P!JIjBuBCAXTU_sz=CD^2rW?VF z@gbtu6~(>0y&eo9At$I$APBB=-e>Do^9QQ8XuP6S7S%deAT!8dJvLA-Dn^ zVkgbT^j?Cg%j;O~o<2mLZJn+?%}i{qz{Xh6-7-5{3&-d63g{M~Jf=Hb$u41EQ5(ry zYoZP3T% zYP&Adkm-yY1C2Ez5H##HEk3L#hI*nlw1~Lxc6APb@RdZB1U;y|)tc)?acktZ3|Yn` zXdHg81%XK#Jn=OR$V2EPd+VCijf*cQ*&dk6U~Dk?4kQ{2u5M(NL(S}Ao!*wtY^nh%D^r@mTUsO+huI}?&Qoc7 z8xOm!)Yv)Iq@ZeO9H{LwU$v1@XlUUZkmg*1dt9s;xiYLa0?48Z38VO=TJ(|HRE>*V zq}27ojQFv(o@b!0VG?^p3tSqf;=v#qEE*Zq$s`6)9$?#Bk9b9yw-_D+$S&3wu4vN0 zf*uTOcmsAZ3M;;O&nS$=kHbj0^mV}sP+$!?y~n0jwlH3s*puLr{Ma2WT|iu~ zkFOZsz4tElHe1|6oATsYJOWbh_d@teRIS-)qAR@)fpaT>r80ff>nd8#*Pc)>j8aQ% z`o@!E4ntaJ*w~lR6kz%vuu=x00FL3Woth34t70oN^3fux>RSq{-tbU0Y|GH#hg+B( zi5w^=f>Dx?2;#*fM5RoI1=(a<;Yu69Op1#t5jNXK82P|>{1JKj{CK$yN!X|2+J3}S z#Dcp|I4;j$VzEYV-UoRMiLQj4CYh33cYs__GienW?W5!glLC7OBWe2Rl12?*hdFj9#KuhsCeljhBfT}Wo> zeH?*0av;`@B1m&emUAaZ?1**PmZZXu)>rHRz|WY;_=SVu1L4Z@Yr^G+S`Rr(YH+4_ z6s}@)EVnM?Zc=f$MwYalib5-=-}xbSK7Z2*qO(*=`GUx@Dn!rXF(nR6ax#&R$oL66 z`FNF7iEBrBrGoe!Mfy*DxdsWb~g zvZvZl*#gbp8_JT)^ut)6-gpga0s7z$5MMJTp8_=9I=&oJoTKF?KV7#6&S&t}2NdFo zs(a3099BJX0)MICgl{rGfhG6?HmW2KOAeypVJ~-H2CZy8?)9|OaZ1<6ECOskyRwB{ z{Yo_(72e~rTX|CpY%QuzJNB0Nq@SqkWGTcPma`$KiHe#~QQ@{2FFJ@{6U%#TMVY{= zA=|_J0`n|Sx|$NvEGvDCy!GvacTlkY;B{VLk4Q}g>H>u=V8Eyi^Z3jnl$HU%=j`#g zaYDF>c9?blBUZbrgKvkxyY?V&T&tVD99o?@& zF+*et$d*;3JCzD(8&BDBq`5m3OfRJ;o0zRQSg6+FK^B$9RMzx+tMCYjmiHkXuwJJVg<3%+Wx`G{DzeegzM8hGwm}YJ2D=rFmmLO{sLU zWS}@Y&s>n5y$i#D1oJdftiAL)1ysp`dneVzjpl?}o!%BdWW?JGV!Xv7-hp?Irc4m< zk;dD+(t-DK2hB0w5i}QIH@8xTs8~Isk}NesEO89F0N=MSUp*j5KjQ}p^>{&SnGolg zm1YY^VPdgi;Wr?btkR;3IK3u;&4WbD(qr-kjxhPOssr4*afH9U#z$2Y z&XxgKd~$pn_f4#S5ld+AfDpag2!uBvFil?P)J~`&rV`%5n5--Mp|yi&QM^a0;kgv% z4*4D%ynNyJn)`Ykh7`B9&0PWYBJ18}R<76!Kc_AYvRQ576G^_fP?qAh6VOsNX*y4@ zY3-EgCs8}zE0y9N4~%kMNIGq1^;8>HC_@LAf;v^M#M0%eqsQOTK*v52pJfovCAt}+ z_z&66=zEg0W0+D+Pzlf1LHPkyV~R-cS!98FMZ>8Zxizx)0cEmvSuAvQE1jqs@zAT# zcpYrMsgv76&-dw%=c^uZm^t6$C>{g{9|DpGgO2D)sLq~n)+%q9A_sANUy$5r?azX^xgvxdX~KQ#y1OA5}Fo6 z>?*Ow>@Pt)j z8ZtrPt+un63Kt$W$>4&@Q>K^VPT1H8>aNh}@SbgsS%l4K0=ek}T3C6Y>r4AahV(#P z$+N>@%NfV&!M<*=on(}8SQO@>G~R6itzF74^v)*stT|GdsoF;-(B1}d4+f;)8>$Tq zxaaLF;=r0gU@q9IeSu23datwRg=bqBMW|xxi0&YAhxE7+#@j{o&XHH%;B|6|ZS)`w zXKj>y41AHS;jXs&oyZ7!mA_Ses|r1n1WhgPsLxmh5j}=scBU%e>7^Yg;ZVyRtc(c) zSfB1D5@Y%sATSd)+e&RUgfiaM(o|?_@3eVa-qSVHEV%=|^A>i6-x8}xj5PK^sG_Vo zF1IJ@=1uNl+-xz{#unL-D4b{bhOy)kbnWZZ*LEo<5Hj)%)!wqlcAK1q`3jiKJ(zR0 zlsC{1nb}H#yjX)_D7Id{i`2Zx(LND;qLtfG1t`6Hrzu#ejlJM{Tj5Yy(f8sA)fag0 zt?^Pc`#eWWmyvt8a4KH!n$f^Dmp#GYF3M+{?E-URt0A?lnZ2w0%ru6Dl7!9s{$n<- zo?U?To}~B7=$U0wSsPKu>3gC@7NOVGNW2g2;Kf2h#SgrmnASY^kfMp_%%S(HK__$x z1fx;s$!=Z|mmO9Ly^O-eHBeXvMYI0(G9Bb zKwOi;V12a@;~_pg19^^aY9s|un;YROK?vvo*aC!FVCFL;Ta~-0`7pLN9+39fk4zn9kWOH9bu6lDzbrS4O2RA>VP&rx( zV{!r)SI*P+V@OP4W`0tVX6Qcq_}=3?OMRA*Fvo2H-5N^B&pW4(xW*nQ$mJE;RE#N) zLHav#7IU6>r(;WeN7+j`kb0f{unT|*ICcS(nwMYkVxwfQNNU;&7cM4TwdWPIBX%Gj zxpKQ6!hn(TP_WT}E3vcC<1k!)Emg2Naxa#7-rE`&7k&_hgy*FYO~PR+F@*l+lsdw8 zGaR%fx#ixY0N{Bw?=EkQUEYhaGBnP4ZA>ZPL8S1|eUoU+bwS%*aWmT1NGHT_4=m43 zHu$1MMGk;O$YfgINd^YNZ37apzEWY3?ST}X@ic$G{+-zoQCrv6y5YM9D{==tap<}Y z7@=ez4966F7OwAUchGXCG4;u4N)!QZEYPT`m=YPINVn`Tdp(+vt;w`OyB+y6m3inQle z7!8*t;Bye^y?5}|Nu#H`4jK&l_QtP=L$P*3s+$2oC&vMZ=w*wNq_5F~FeEcO6*q$? zNAzf|JBibMG(l&yM5a#=7x|rtiK4$c;PFn3DQAr*y^ONs$A?`k@VdoKAq~@6>5`?T z8D9Ccup3KL&<6U$)M?fCwDJj*FM?~MRKFJqWI*mE-VRw()O%;5*Ycj?*xWF1kXY)z z^TIK^Tv)1y_^3%nBYM=?E)Sv9URODbgEZP8VyTUX;kLbAo9XZ<$c8J9r|LLd^8kb& zDKnaDg~k%)nL>QRd}{8aKA=8(FJsnA@<9R&aIoVTPFn-xOPDpv{DfBN z3tH4ST5m<+o!LZ^J$W|F&bY7YnU4%eHw*hD(gh%p@uptq)hy|YDLO0l3&hdj(R*

nJLYnt<$PQi86UnxvK+ceSbB#mC5$ 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 diff --git a/vendor/golang.org/x/crypto/sha3/xor.go b/vendor/golang.org/x/crypto/sha3/xor.go deleted file mode 100644 index 46a0d63..0000000 --- a/vendor/golang.org/x/crypto/sha3/xor.go +++ /dev/null @@ -1,16 +0,0 @@ -// 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. - -// +build !amd64,!386,!ppc64le appengine - -package sha3 - -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 deleted file mode 100644 index fd35f02..0000000 --- a/vendor/golang.org/x/crypto/sha3/xor_generic.go +++ /dev/null @@ -1,28 +0,0 @@ -// 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 ulint64s 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 deleted file mode 100644 index 929a486..0000000 --- a/vendor/golang.org/x/crypto/sha3/xor_unaligned.go +++ /dev/null @@ -1,58 +0,0 @@ -// 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. - -// +build amd64 386 ppc64le -// +build !appengine - -package sha3 - -import "unsafe" - -func xorInUnaligned(d *state, buf []byte) { - bw := (*[maxRate / 8]uint64)(unsafe.Pointer(&buf[0])) - n := len(buf) - 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 deleted file mode 100644 index ecfd7c5..0000000 --- a/vendor/golang.org/x/crypto/ssh/agent/client.go +++ /dev/null @@ -1,659 +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. - -// 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]: http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/PROTOCOL.agent?rev=HEAD -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" -) - -// 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) -} - -// AddedKey describes an SSH key to be added to an Agent. -type AddedKey struct { - // PrivateKey must be a *rsa.PrivateKey, *dsa.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 -} - -// 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 -) - -// 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"` -} - -// 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) Agent { - 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) { - 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(err) - } - - buf := make([]byte, respSize) - if _, err = io.ReadFull(c.conn, buf); err != nil { - return nil, clientErr(err) - } - reply, err = unmarshal(buf) - if err != nil { - return nil, clientErr(err) - } - return reply, err -} - -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) { - req := ssh.Marshal(signRequestAgentMsg{ - KeyBlob: key.Marshal(), - Data: data, - }) - - 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, - }) - 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, agentConstrainLifetime) - - var secsBytes [4]byte - binary.BigEndian.PutUint32(secsBytes[:], secs) - constraints = append(constraints, secsBytes[:]...) - } - - if key.ConfirmBeforeUse { - constraints = append(constraints, agentConstrainConfirm) - } - - if cert := key.Certificate; cert == nil { - return c.insertKey(key.PrivateKey, key.Comment, constraints) - } else { - 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, - }) - 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) -} diff --git a/vendor/golang.org/x/crypto/ssh/agent/client_test.go b/vendor/golang.org/x/crypto/ssh/agent/client_test.go deleted file mode 100644 index 230351f..0000000 --- a/vendor/golang.org/x/crypto/ssh/agent/client_test.go +++ /dev/null @@ -1,327 +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. - -package agent - -import ( - "bytes" - "crypto/rand" - "errors" - "net" - "os" - "os/exec" - "path/filepath" - "strconv" - "testing" - "time" - - "golang.org/x/crypto/ssh" -) - -// startAgent executes ssh-agent, and returns a Agent interface to it. -func startAgent(t *testing.T) (client Agent, socket string, cleanup func()) { - if testing.Short() { - // ssh-agent is not always available, and the key - // types supported vary by platform. - t.Skip("skipping test due to -short") - } - - bin, err := exec.LookPath("ssh-agent") - if err != nil { - t.Skip("could not find ssh-agent") - } - - cmd := exec.Command(bin, "-s") - out, err := cmd.Output() - if err != nil { - t.Fatalf("cmd.Output: %v", err) - } - - /* Output looks like: - - SSH_AUTH_SOCK=/tmp/ssh-P65gpcqArqvH/agent.15541; export SSH_AUTH_SOCK; - SSH_AGENT_PID=15542; export SSH_AGENT_PID; - echo Agent pid 15542; - */ - fields := bytes.Split(out, []byte(";")) - line := bytes.SplitN(fields[0], []byte("="), 2) - line[0] = bytes.TrimLeft(line[0], "\n") - if string(line[0]) != "SSH_AUTH_SOCK" { - t.Fatalf("could not find key SSH_AUTH_SOCK in %q", fields[0]) - } - socket = string(line[1]) - - line = bytes.SplitN(fields[2], []byte("="), 2) - line[0] = bytes.TrimLeft(line[0], "\n") - if string(line[0]) != "SSH_AGENT_PID" { - t.Fatalf("could not find key SSH_AGENT_PID in %q", fields[2]) - } - pidStr := line[1] - pid, err := strconv.Atoi(string(pidStr)) - if err != nil { - t.Fatalf("Atoi(%q): %v", pidStr, err) - } - - conn, err := net.Dial("unix", string(socket)) - if err != nil { - t.Fatalf("net.Dial: %v", err) - } - - ac := NewClient(conn) - return ac, socket, func() { - proc, _ := os.FindProcess(pid) - if proc != nil { - proc.Kill() - } - conn.Close() - os.RemoveAll(filepath.Dir(socket)) - } -} - -func testAgent(t *testing.T, key interface{}, cert *ssh.Certificate, lifetimeSecs uint32) { - agent, _, cleanup := startAgent(t) - defer cleanup() - - testAgentInterface(t, agent, key, cert, lifetimeSecs) -} - -func testAgentInterface(t *testing.T, agent Agent, key interface{}, cert *ssh.Certificate, lifetimeSecs uint32) { - signer, err := ssh.NewSignerFromKey(key) - if err != nil { - t.Fatalf("NewSignerFromKey(%T): %v", key, err) - } - // The agent should start up empty. - if keys, err := agent.List(); err != nil { - t.Fatalf("RequestIdentities: %v", err) - } else if len(keys) > 0 { - t.Fatalf("got %d keys, want 0: %v", len(keys), keys) - } - - // Attempt to insert the key, with certificate if specified. - var pubKey ssh.PublicKey - if cert != nil { - err = agent.Add(AddedKey{ - PrivateKey: key, - Certificate: cert, - Comment: "comment", - LifetimeSecs: lifetimeSecs, - }) - pubKey = cert - } else { - err = agent.Add(AddedKey{PrivateKey: key, Comment: "comment", LifetimeSecs: lifetimeSecs}) - pubKey = signer.PublicKey() - } - if err != nil { - t.Fatalf("insert(%T): %v", key, err) - } - - // Did the key get inserted successfully? - if keys, err := agent.List(); err != nil { - t.Fatalf("List: %v", err) - } else if len(keys) != 1 { - t.Fatalf("got %v, want 1 key", keys) - } else if keys[0].Comment != "comment" { - t.Fatalf("key comment: got %v, want %v", keys[0].Comment, "comment") - } else if !bytes.Equal(keys[0].Blob, pubKey.Marshal()) { - t.Fatalf("key mismatch") - } - - // Can the agent make a valid signature? - data := []byte("hello") - sig, err := agent.Sign(pubKey, data) - if err != nil { - t.Fatalf("Sign(%s): %v", pubKey.Type(), err) - } - - if err := pubKey.Verify(data, sig); err != nil { - t.Fatalf("Verify(%s): %v", pubKey.Type(), err) - } -} - -func TestAgent(t *testing.T) { - for _, keyType := range []string{"rsa", "dsa", "ecdsa", "ed25519"} { - testAgent(t, testPrivateKeys[keyType], nil, 0) - } -} - -func TestCert(t *testing.T) { - cert := &ssh.Certificate{ - Key: testPublicKeys["rsa"], - ValidBefore: ssh.CertTimeInfinity, - CertType: ssh.UserCert, - } - cert.SignCert(rand.Reader, testSigners["ecdsa"]) - - testAgent(t, testPrivateKeys["rsa"], cert, 0) -} - -func TestConstraints(t *testing.T) { - testAgent(t, testPrivateKeys["rsa"], nil, 3600 /* lifetime in seconds */) -} - -// netPipe is analogous to net.Pipe, but it uses a real net.Conn, and -// therefore is buffered (net.Pipe deadlocks if both sides start with -// a write.) -func netPipe() (net.Conn, net.Conn, error) { - listener, err := net.Listen("tcp", "127.0.0.1:0") - if err != nil { - return nil, nil, err - } - defer listener.Close() - c1, err := net.Dial("tcp", listener.Addr().String()) - if err != nil { - return nil, nil, err - } - - c2, err := listener.Accept() - if err != nil { - c1.Close() - return nil, nil, err - } - - return c1, c2, nil -} - -func TestAuth(t *testing.T) { - a, b, err := netPipe() - if err != nil { - t.Fatalf("netPipe: %v", err) - } - - defer a.Close() - defer b.Close() - - agent, _, cleanup := startAgent(t) - defer cleanup() - - if err := agent.Add(AddedKey{PrivateKey: testPrivateKeys["rsa"], Comment: "comment"}); err != nil { - t.Errorf("Add: %v", err) - } - - serverConf := ssh.ServerConfig{} - serverConf.AddHostKey(testSigners["rsa"]) - serverConf.PublicKeyCallback = func(c ssh.ConnMetadata, key ssh.PublicKey) (*ssh.Permissions, error) { - if bytes.Equal(key.Marshal(), testPublicKeys["rsa"].Marshal()) { - return nil, nil - } - - return nil, errors.New("pubkey rejected") - } - - go func() { - conn, _, _, err := ssh.NewServerConn(a, &serverConf) - if err != nil { - t.Fatalf("Server: %v", err) - } - conn.Close() - }() - - conf := ssh.ClientConfig{} - conf.Auth = append(conf.Auth, ssh.PublicKeysCallback(agent.Signers)) - conn, _, _, err := ssh.NewClientConn(b, "", &conf) - if err != nil { - t.Fatalf("NewClientConn: %v", err) - } - conn.Close() -} - -func TestLockClient(t *testing.T) { - agent, _, cleanup := startAgent(t) - defer cleanup() - testLockAgent(agent, t) -} - -func testLockAgent(agent Agent, t *testing.T) { - if err := agent.Add(AddedKey{PrivateKey: testPrivateKeys["rsa"], Comment: "comment 1"}); err != nil { - t.Errorf("Add: %v", err) - } - if err := agent.Add(AddedKey{PrivateKey: testPrivateKeys["dsa"], Comment: "comment dsa"}); err != nil { - t.Errorf("Add: %v", err) - } - if keys, err := agent.List(); err != nil { - t.Errorf("List: %v", err) - } else if len(keys) != 2 { - t.Errorf("Want 2 keys, got %v", keys) - } - - passphrase := []byte("secret") - if err := agent.Lock(passphrase); err != nil { - t.Errorf("Lock: %v", err) - } - - if keys, err := agent.List(); err != nil { - t.Errorf("List: %v", err) - } else if len(keys) != 0 { - t.Errorf("Want 0 keys, got %v", keys) - } - - signer, _ := ssh.NewSignerFromKey(testPrivateKeys["rsa"]) - if _, err := agent.Sign(signer.PublicKey(), []byte("hello")); err == nil { - t.Fatalf("Sign did not fail") - } - - if err := agent.Remove(signer.PublicKey()); err == nil { - t.Fatalf("Remove did not fail") - } - - if err := agent.RemoveAll(); err == nil { - t.Fatalf("RemoveAll did not fail") - } - - if err := agent.Unlock(nil); err == nil { - t.Errorf("Unlock with wrong passphrase succeeded") - } - if err := agent.Unlock(passphrase); err != nil { - t.Errorf("Unlock: %v", err) - } - - if err := agent.Remove(signer.PublicKey()); err != nil { - t.Fatalf("Remove: %v", err) - } - - if keys, err := agent.List(); err != nil { - t.Errorf("List: %v", err) - } else if len(keys) != 1 { - t.Errorf("Want 1 keys, got %v", keys) - } -} - -func TestAgentLifetime(t *testing.T) { - agent, _, cleanup := startAgent(t) - defer cleanup() - - for _, keyType := range []string{"rsa", "dsa", "ecdsa"} { - // Add private keys to the agent. - err := agent.Add(AddedKey{ - PrivateKey: testPrivateKeys[keyType], - Comment: "comment", - LifetimeSecs: 1, - }) - if err != nil { - t.Fatalf("add: %v", err) - } - // Add certs to the agent. - cert := &ssh.Certificate{ - Key: testPublicKeys[keyType], - ValidBefore: ssh.CertTimeInfinity, - CertType: ssh.UserCert, - } - cert.SignCert(rand.Reader, testSigners[keyType]) - err = agent.Add(AddedKey{ - PrivateKey: testPrivateKeys[keyType], - Certificate: cert, - Comment: "comment", - LifetimeSecs: 1, - }) - if err != nil { - t.Fatalf("add: %v", err) - } - } - time.Sleep(1100 * time.Millisecond) - if keys, err := agent.List(); err != nil { - t.Errorf("List: %v", err) - } else if len(keys) != 0 { - t.Errorf("Want 0 keys, got %v", len(keys)) - } -} diff --git a/vendor/golang.org/x/crypto/ssh/agent/example_test.go b/vendor/golang.org/x/crypto/ssh/agent/example_test.go deleted file mode 100644 index c1130f7..0000000 --- a/vendor/golang.org/x/crypto/ssh/agent/example_test.go +++ /dev/null @@ -1,40 +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 agent_test - -import ( - "log" - "os" - "net" - - "golang.org/x/crypto/ssh" - "golang.org/x/crypto/ssh/agent" -) - -func ExampleClientAgent() { - // ssh-agent has a UNIX socket under $SSH_AUTH_SOCK - socket := os.Getenv("SSH_AUTH_SOCK") - conn, err := net.Dial("unix", socket) - if err != nil { - log.Fatalf("net.Dial: %v", err) - } - agentClient := agent.NewClient(conn) - config := &ssh.ClientConfig{ - User: "username", - Auth: []ssh.AuthMethod{ - // Use a callback rather than PublicKeys - // so we only consult the agent once the remote server - // wants it. - ssh.PublicKeysCallback(agentClient.Signers), - }, - } - - sshc, err := ssh.Dial("tcp", "localhost:22", config) - if err != nil { - log.Fatalf("Dial: %v", err) - } - // .. use sshc - sshc.Close() -} diff --git a/vendor/golang.org/x/crypto/ssh/agent/forward.go b/vendor/golang.org/x/crypto/ssh/agent/forward.go deleted file mode 100644 index fd24ba9..0000000 --- a/vendor/golang.org/x/crypto/ssh/agent/forward.go +++ /dev/null @@ -1,103 +0,0 @@ -// 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 deleted file mode 100644 index 12ffa82..0000000 --- a/vendor/golang.org/x/crypto/ssh/agent/keyring.go +++ /dev/null @@ -1,184 +0,0 @@ -// 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" - - "golang.org/x/crypto/ssh" -) - -type privKey struct { - signer ssh.Signer - comment string -} - -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 -} - -// 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 - } - - want := key.Marshal() - 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 -} - -// Lock locks the agent. Sign and Remove will fail, and List will empty 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 len(passphrase) != len(r.passphrase) || 1 != subtle.ConstantTimeCompare(passphrase, r.passphrase) { - return fmt.Errorf("agent: incorrect passphrase") - } - - r.locked = false - r.passphrase = nil - return nil -} - -// 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 - } - - 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 - } - } - - r.keys = append(r.keys, privKey{signer, key.Comment}) - - return nil -} - -// Sign returns a signature for the data. -func (r *keyring) Sign(key ssh.PublicKey, data []byte) (*ssh.Signature, error) { - r.mu.Lock() - defer r.mu.Unlock() - if r.locked { - return nil, errLocked - } - - wanted := key.Marshal() - for _, k := range r.keys { - if bytes.Equal(k.signer.PublicKey().Marshal(), wanted) { - return k.signer.Sign(rand.Reader, data) - } - } - 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 - } - - s := make([]ssh.Signer, 0, len(r.keys)) - for _, k := range r.keys { - s = append(s, k.signer) - } - return s, nil -} diff --git a/vendor/golang.org/x/crypto/ssh/agent/keyring_test.go b/vendor/golang.org/x/crypto/ssh/agent/keyring_test.go deleted file mode 100644 index 7f05905..0000000 --- a/vendor/golang.org/x/crypto/ssh/agent/keyring_test.go +++ /dev/null @@ -1,78 +0,0 @@ -// 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 agent - -import ( - "testing" -) - -func addTestKey(t *testing.T, a Agent, keyName string) { - err := a.Add(AddedKey{ - PrivateKey: testPrivateKeys[keyName], - Comment: keyName, - }) - if err != nil { - t.Fatalf("failed to add key %q: %v", keyName, err) - } -} - -func removeTestKey(t *testing.T, a Agent, keyName string) { - err := a.Remove(testPublicKeys[keyName]) - if err != nil { - t.Fatalf("failed to remove key %q: %v", keyName, err) - } -} - -func validateListedKeys(t *testing.T, a Agent, expectedKeys []string) { - listedKeys, err := a.List() - if err != nil { - t.Fatalf("failed to list keys: %v", err) - return - } - actualKeys := make(map[string]bool) - for _, key := range listedKeys { - actualKeys[key.Comment] = true - } - - matchedKeys := make(map[string]bool) - for _, expectedKey := range expectedKeys { - if !actualKeys[expectedKey] { - t.Fatalf("expected key %q, but was not found", expectedKey) - } else { - matchedKeys[expectedKey] = true - } - } - - for actualKey := range actualKeys { - if !matchedKeys[actualKey] { - t.Fatalf("key %q was found, but was not expected", actualKey) - } - } -} - -func TestKeyringAddingAndRemoving(t *testing.T) { - keyNames := []string{"dsa", "ecdsa", "rsa", "user"} - - // add all test private keys - k := NewKeyring() - for _, keyName := range keyNames { - addTestKey(t, k, keyName) - } - validateListedKeys(t, k, keyNames) - - // remove a key in the middle - keyToRemove := keyNames[1] - keyNames = append(keyNames[:1], keyNames[2:]...) - - removeTestKey(t, k, keyToRemove) - validateListedKeys(t, k, keyNames) - - // remove all keys - err := k.RemoveAll() - if err != nil { - t.Fatalf("failed to remove all keys: %v", err) - } - validateListedKeys(t, k, []string{}) -} diff --git a/vendor/golang.org/x/crypto/ssh/agent/server.go b/vendor/golang.org/x/crypto/ssh/agent/server.go deleted file mode 100644 index 092fd8f..0000000 --- a/vendor/golang.org/x/crypto/ssh/agent/server.go +++ /dev/null @@ -1,451 +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. - -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 agentLockMsg - 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, - } - - sig, err := s.agent.Sign(k, req.Data) // TODO(hanwen): flags. - 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) - } - - return nil, fmt.Errorf("unknown opcode %d", data[0]) -} - -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() - - return &AddedKey{PrivateKey: priv, Comment: k.Comments}, 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) - return &AddedKey{PrivateKey: &priv, Comment: k.Comments}, 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, - } - - return &AddedKey{PrivateKey: priv, Comment: k.Comments}, 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") - } - return &AddedKey{PrivateKey: &priv, Certificate: cert, Comment: k.Comments}, 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 - } - - return &AddedKey{PrivateKey: &priv, Comment: k.Comments}, 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() - - return &AddedKey{PrivateKey: &priv, Certificate: cert, Comment: k.Comments}, 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, - } - - return &AddedKey{PrivateKey: priv, Certificate: cert, Comment: k.Comments}, 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 - } - - return &AddedKey{PrivateKey: priv, Certificate: cert, Comment: k.Comments}, 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 = parseECDSACert(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 > 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/agent/server_test.go b/vendor/golang.org/x/crypto/ssh/agent/server_test.go deleted file mode 100644 index b5e92a6..0000000 --- a/vendor/golang.org/x/crypto/ssh/agent/server_test.go +++ /dev/null @@ -1,204 +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. - -package agent - -import ( - "crypto" - "crypto/rand" - "fmt" - "testing" - - "golang.org/x/crypto/ssh" -) - -func TestServer(t *testing.T) { - c1, c2, err := netPipe() - if err != nil { - t.Fatalf("netPipe: %v", err) - } - defer c1.Close() - defer c2.Close() - client := NewClient(c1) - - go ServeAgent(NewKeyring(), c2) - - testAgentInterface(t, client, testPrivateKeys["rsa"], nil, 0) -} - -func TestLockServer(t *testing.T) { - testLockAgent(NewKeyring(), t) -} - -func TestSetupForwardAgent(t *testing.T) { - a, b, err := netPipe() - if err != nil { - t.Fatalf("netPipe: %v", err) - } - - defer a.Close() - defer b.Close() - - _, socket, cleanup := startAgent(t) - defer cleanup() - - serverConf := ssh.ServerConfig{ - NoClientAuth: true, - } - serverConf.AddHostKey(testSigners["rsa"]) - incoming := make(chan *ssh.ServerConn, 1) - go func() { - conn, _, _, err := ssh.NewServerConn(a, &serverConf) - if err != nil { - t.Fatalf("Server: %v", err) - } - incoming <- conn - }() - - conf := ssh.ClientConfig{} - conn, chans, reqs, err := ssh.NewClientConn(b, "", &conf) - if err != nil { - t.Fatalf("NewClientConn: %v", err) - } - client := ssh.NewClient(conn, chans, reqs) - - if err := ForwardToRemote(client, socket); err != nil { - t.Fatalf("SetupForwardAgent: %v", err) - } - - server := <-incoming - ch, reqs, err := server.OpenChannel(channelType, nil) - if err != nil { - t.Fatalf("OpenChannel(%q): %v", channelType, err) - } - go ssh.DiscardRequests(reqs) - - agentClient := NewClient(ch) - testAgentInterface(t, agentClient, testPrivateKeys["rsa"], nil, 0) - conn.Close() -} - -func TestV1ProtocolMessages(t *testing.T) { - c1, c2, err := netPipe() - if err != nil { - t.Fatalf("netPipe: %v", err) - } - defer c1.Close() - defer c2.Close() - c := NewClient(c1) - - go ServeAgent(NewKeyring(), c2) - - testV1ProtocolMessages(t, c.(*client)) -} - -func testV1ProtocolMessages(t *testing.T, c *client) { - reply, err := c.call([]byte{agentRequestV1Identities}) - if err != nil { - t.Fatalf("v1 request all failed: %v", err) - } - if msg, ok := reply.(*agentV1IdentityMsg); !ok || msg.Numkeys != 0 { - t.Fatalf("invalid request all response: %#v", reply) - } - - reply, err = c.call([]byte{agentRemoveAllV1Identities}) - if err != nil { - t.Fatalf("v1 remove all failed: %v", err) - } - if _, ok := reply.(*successAgentMsg); !ok { - t.Fatalf("invalid remove all response: %#v", reply) - } -} - -func verifyKey(sshAgent Agent) error { - keys, err := sshAgent.List() - if err != nil { - return fmt.Errorf("listing keys: %v", err) - } - - if len(keys) != 1 { - return fmt.Errorf("bad number of keys found. expected 1, got %d", len(keys)) - } - - buf := make([]byte, 128) - if _, err := rand.Read(buf); err != nil { - return fmt.Errorf("rand: %v", err) - } - - sig, err := sshAgent.Sign(keys[0], buf) - if err != nil { - return fmt.Errorf("sign: %v", err) - } - - if err := keys[0].Verify(buf, sig); err != nil { - return fmt.Errorf("verify: %v", err) - } - return nil -} - -func addKeyToAgent(key crypto.PrivateKey) error { - sshAgent := NewKeyring() - if err := sshAgent.Add(AddedKey{PrivateKey: key}); err != nil { - return fmt.Errorf("add: %v", err) - } - return verifyKey(sshAgent) -} - -func TestKeyTypes(t *testing.T) { - for k, v := range testPrivateKeys { - if err := addKeyToAgent(v); err != nil { - t.Errorf("error adding key type %s, %v", k, err) - } - } -} - -func addCertToAgentSock(key crypto.PrivateKey, cert *ssh.Certificate) error { - a, b, err := netPipe() - if err != nil { - return err - } - agentServer := NewKeyring() - go ServeAgent(agentServer, a) - - agentClient := NewClient(b) - if err := agentClient.Add(AddedKey{PrivateKey: key, Certificate: cert}); err != nil { - return fmt.Errorf("add: %v", err) - } - return verifyKey(agentClient) -} - -func addCertToAgent(key crypto.PrivateKey, cert *ssh.Certificate) error { - sshAgent := NewKeyring() - if err := sshAgent.Add(AddedKey{PrivateKey: key, Certificate: cert}); err != nil { - return fmt.Errorf("add: %v", err) - } - return verifyKey(sshAgent) -} - -func TestCertTypes(t *testing.T) { - for keyType, key := range testPublicKeys { - cert := &ssh.Certificate{ - ValidPrincipals: []string{"gopher1"}, - ValidAfter: 0, - ValidBefore: ssh.CertTimeInfinity, - Key: key, - Serial: 1, - CertType: ssh.UserCert, - SignatureKey: testPublicKeys["rsa"], - Permissions: ssh.Permissions{ - CriticalOptions: map[string]string{}, - Extensions: map[string]string{}, - }, - } - if err := cert.SignCert(rand.Reader, testSigners["rsa"]); err != nil { - t.Fatalf("signcert: %v", err) - } - if err := addCertToAgent(testPrivateKeys[keyType], cert); err != nil { - t.Fatalf("%v", err) - } - if err := addCertToAgentSock(testPrivateKeys[keyType], cert); err != nil { - t.Fatalf("%v", err) - } - } -} diff --git a/vendor/golang.org/x/crypto/ssh/agent/testdata_test.go b/vendor/golang.org/x/crypto/ssh/agent/testdata_test.go deleted file mode 100644 index b7a8781..0000000 --- a/vendor/golang.org/x/crypto/ssh/agent/testdata_test.go +++ /dev/null @@ -1,64 +0,0 @@ -// 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. - -// IMPLEMENTOR NOTE: To avoid a package loop, this file is in three places: -// ssh/, ssh/agent, and ssh/test/. It should be kept in sync across all three -// instances. - -package agent - -import ( - "crypto/rand" - "fmt" - - "golang.org/x/crypto/ssh" - "golang.org/x/crypto/ssh/testdata" -) - -var ( - testPrivateKeys map[string]interface{} - testSigners map[string]ssh.Signer - testPublicKeys map[string]ssh.PublicKey -) - -func init() { - var err error - - n := len(testdata.PEMBytes) - testPrivateKeys = make(map[string]interface{}, n) - testSigners = make(map[string]ssh.Signer, n) - testPublicKeys = make(map[string]ssh.PublicKey, n) - for t, k := range testdata.PEMBytes { - testPrivateKeys[t], err = ssh.ParseRawPrivateKey(k) - if err != nil { - panic(fmt.Sprintf("Unable to parse test key %s: %v", t, err)) - } - testSigners[t], err = ssh.NewSignerFromKey(testPrivateKeys[t]) - if err != nil { - panic(fmt.Sprintf("Unable to create signer for test key %s: %v", t, err)) - } - testPublicKeys[t] = testSigners[t].PublicKey() - } - - // Create a cert and sign it for use in tests. - testCert := &ssh.Certificate{ - Nonce: []byte{}, // To pass reflect.DeepEqual after marshal & parse, this must be non-nil - ValidPrincipals: []string{"gopher1", "gopher2"}, // increases test coverage - ValidAfter: 0, // unix epoch - ValidBefore: ssh.CertTimeInfinity, // The end of currently representable time. - Reserved: []byte{}, // To pass reflect.DeepEqual after marshal & parse, this must be non-nil - Key: testPublicKeys["ecdsa"], - SignatureKey: testPublicKeys["rsa"], - Permissions: ssh.Permissions{ - CriticalOptions: map[string]string{}, - Extensions: map[string]string{}, - }, - } - testCert.SignCert(rand.Reader, testSigners["rsa"]) - testPrivateKeys["cert"] = testPrivateKeys["ecdsa"] - testSigners["cert"], err = ssh.NewCertSigner(testCert, testSigners["ecdsa"]) - if err != nil { - panic(fmt.Sprintf("Unable to create certificate signer: %v", err)) - } -} diff --git a/vendor/golang.org/x/crypto/ssh/benchmark_test.go b/vendor/golang.org/x/crypto/ssh/benchmark_test.go deleted file mode 100644 index d9f7eb9..0000000 --- a/vendor/golang.org/x/crypto/ssh/benchmark_test.go +++ /dev/null @@ -1,122 +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 ssh - -import ( - "errors" - "io" - "net" - "testing" -) - -type server struct { - *ServerConn - chans <-chan NewChannel -} - -func newServer(c net.Conn, conf *ServerConfig) (*server, error) { - sconn, chans, reqs, err := NewServerConn(c, conf) - if err != nil { - return nil, err - } - go DiscardRequests(reqs) - return &server{sconn, chans}, nil -} - -func (s *server) Accept() (NewChannel, error) { - n, ok := <-s.chans - if !ok { - return nil, io.EOF - } - return n, nil -} - -func sshPipe() (Conn, *server, error) { - c1, c2, err := netPipe() - if err != nil { - return nil, nil, err - } - - clientConf := ClientConfig{ - User: "user", - } - serverConf := ServerConfig{ - NoClientAuth: true, - } - serverConf.AddHostKey(testSigners["ecdsa"]) - done := make(chan *server, 1) - go func() { - server, err := newServer(c2, &serverConf) - if err != nil { - done <- nil - } - done <- server - }() - - client, _, reqs, err := NewClientConn(c1, "", &clientConf) - if err != nil { - return nil, nil, err - } - - server := <-done - if server == nil { - return nil, nil, errors.New("server handshake failed.") - } - go DiscardRequests(reqs) - - return client, server, nil -} - -func BenchmarkEndToEnd(b *testing.B) { - b.StopTimer() - - client, server, err := sshPipe() - if err != nil { - b.Fatalf("sshPipe: %v", err) - } - - defer client.Close() - defer server.Close() - - size := (1 << 20) - input := make([]byte, size) - output := make([]byte, size) - b.SetBytes(int64(size)) - done := make(chan int, 1) - - go func() { - newCh, err := server.Accept() - if err != nil { - b.Fatalf("Client: %v", err) - } - ch, incoming, err := newCh.Accept() - go DiscardRequests(incoming) - for i := 0; i < b.N; i++ { - if _, err := io.ReadFull(ch, output); err != nil { - b.Fatalf("ReadFull: %v", err) - } - } - ch.Close() - done <- 1 - }() - - ch, in, err := client.OpenChannel("speed", nil) - if err != nil { - b.Fatalf("OpenChannel: %v", err) - } - go DiscardRequests(in) - - b.ResetTimer() - b.StartTimer() - for i := 0; i < b.N; i++ { - if _, err := ch.Write(input); err != nil { - b.Fatalf("WriteFull: %v", err) - } - } - ch.Close() - b.StopTimer() - - <-done -} diff --git a/vendor/golang.org/x/crypto/ssh/buffer.go b/vendor/golang.org/x/crypto/ssh/buffer.go deleted file mode 100644 index 6931b51..0000000 --- a/vendor/golang.org/x/crypto/ssh/buffer.go +++ /dev/null @@ -1,98 +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. - -package ssh - -import ( - "io" - "sync" -) - -// buffer provides a linked list buffer for data exchange -// between producer and consumer. Theoretically the buffer is -// of unlimited capacity as it does no allocation of its own. -type buffer struct { - // protects concurrent access to head, tail and closed - *sync.Cond - - head *element // the buffer that will be read first - tail *element // the buffer that will be read last - - closed bool -} - -// An element represents a single link in a linked list. -type element struct { - buf []byte - next *element -} - -// newBuffer returns an empty buffer that is not closed. -func newBuffer() *buffer { - e := new(element) - b := &buffer{ - Cond: newCond(), - head: e, - tail: e, - } - return b -} - -// write makes buf available for Read to receive. -// buf must not be modified after the call to write. -func (b *buffer) write(buf []byte) { - b.Cond.L.Lock() - e := &element{buf: buf} - b.tail.next = e - b.tail = e - b.Cond.Signal() - b.Cond.L.Unlock() -} - -// eof closes the buffer. Reads from the buffer once all -// the data has been consumed will receive os.EOF. -func (b *buffer) eof() error { - b.Cond.L.Lock() - b.closed = true - b.Cond.Signal() - b.Cond.L.Unlock() - return nil -} - -// Read reads data from the internal buffer in buf. Reads will block -// if no data is available, or until the buffer is closed. -func (b *buffer) Read(buf []byte) (n int, err error) { - b.Cond.L.Lock() - defer b.Cond.L.Unlock() - - for len(buf) > 0 { - // if there is data in b.head, copy it - if len(b.head.buf) > 0 { - r := copy(buf, b.head.buf) - buf, b.head.buf = buf[r:], b.head.buf[r:] - n += r - continue - } - // if there is a next buffer, make it the head - if len(b.head.buf) == 0 && b.head != b.tail { - b.head = b.head.next - continue - } - - // if at least one byte has been copied, return - if n > 0 { - break - } - - // if nothing was read, and there is nothing outstanding - // check to see if the buffer is closed. - if b.closed { - err = io.EOF - break - } - // out of buffers, wait for producer - b.Cond.Wait() - } - return -} diff --git a/vendor/golang.org/x/crypto/ssh/buffer_test.go b/vendor/golang.org/x/crypto/ssh/buffer_test.go deleted file mode 100644 index d5781cb..0000000 --- a/vendor/golang.org/x/crypto/ssh/buffer_test.go +++ /dev/null @@ -1,87 +0,0 @@ -// 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 ssh - -import ( - "io" - "testing" -) - -var alphabet = []byte("abcdefghijklmnopqrstuvwxyz") - -func TestBufferReadwrite(t *testing.T) { - b := newBuffer() - b.write(alphabet[:10]) - r, _ := b.Read(make([]byte, 10)) - if r != 10 { - t.Fatalf("Expected written == read == 10, written: 10, read %d", r) - } - - b = newBuffer() - b.write(alphabet[:5]) - r, _ = b.Read(make([]byte, 10)) - if r != 5 { - t.Fatalf("Expected written == read == 5, written: 5, read %d", r) - } - - b = newBuffer() - b.write(alphabet[:10]) - r, _ = b.Read(make([]byte, 5)) - if r != 5 { - t.Fatalf("Expected written == 10, read == 5, written: 10, read %d", r) - } - - b = newBuffer() - b.write(alphabet[:5]) - b.write(alphabet[5:15]) - r, _ = b.Read(make([]byte, 10)) - r2, _ := b.Read(make([]byte, 10)) - if r != 10 || r2 != 5 || 15 != r+r2 { - t.Fatal("Expected written == read == 15") - } -} - -func TestBufferClose(t *testing.T) { - b := newBuffer() - b.write(alphabet[:10]) - b.eof() - _, err := b.Read(make([]byte, 5)) - if err != nil { - t.Fatal("expected read of 5 to not return EOF") - } - b = newBuffer() - b.write(alphabet[:10]) - b.eof() - r, err := b.Read(make([]byte, 5)) - r2, err2 := b.Read(make([]byte, 10)) - if r != 5 || r2 != 5 || err != nil || err2 != nil { - t.Fatal("expected reads of 5 and 5") - } - - b = newBuffer() - b.write(alphabet[:10]) - b.eof() - r, err = b.Read(make([]byte, 5)) - r2, err2 = b.Read(make([]byte, 10)) - r3, err3 := b.Read(make([]byte, 10)) - if r != 5 || r2 != 5 || r3 != 0 || err != nil || err2 != nil || err3 != io.EOF { - t.Fatal("expected reads of 5 and 5 and 0, with EOF") - } - - b = newBuffer() - b.write(make([]byte, 5)) - b.write(make([]byte, 10)) - b.eof() - r, err = b.Read(make([]byte, 9)) - r2, err2 = b.Read(make([]byte, 3)) - r3, err3 = b.Read(make([]byte, 3)) - r4, err4 := b.Read(make([]byte, 10)) - if err != nil || err2 != nil || err3 != nil || err4 != io.EOF { - t.Fatalf("Expected EOF on forth read only, err=%v, err2=%v, err3=%v, err4=%v", err, err2, err3, err4) - } - if r != 9 || r2 != 3 || r3 != 3 || r4 != 0 { - t.Fatal("Expected written == read == 15", r, r2, r3, r4) - } -} diff --git a/vendor/golang.org/x/crypto/ssh/certs.go b/vendor/golang.org/x/crypto/ssh/certs.go deleted file mode 100644 index 6331c94..0000000 --- a/vendor/golang.org/x/crypto/ssh/certs.go +++ /dev/null @@ -1,503 +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. - -package ssh - -import ( - "bytes" - "errors" - "fmt" - "io" - "net" - "sort" - "time" -) - -// These constants from [PROTOCOL.certkeys] represent the algorithm names -// for certificate types supported by this package. -const ( - CertAlgoRSAv01 = "ssh-rsa-cert-v01@openssh.com" - CertAlgoDSAv01 = "ssh-dss-cert-v01@openssh.com" - CertAlgoECDSA256v01 = "ecdsa-sha2-nistp256-cert-v01@openssh.com" - CertAlgoECDSA384v01 = "ecdsa-sha2-nistp384-cert-v01@openssh.com" - CertAlgoECDSA521v01 = "ecdsa-sha2-nistp521-cert-v01@openssh.com" - CertAlgoED25519v01 = "ssh-ed25519-cert-v01@openssh.com" -) - -// Certificate types distinguish between host and user -// certificates. The values can be set in the CertType field of -// Certificate. -const ( - UserCert = 1 - HostCert = 2 -) - -// Signature represents a cryptographic signature. -type Signature struct { - Format string - Blob []byte -} - -// CertTimeInfinity can be used for OpenSSHCertV01.ValidBefore to indicate that -// a certificate does not expire. -const CertTimeInfinity = 1<<64 - 1 - -// An Certificate represents an OpenSSH certificate as defined in -// [PROTOCOL.certkeys]?rev=1.8. -type Certificate struct { - Nonce []byte - Key PublicKey - Serial uint64 - CertType uint32 - KeyId string - ValidPrincipals []string - ValidAfter uint64 - ValidBefore uint64 - Permissions - Reserved []byte - SignatureKey PublicKey - Signature *Signature -} - -// genericCertData holds the key-independent part of the certificate data. -// Overall, certificates contain an nonce, public key fields and -// key-independent fields. -type genericCertData struct { - Serial uint64 - CertType uint32 - KeyId string - ValidPrincipals []byte - ValidAfter uint64 - ValidBefore uint64 - CriticalOptions []byte - Extensions []byte - Reserved []byte - SignatureKey []byte - Signature []byte -} - -func marshalStringList(namelist []string) []byte { - var to []byte - for _, name := range namelist { - s := struct{ N string }{name} - to = append(to, Marshal(&s)...) - } - return to -} - -type optionsTuple struct { - Key string - Value []byte -} - -type optionsTupleValue struct { - Value string -} - -// serialize a map of critical options or extensions -// issue #10569 - per [PROTOCOL.certkeys] and SSH implementation, -// we need two length prefixes for a non-empty string value -func marshalTuples(tups map[string]string) []byte { - keys := make([]string, 0, len(tups)) - for key := range tups { - keys = append(keys, key) - } - sort.Strings(keys) - - var ret []byte - for _, key := range keys { - s := optionsTuple{Key: key} - if value := tups[key]; len(value) > 0 { - s.Value = Marshal(&optionsTupleValue{value}) - } - ret = append(ret, Marshal(&s)...) - } - return ret -} - -// issue #10569 - per [PROTOCOL.certkeys] and SSH implementation, -// we need two length prefixes for a non-empty option value -func parseTuples(in []byte) (map[string]string, error) { - tups := map[string]string{} - var lastKey string - var haveLastKey bool - - for len(in) > 0 { - var key, val, extra []byte - var ok bool - - if key, in, ok = parseString(in); !ok { - return nil, errShortRead - } - keyStr := string(key) - // according to [PROTOCOL.certkeys], the names must be in - // lexical order. - if haveLastKey && keyStr <= lastKey { - return nil, fmt.Errorf("ssh: certificate options are not in lexical order") - } - lastKey, haveLastKey = keyStr, true - // the next field is a data field, which if non-empty has a string embedded - if val, in, ok = parseString(in); !ok { - return nil, errShortRead - } - if len(val) > 0 { - val, extra, ok = parseString(val) - if !ok { - return nil, errShortRead - } - if len(extra) > 0 { - return nil, fmt.Errorf("ssh: unexpected trailing data after certificate option value") - } - tups[keyStr] = string(val) - } else { - tups[keyStr] = "" - } - } - return tups, nil -} - -func parseCert(in []byte, privAlgo string) (*Certificate, error) { - nonce, rest, ok := parseString(in) - if !ok { - return nil, errShortRead - } - - key, rest, err := parsePubKey(rest, privAlgo) - if err != nil { - return nil, err - } - - var g genericCertData - if err := Unmarshal(rest, &g); err != nil { - return nil, err - } - - c := &Certificate{ - Nonce: nonce, - Key: key, - Serial: g.Serial, - CertType: g.CertType, - KeyId: g.KeyId, - ValidAfter: g.ValidAfter, - ValidBefore: g.ValidBefore, - } - - for principals := g.ValidPrincipals; len(principals) > 0; { - principal, rest, ok := parseString(principals) - if !ok { - return nil, errShortRead - } - c.ValidPrincipals = append(c.ValidPrincipals, string(principal)) - principals = rest - } - - c.CriticalOptions, err = parseTuples(g.CriticalOptions) - if err != nil { - return nil, err - } - c.Extensions, err = parseTuples(g.Extensions) - if err != nil { - return nil, err - } - c.Reserved = g.Reserved - k, err := ParsePublicKey(g.SignatureKey) - if err != nil { - return nil, err - } - - c.SignatureKey = k - c.Signature, rest, ok = parseSignatureBody(g.Signature) - if !ok || len(rest) > 0 { - return nil, errors.New("ssh: signature parse error") - } - - return c, nil -} - -type openSSHCertSigner struct { - pub *Certificate - signer Signer -} - -// NewCertSigner returns a Signer that signs with the given Certificate, whose -// private key is held by signer. It returns an error if the public key in cert -// doesn't match the key used by signer. -func NewCertSigner(cert *Certificate, signer Signer) (Signer, error) { - if bytes.Compare(cert.Key.Marshal(), signer.PublicKey().Marshal()) != 0 { - return nil, errors.New("ssh: signer and cert have different public key") - } - - return &openSSHCertSigner{cert, signer}, nil -} - -func (s *openSSHCertSigner) Sign(rand io.Reader, data []byte) (*Signature, error) { - return s.signer.Sign(rand, data) -} - -func (s *openSSHCertSigner) PublicKey() PublicKey { - return s.pub -} - -const sourceAddressCriticalOption = "source-address" - -// CertChecker does the work of verifying a certificate. Its methods -// can be plugged into ClientConfig.HostKeyCallback and -// ServerConfig.PublicKeyCallback. For the CertChecker to work, -// minimally, the IsAuthority callback should be set. -type CertChecker struct { - // SupportedCriticalOptions lists the CriticalOptions that the - // server application layer understands. These are only used - // for user certificates. - SupportedCriticalOptions []string - - // IsAuthority should return true if the key is recognized as - // an authority. This allows for certificates to be signed by other - // certificates. - IsAuthority func(auth PublicKey) bool - - // Clock is used for verifying time stamps. If nil, time.Now - // is used. - Clock func() time.Time - - // UserKeyFallback is called when CertChecker.Authenticate encounters a - // public key that is not a certificate. It must implement validation - // of user keys or else, if nil, all such keys are rejected. - UserKeyFallback func(conn ConnMetadata, key PublicKey) (*Permissions, error) - - // HostKeyFallback is called when CertChecker.CheckHostKey encounters a - // public key that is not a certificate. It must implement host key - // validation or else, if nil, all such keys are rejected. - HostKeyFallback func(addr string, remote net.Addr, key PublicKey) error - - // IsRevoked is called for each certificate so that revocation checking - // can be implemented. It should return true if the given certificate - // is revoked and false otherwise. If nil, no certificates are - // considered to have been revoked. - IsRevoked func(cert *Certificate) bool -} - -// CheckHostKey checks a host key certificate. This method can be -// plugged into ClientConfig.HostKeyCallback. -func (c *CertChecker) CheckHostKey(addr string, remote net.Addr, key PublicKey) error { - cert, ok := key.(*Certificate) - if !ok { - if c.HostKeyFallback != nil { - return c.HostKeyFallback(addr, remote, key) - } - return errors.New("ssh: non-certificate host key") - } - if cert.CertType != HostCert { - return fmt.Errorf("ssh: certificate presented as a host key has type %d", cert.CertType) - } - - return c.CheckCert(addr, cert) -} - -// Authenticate checks a user certificate. Authenticate can be used as -// a value for ServerConfig.PublicKeyCallback. -func (c *CertChecker) Authenticate(conn ConnMetadata, pubKey PublicKey) (*Permissions, error) { - cert, ok := pubKey.(*Certificate) - if !ok { - if c.UserKeyFallback != nil { - return c.UserKeyFallback(conn, pubKey) - } - return nil, errors.New("ssh: normal key pairs not accepted") - } - - if cert.CertType != UserCert { - return nil, fmt.Errorf("ssh: cert has type %d", cert.CertType) - } - - if err := c.CheckCert(conn.User(), cert); err != nil { - return nil, err - } - - return &cert.Permissions, nil -} - -// CheckCert checks CriticalOptions, ValidPrincipals, revocation, timestamp and -// the signature of the certificate. -func (c *CertChecker) CheckCert(principal string, cert *Certificate) error { - if c.IsRevoked != nil && c.IsRevoked(cert) { - return fmt.Errorf("ssh: certicate serial %d revoked", cert.Serial) - } - - for opt, _ := range cert.CriticalOptions { - // sourceAddressCriticalOption will be enforced by - // serverAuthenticate - if opt == sourceAddressCriticalOption { - continue - } - - found := false - for _, supp := range c.SupportedCriticalOptions { - if supp == opt { - found = true - break - } - } - if !found { - return fmt.Errorf("ssh: unsupported critical option %q in certificate", opt) - } - } - - if len(cert.ValidPrincipals) > 0 { - // By default, certs are valid for all users/hosts. - found := false - for _, p := range cert.ValidPrincipals { - if p == principal { - found = true - break - } - } - if !found { - return fmt.Errorf("ssh: principal %q not in the set of valid principals for given certificate: %q", principal, cert.ValidPrincipals) - } - } - - if !c.IsAuthority(cert.SignatureKey) { - return fmt.Errorf("ssh: certificate signed by unrecognized authority") - } - - clock := c.Clock - if clock == nil { - clock = time.Now - } - - unixNow := clock().Unix() - if after := int64(cert.ValidAfter); after < 0 || unixNow < int64(cert.ValidAfter) { - return fmt.Errorf("ssh: cert is not yet valid") - } - if before := int64(cert.ValidBefore); cert.ValidBefore != uint64(CertTimeInfinity) && (unixNow >= before || before < 0) { - return fmt.Errorf("ssh: cert has expired") - } - if err := cert.SignatureKey.Verify(cert.bytesForSigning(), cert.Signature); err != nil { - return fmt.Errorf("ssh: certificate signature does not verify") - } - - return nil -} - -// SignCert sets c.SignatureKey to the authority's public key and stores a -// Signature, by authority, in the certificate. -func (c *Certificate) SignCert(rand io.Reader, authority Signer) error { - c.Nonce = make([]byte, 32) - if _, err := io.ReadFull(rand, c.Nonce); err != nil { - return err - } - c.SignatureKey = authority.PublicKey() - - sig, err := authority.Sign(rand, c.bytesForSigning()) - if err != nil { - return err - } - c.Signature = sig - return nil -} - -var certAlgoNames = map[string]string{ - KeyAlgoRSA: CertAlgoRSAv01, - KeyAlgoDSA: CertAlgoDSAv01, - KeyAlgoECDSA256: CertAlgoECDSA256v01, - KeyAlgoECDSA384: CertAlgoECDSA384v01, - KeyAlgoECDSA521: CertAlgoECDSA521v01, - KeyAlgoED25519: CertAlgoED25519v01, -} - -// 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 - } - } - panic("unknown cert algorithm") -} - -func (cert *Certificate) bytesForSigning() []byte { - c2 := *cert - c2.Signature = nil - out := c2.Marshal() - // Drop trailing signature length. - return out[:len(out)-4] -} - -// Marshal serializes c into OpenSSH's wire format. It is part of the -// PublicKey interface. -func (c *Certificate) Marshal() []byte { - generic := genericCertData{ - Serial: c.Serial, - CertType: c.CertType, - KeyId: c.KeyId, - ValidPrincipals: marshalStringList(c.ValidPrincipals), - ValidAfter: uint64(c.ValidAfter), - ValidBefore: uint64(c.ValidBefore), - CriticalOptions: marshalTuples(c.CriticalOptions), - Extensions: marshalTuples(c.Extensions), - Reserved: c.Reserved, - SignatureKey: c.SignatureKey.Marshal(), - } - if c.Signature != nil { - generic.Signature = Marshal(c.Signature) - } - genericBytes := Marshal(&generic) - keyBytes := c.Key.Marshal() - _, keyBytes, _ = parseString(keyBytes) - prefix := Marshal(&struct { - Name string - Nonce []byte - Key []byte `ssh:"rest"` - }{c.Type(), c.Nonce, keyBytes}) - - result := make([]byte, 0, len(prefix)+len(genericBytes)) - result = append(result, prefix...) - result = append(result, genericBytes...) - return result -} - -// Type returns the key name. It is part of the PublicKey interface. -func (c *Certificate) Type() string { - algo, ok := certAlgoNames[c.Key.Type()] - if !ok { - panic("unknown cert key type " + c.Key.Type()) - } - return algo -} - -// Verify verifies a signature against the certificate's public -// key. It is part of the PublicKey interface. -func (c *Certificate) Verify(data []byte, sig *Signature) error { - return c.Key.Verify(data, sig) -} - -func parseSignatureBody(in []byte) (out *Signature, rest []byte, ok bool) { - format, in, ok := parseString(in) - if !ok { - return - } - - out = &Signature{ - Format: string(format), - } - - if out.Blob, in, ok = parseString(in); !ok { - return - } - - return out, in, ok -} - -func parseSignature(in []byte) (out *Signature, rest []byte, ok bool) { - sigBytes, rest, ok := parseString(in) - if !ok { - return - } - - out, trailing, ok := parseSignatureBody(sigBytes) - if !ok || len(trailing) > 0 { - return nil, nil, false - } - return -} diff --git a/vendor/golang.org/x/crypto/ssh/certs_test.go b/vendor/golang.org/x/crypto/ssh/certs_test.go deleted file mode 100644 index c5f2e53..0000000 --- a/vendor/golang.org/x/crypto/ssh/certs_test.go +++ /dev/null @@ -1,216 +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 ssh - -import ( - "bytes" - "crypto/rand" - "reflect" - "testing" - "time" -) - -// Cert generated by ssh-keygen 6.0p1 Debian-4. -// % ssh-keygen -s ca-key -I test user-key -const exampleSSHCert = `ssh-rsa-cert-v01@openssh.com AAAAHHNzaC1yc2EtY2VydC12MDFAb3BlbnNzaC5jb20AAAAgb1srW/W3ZDjYAO45xLYAwzHBDLsJ4Ux6ICFIkTjb1LEAAAADAQABAAAAYQCkoR51poH0wE8w72cqSB8Sszx+vAhzcMdCO0wqHTj7UNENHWEXGrU0E0UQekD7U+yhkhtoyjbPOVIP7hNa6aRk/ezdh/iUnCIt4Jt1v3Z1h1P+hA4QuYFMHNB+rmjPwAcAAAAAAAAAAAAAAAEAAAAEdGVzdAAAAAAAAAAAAAAAAP//////////AAAAAAAAAIIAAAAVcGVybWl0LVgxMS1mb3J3YXJkaW5nAAAAAAAAABdwZXJtaXQtYWdlbnQtZm9yd2FyZGluZwAAAAAAAAAWcGVybWl0LXBvcnQtZm9yd2FyZGluZwAAAAAAAAAKcGVybWl0LXB0eQAAAAAAAAAOcGVybWl0LXVzZXItcmMAAAAAAAAAAAAAAHcAAAAHc3NoLXJzYQAAAAMBAAEAAABhANFS2kaktpSGc+CcmEKPyw9mJC4nZKxHKTgLVZeaGbFZOvJTNzBspQHdy7Q1uKSfktxpgjZnksiu/tFF9ngyY2KFoc+U88ya95IZUycBGCUbBQ8+bhDtw/icdDGQD5WnUwAAAG8AAAAHc3NoLXJzYQAAAGC8Y9Z2LQKhIhxf52773XaWrXdxP0t3GBVo4A10vUWiYoAGepr6rQIoGGXFxT4B9Gp+nEBJjOwKDXPrAevow0T9ca8gZN+0ykbhSrXLE5Ao48rqr3zP4O1/9P7e6gp0gw8=` - -func TestParseCert(t *testing.T) { - authKeyBytes := []byte(exampleSSHCert) - - key, _, _, rest, err := ParseAuthorizedKey(authKeyBytes) - if err != nil { - t.Fatalf("ParseAuthorizedKey: %v", err) - } - if len(rest) > 0 { - t.Errorf("rest: got %q, want empty", rest) - } - - if _, ok := key.(*Certificate); !ok { - t.Fatalf("got %v (%T), want *Certificate", key, key) - } - - marshaled := MarshalAuthorizedKey(key) - // Before comparison, remove the trailing newline that - // MarshalAuthorizedKey adds. - marshaled = marshaled[:len(marshaled)-1] - if !bytes.Equal(authKeyBytes, marshaled) { - t.Errorf("marshaled certificate does not match original: got %q, want %q", marshaled, authKeyBytes) - } -} - -// Cert generated by ssh-keygen OpenSSH_6.8p1 OS X 10.10.3 -// % ssh-keygen -s ca -I testcert -O source-address=192.168.1.0/24 -O force-command=/bin/sleep user.pub -// user.pub key: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDACh1rt2DXfV3hk6fszSQcQ/rueMId0kVD9U7nl8cfEnFxqOCrNT92g4laQIGl2mn8lsGZfTLg8ksHq3gkvgO3oo/0wHy4v32JeBOHTsN5AL4gfHNEhWeWb50ev47hnTsRIt9P4dxogeUo/hTu7j9+s9lLpEQXCvq6xocXQt0j8MV9qZBBXFLXVT3cWIkSqOdwt/5ZBg+1GSrc7WfCXVWgTk4a20uPMuJPxU4RQwZW6X3+O8Pqo8C3cW0OzZRFP6gUYUKUsTI5WntlS+LAxgw1mZNsozFGdbiOPRnEryE3SRldh9vjDR3tin1fGpA5P7+CEB/bqaXtG3V+F2OkqaMN -// Critical Options: -// force-command /bin/sleep -// source-address 192.168.1.0/24 -// Extensions: -// permit-X11-forwarding -// permit-agent-forwarding -// permit-port-forwarding -// permit-pty -// permit-user-rc -const exampleSSHCertWithOptions = `ssh-rsa-cert-v01@openssh.com AAAAHHNzaC1yc2EtY2VydC12MDFAb3BlbnNzaC5jb20AAAAgDyysCJY0XrO1n03EeRRoITnTPdjENFmWDs9X58PP3VUAAAADAQABAAABAQDACh1rt2DXfV3hk6fszSQcQ/rueMId0kVD9U7nl8cfEnFxqOCrNT92g4laQIGl2mn8lsGZfTLg8ksHq3gkvgO3oo/0wHy4v32JeBOHTsN5AL4gfHNEhWeWb50ev47hnTsRIt9P4dxogeUo/hTu7j9+s9lLpEQXCvq6xocXQt0j8MV9qZBBXFLXVT3cWIkSqOdwt/5ZBg+1GSrc7WfCXVWgTk4a20uPMuJPxU4RQwZW6X3+O8Pqo8C3cW0OzZRFP6gUYUKUsTI5WntlS+LAxgw1mZNsozFGdbiOPRnEryE3SRldh9vjDR3tin1fGpA5P7+CEB/bqaXtG3V+F2OkqaMNAAAAAAAAAAAAAAABAAAACHRlc3RjZXJ0AAAAAAAAAAAAAAAA//////////8AAABLAAAADWZvcmNlLWNvbW1hbmQAAAAOAAAACi9iaW4vc2xlZXAAAAAOc291cmNlLWFkZHJlc3MAAAASAAAADjE5Mi4xNjguMS4wLzI0AAAAggAAABVwZXJtaXQtWDExLWZvcndhcmRpbmcAAAAAAAAAF3Blcm1pdC1hZ2VudC1mb3J3YXJkaW5nAAAAAAAAABZwZXJtaXQtcG9ydC1mb3J3YXJkaW5nAAAAAAAAAApwZXJtaXQtcHR5AAAAAAAAAA5wZXJtaXQtdXNlci1yYwAAAAAAAAAAAAABFwAAAAdzc2gtcnNhAAAAAwEAAQAAAQEAwU+c5ui5A8+J/CFpjW8wCa52bEODA808WWQDCSuTG/eMXNf59v9Y8Pk0F1E9dGCosSNyVcB/hacUrc6He+i97+HJCyKavBsE6GDxrjRyxYqAlfcOXi/IVmaUGiO8OQ39d4GHrjToInKvExSUeleQyH4Y4/e27T/pILAqPFL3fyrvMLT5qU9QyIt6zIpa7GBP5+urouNavMprV3zsfIqNBbWypinOQAw823a5wN+zwXnhZrgQiHZ/USG09Y6k98y1dTVz8YHlQVR4D3lpTAsKDKJ5hCH9WU4fdf+lU8OyNGaJ/vz0XNqxcToe1l4numLTnaoSuH89pHryjqurB7lJKwAAAQ8AAAAHc3NoLXJzYQAAAQCaHvUIoPL1zWUHIXLvu96/HU1s/i4CAW2IIEuGgxCUCiFj6vyTyYtgxQxcmbfZf6eaITlS6XJZa7Qq4iaFZh75C1DXTX8labXhRSD4E2t//AIP9MC1rtQC5xo6FmbQ+BoKcDskr+mNACcbRSxs3IL3bwCfWDnIw2WbVox9ZdcthJKk4UoCW4ix4QwdHw7zlddlz++fGEEVhmTbll1SUkycGApPFBsAYRTMupUJcYPIeReBI/m8XfkoMk99bV8ZJQTAd7OekHY2/48Ff53jLmyDjP7kNw1F8OaPtkFs6dGJXta4krmaekPy87j+35In5hFj7yoOqvSbmYUkeX70/GGQ` - -func TestParseCertWithOptions(t *testing.T) { - opts := map[string]string{ - "source-address": "192.168.1.0/24", - "force-command": "/bin/sleep", - } - exts := map[string]string{ - "permit-X11-forwarding": "", - "permit-agent-forwarding": "", - "permit-port-forwarding": "", - "permit-pty": "", - "permit-user-rc": "", - } - authKeyBytes := []byte(exampleSSHCertWithOptions) - - key, _, _, rest, err := ParseAuthorizedKey(authKeyBytes) - if err != nil { - t.Fatalf("ParseAuthorizedKey: %v", err) - } - if len(rest) > 0 { - t.Errorf("rest: got %q, want empty", rest) - } - cert, ok := key.(*Certificate) - if !ok { - t.Fatalf("got %v (%T), want *Certificate", key, key) - } - if !reflect.DeepEqual(cert.CriticalOptions, opts) { - t.Errorf("unexpected critical options - got %v, want %v", cert.CriticalOptions, opts) - } - if !reflect.DeepEqual(cert.Extensions, exts) { - t.Errorf("unexpected Extensions - got %v, want %v", cert.Extensions, exts) - } - marshaled := MarshalAuthorizedKey(key) - // Before comparison, remove the trailing newline that - // MarshalAuthorizedKey adds. - marshaled = marshaled[:len(marshaled)-1] - if !bytes.Equal(authKeyBytes, marshaled) { - t.Errorf("marshaled certificate does not match original: got %q, want %q", marshaled, authKeyBytes) - } -} - -func TestValidateCert(t *testing.T) { - key, _, _, _, err := ParseAuthorizedKey([]byte(exampleSSHCert)) - if err != nil { - t.Fatalf("ParseAuthorizedKey: %v", err) - } - validCert, ok := key.(*Certificate) - if !ok { - t.Fatalf("got %v (%T), want *Certificate", key, key) - } - checker := CertChecker{} - checker.IsAuthority = func(k PublicKey) bool { - return bytes.Equal(k.Marshal(), validCert.SignatureKey.Marshal()) - } - - if err := checker.CheckCert("user", validCert); err != nil { - t.Errorf("Unable to validate certificate: %v", err) - } - invalidCert := &Certificate{ - Key: testPublicKeys["rsa"], - SignatureKey: testPublicKeys["ecdsa"], - ValidBefore: CertTimeInfinity, - Signature: &Signature{}, - } - if err := checker.CheckCert("user", invalidCert); err == nil { - t.Error("Invalid cert signature passed validation") - } -} - -func TestValidateCertTime(t *testing.T) { - cert := Certificate{ - ValidPrincipals: []string{"user"}, - Key: testPublicKeys["rsa"], - ValidAfter: 50, - ValidBefore: 100, - } - - cert.SignCert(rand.Reader, testSigners["ecdsa"]) - - for ts, ok := range map[int64]bool{ - 25: false, - 50: true, - 99: true, - 100: false, - 125: false, - } { - checker := CertChecker{ - Clock: func() time.Time { return time.Unix(ts, 0) }, - } - checker.IsAuthority = func(k PublicKey) bool { - return bytes.Equal(k.Marshal(), - testPublicKeys["ecdsa"].Marshal()) - } - - if v := checker.CheckCert("user", &cert); (v == nil) != ok { - t.Errorf("Authenticate(%d): %v", ts, v) - } - } -} - -// TODO(hanwen): tests for -// -// host keys: -// * fallbacks - -func TestHostKeyCert(t *testing.T) { - cert := &Certificate{ - ValidPrincipals: []string{"hostname", "hostname.domain"}, - Key: testPublicKeys["rsa"], - ValidBefore: CertTimeInfinity, - CertType: HostCert, - } - cert.SignCert(rand.Reader, testSigners["ecdsa"]) - - checker := &CertChecker{ - IsAuthority: func(p PublicKey) bool { - return bytes.Equal(testPublicKeys["ecdsa"].Marshal(), p.Marshal()) - }, - } - - certSigner, err := NewCertSigner(cert, testSigners["rsa"]) - if err != nil { - t.Errorf("NewCertSigner: %v", err) - } - - for _, name := range []string{"hostname", "otherhost"} { - c1, c2, err := netPipe() - if err != nil { - t.Fatalf("netPipe: %v", err) - } - defer c1.Close() - defer c2.Close() - - errc := make(chan error) - - go func() { - conf := ServerConfig{ - NoClientAuth: true, - } - conf.AddHostKey(certSigner) - _, _, _, err := NewServerConn(c1, &conf) - errc <- err - }() - - config := &ClientConfig{ - User: "user", - HostKeyCallback: checker.CheckHostKey, - } - _, _, _, err = NewClientConn(c2, name, config) - - succeed := name == "hostname" - if (err == nil) != succeed { - t.Fatalf("NewClientConn(%q): %v", name, err) - } - - err = <-errc - if (err == nil) != succeed { - t.Fatalf("NewServerConn(%q): %v", name, err) - } - } -} diff --git a/vendor/golang.org/x/crypto/ssh/channel.go b/vendor/golang.org/x/crypto/ssh/channel.go deleted file mode 100644 index 6671c98..0000000 --- a/vendor/golang.org/x/crypto/ssh/channel.go +++ /dev/null @@ -1,631 +0,0 @@ -// 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 ssh - -import ( - "encoding/binary" - "errors" - "fmt" - "io" - "log" - "sync" -) - -const ( - minPacketLength = 9 - // channelMaxPacket contains the maximum number of bytes that will be - // sent in a single packet. As per RFC 4253, section 6.1, 32k is also - // the minimum. - channelMaxPacket = 1 << 15 - // We follow OpenSSH here. - channelWindowSize = 64 * channelMaxPacket -) - -// NewChannel represents an incoming request to a channel. It must either be -// accepted for use by calling Accept, or rejected by calling Reject. -type NewChannel interface { - // Accept accepts the channel creation request. It returns the Channel - // and a Go channel containing SSH requests. The Go channel must be - // serviced otherwise the Channel will hang. - Accept() (Channel, <-chan *Request, error) - - // Reject rejects the channel creation request. After calling - // this, no other methods on the Channel may be called. - Reject(reason RejectionReason, message string) error - - // ChannelType returns the type of the channel, as supplied by the - // client. - ChannelType() string - - // ExtraData returns the arbitrary payload for this channel, as supplied - // by the client. This data is specific to the channel type. - ExtraData() []byte -} - -// A Channel is an ordered, reliable, flow-controlled, duplex stream -// that is multiplexed over an SSH connection. -type Channel interface { - // Read reads up to len(data) bytes from the channel. - Read(data []byte) (int, error) - - // Write writes len(data) bytes to the channel. - Write(data []byte) (int, error) - - // Close signals end of channel use. No data may be sent after this - // call. - Close() error - - // CloseWrite signals the end of sending in-band - // data. Requests may still be sent, and the other side may - // still send data - CloseWrite() error - - // SendRequest sends a channel request. If wantReply is true, - // it will wait for a reply and return the result as a - // boolean, otherwise the return value will be false. Channel - // requests are out-of-band messages so they may be sent even - // if the data stream is closed or blocked by flow control. - SendRequest(name string, wantReply bool, payload []byte) (bool, error) - - // Stderr returns an io.ReadWriter that writes to this channel - // with the extended data type set to stderr. Stderr may - // safely be read and written from a different goroutine than - // Read and Write respectively. - Stderr() io.ReadWriter -} - -// Request is a request sent outside of the normal stream of -// data. Requests can either be specific to an SSH channel, or they -// can be global. -type Request struct { - Type string - WantReply bool - Payload []byte - - ch *channel - mux *mux -} - -// Reply sends a response to a request. It must be called for all requests -// where WantReply is true and is a no-op otherwise. The payload argument is -// ignored for replies to channel-specific requests. -func (r *Request) Reply(ok bool, payload []byte) error { - if !r.WantReply { - return nil - } - - if r.ch == nil { - return r.mux.ackRequest(ok, payload) - } - - return r.ch.ackRequest(ok) -} - -// RejectionReason is an enumeration used when rejecting channel creation -// requests. See RFC 4254, section 5.1. -type RejectionReason uint32 - -const ( - Prohibited RejectionReason = iota + 1 - ConnectionFailed - UnknownChannelType - ResourceShortage -) - -// String converts the rejection reason to human readable form. -func (r RejectionReason) String() string { - switch r { - case Prohibited: - return "administratively prohibited" - case ConnectionFailed: - return "connect failed" - case UnknownChannelType: - return "unknown channel type" - case ResourceShortage: - return "resource shortage" - } - return fmt.Sprintf("unknown reason %d", int(r)) -} - -func min(a uint32, b int) uint32 { - if a < uint32(b) { - return a - } - return uint32(b) -} - -type channelDirection uint8 - -const ( - channelInbound channelDirection = iota - channelOutbound -) - -// channel is an implementation of the Channel interface that works -// with the mux class. -type channel struct { - // R/O after creation - chanType string - extraData []byte - localId, remoteId uint32 - - // maxIncomingPayload and maxRemotePayload are the maximum - // payload sizes of normal and extended data packets for - // receiving and sending, respectively. The wire packet will - // be 9 or 13 bytes larger (excluding encryption overhead). - maxIncomingPayload uint32 - maxRemotePayload uint32 - - mux *mux - - // decided is set to true if an accept or reject message has been sent - // (for outbound channels) or received (for inbound channels). - decided bool - - // direction contains either channelOutbound, for channels created - // locally, or channelInbound, for channels created by the peer. - direction channelDirection - - // Pending internal channel messages. - msg chan interface{} - - // Since requests have no ID, there can be only one request - // with WantReply=true outstanding. This lock is held by a - // goroutine that has such an outgoing request pending. - sentRequestMu sync.Mutex - - incomingRequests chan *Request - - sentEOF bool - - // thread-safe data - remoteWin window - pending *buffer - extPending *buffer - - // windowMu protects myWindow, the flow-control window. - windowMu sync.Mutex - myWindow uint32 - - // writeMu serializes calls to mux.conn.writePacket() and - // protects sentClose and packetPool. This mutex must be - // different from windowMu, as writePacket can block if there - // is a key exchange pending. - writeMu sync.Mutex - sentClose bool - - // packetPool has a buffer for each extended channel ID to - // save allocations during writes. - packetPool map[uint32][]byte -} - -// writePacket sends a packet. If the packet is a channel close, it updates -// sentClose. This method takes the lock c.writeMu. -func (c *channel) writePacket(packet []byte) error { - c.writeMu.Lock() - if c.sentClose { - c.writeMu.Unlock() - return io.EOF - } - c.sentClose = (packet[0] == msgChannelClose) - err := c.mux.conn.writePacket(packet) - c.writeMu.Unlock() - return err -} - -func (c *channel) sendMessage(msg interface{}) error { - if debugMux { - log.Printf("send(%d): %#v", c.mux.chanList.offset, msg) - } - - p := Marshal(msg) - binary.BigEndian.PutUint32(p[1:], c.remoteId) - return c.writePacket(p) -} - -// WriteExtended writes data to a specific extended stream. These streams are -// used, for example, for stderr. -func (c *channel) WriteExtended(data []byte, extendedCode uint32) (n int, err error) { - if c.sentEOF { - return 0, io.EOF - } - // 1 byte message type, 4 bytes remoteId, 4 bytes data length - opCode := byte(msgChannelData) - headerLength := uint32(9) - if extendedCode > 0 { - headerLength += 4 - opCode = msgChannelExtendedData - } - - c.writeMu.Lock() - packet := c.packetPool[extendedCode] - // We don't remove the buffer from packetPool, so - // WriteExtended calls from different goroutines will be - // flagged as errors by the race detector. - c.writeMu.Unlock() - - for len(data) > 0 { - space := min(c.maxRemotePayload, len(data)) - if space, err = c.remoteWin.reserve(space); err != nil { - return n, err - } - if want := headerLength + space; uint32(cap(packet)) < want { - packet = make([]byte, want) - } else { - packet = packet[:want] - } - - todo := data[:space] - - packet[0] = opCode - binary.BigEndian.PutUint32(packet[1:], c.remoteId) - if extendedCode > 0 { - binary.BigEndian.PutUint32(packet[5:], uint32(extendedCode)) - } - binary.BigEndian.PutUint32(packet[headerLength-4:], uint32(len(todo))) - copy(packet[headerLength:], todo) - if err = c.writePacket(packet); err != nil { - return n, err - } - - n += len(todo) - data = data[len(todo):] - } - - c.writeMu.Lock() - c.packetPool[extendedCode] = packet - c.writeMu.Unlock() - - return n, err -} - -func (c *channel) handleData(packet []byte) error { - headerLen := 9 - isExtendedData := packet[0] == msgChannelExtendedData - if isExtendedData { - headerLen = 13 - } - if len(packet) < headerLen { - // malformed data packet - return parseError(packet[0]) - } - - var extended uint32 - if isExtendedData { - extended = binary.BigEndian.Uint32(packet[5:]) - } - - length := binary.BigEndian.Uint32(packet[headerLen-4 : headerLen]) - if length == 0 { - return nil - } - if length > c.maxIncomingPayload { - // TODO(hanwen): should send Disconnect? - return errors.New("ssh: incoming packet exceeds maximum payload size") - } - - data := packet[headerLen:] - if length != uint32(len(data)) { - return errors.New("ssh: wrong packet length") - } - - c.windowMu.Lock() - if c.myWindow < length { - c.windowMu.Unlock() - // TODO(hanwen): should send Disconnect with reason? - return errors.New("ssh: remote side wrote too much") - } - c.myWindow -= length - c.windowMu.Unlock() - - if extended == 1 { - c.extPending.write(data) - } else if extended > 0 { - // discard other extended data. - } else { - c.pending.write(data) - } - return nil -} - -func (c *channel) adjustWindow(n uint32) error { - c.windowMu.Lock() - // Since myWindow is managed on our side, and can never exceed - // the initial window setting, we don't worry about overflow. - c.myWindow += uint32(n) - c.windowMu.Unlock() - return c.sendMessage(windowAdjustMsg{ - AdditionalBytes: uint32(n), - }) -} - -func (c *channel) ReadExtended(data []byte, extended uint32) (n int, err error) { - switch extended { - case 1: - n, err = c.extPending.Read(data) - case 0: - n, err = c.pending.Read(data) - default: - return 0, fmt.Errorf("ssh: extended code %d unimplemented", extended) - } - - if n > 0 { - err = c.adjustWindow(uint32(n)) - // sendWindowAdjust can return io.EOF if the remote - // peer has closed the connection, however we want to - // defer forwarding io.EOF to the caller of Read until - // the buffer has been drained. - if n > 0 && err == io.EOF { - err = nil - } - } - - return n, err -} - -func (c *channel) close() { - c.pending.eof() - c.extPending.eof() - close(c.msg) - close(c.incomingRequests) - c.writeMu.Lock() - // This is not necessary for a normal channel teardown, but if - // there was another error, it is. - c.sentClose = true - c.writeMu.Unlock() - // Unblock writers. - c.remoteWin.close() -} - -// responseMessageReceived is called when a success or failure message is -// received on a channel to check that such a message is reasonable for the -// given channel. -func (c *channel) responseMessageReceived() error { - if c.direction == channelInbound { - return errors.New("ssh: channel response message received on inbound channel") - } - if c.decided { - return errors.New("ssh: duplicate response received for channel") - } - c.decided = true - return nil -} - -func (c *channel) handlePacket(packet []byte) error { - switch packet[0] { - case msgChannelData, msgChannelExtendedData: - return c.handleData(packet) - case msgChannelClose: - c.sendMessage(channelCloseMsg{PeersId: c.remoteId}) - c.mux.chanList.remove(c.localId) - c.close() - return nil - case msgChannelEOF: - // RFC 4254 is mute on how EOF affects dataExt messages but - // it is logical to signal EOF at the same time. - c.extPending.eof() - c.pending.eof() - return nil - } - - decoded, err := decode(packet) - if err != nil { - return err - } - - switch msg := decoded.(type) { - case *channelOpenFailureMsg: - if err := c.responseMessageReceived(); err != nil { - return err - } - c.mux.chanList.remove(msg.PeersId) - c.msg <- msg - case *channelOpenConfirmMsg: - if err := c.responseMessageReceived(); err != nil { - return err - } - if msg.MaxPacketSize < minPacketLength || msg.MaxPacketSize > 1<<31 { - return fmt.Errorf("ssh: invalid MaxPacketSize %d from peer", msg.MaxPacketSize) - } - c.remoteId = msg.MyId - c.maxRemotePayload = msg.MaxPacketSize - c.remoteWin.add(msg.MyWindow) - c.msg <- msg - case *windowAdjustMsg: - if !c.remoteWin.add(msg.AdditionalBytes) { - return fmt.Errorf("ssh: invalid window update for %d bytes", msg.AdditionalBytes) - } - case *channelRequestMsg: - req := Request{ - Type: msg.Request, - WantReply: msg.WantReply, - Payload: msg.RequestSpecificData, - ch: c, - } - - c.incomingRequests <- &req - default: - c.msg <- msg - } - return nil -} - -func (m *mux) newChannel(chanType string, direction channelDirection, extraData []byte) *channel { - ch := &channel{ - remoteWin: window{Cond: newCond()}, - myWindow: channelWindowSize, - pending: newBuffer(), - extPending: newBuffer(), - direction: direction, - incomingRequests: make(chan *Request, 16), - msg: make(chan interface{}, 16), - chanType: chanType, - extraData: extraData, - mux: m, - packetPool: make(map[uint32][]byte), - } - ch.localId = m.chanList.add(ch) - return ch -} - -var errUndecided = errors.New("ssh: must Accept or Reject channel") -var errDecidedAlready = errors.New("ssh: can call Accept or Reject only once") - -type extChannel struct { - code uint32 - ch *channel -} - -func (e *extChannel) Write(data []byte) (n int, err error) { - return e.ch.WriteExtended(data, e.code) -} - -func (e *extChannel) Read(data []byte) (n int, err error) { - return e.ch.ReadExtended(data, e.code) -} - -func (c *channel) Accept() (Channel, <-chan *Request, error) { - if c.decided { - return nil, nil, errDecidedAlready - } - c.maxIncomingPayload = channelMaxPacket - confirm := channelOpenConfirmMsg{ - PeersId: c.remoteId, - MyId: c.localId, - MyWindow: c.myWindow, - MaxPacketSize: c.maxIncomingPayload, - } - c.decided = true - if err := c.sendMessage(confirm); err != nil { - return nil, nil, err - } - - return c, c.incomingRequests, nil -} - -func (ch *channel) Reject(reason RejectionReason, message string) error { - if ch.decided { - return errDecidedAlready - } - reject := channelOpenFailureMsg{ - PeersId: ch.remoteId, - Reason: reason, - Message: message, - Language: "en", - } - ch.decided = true - return ch.sendMessage(reject) -} - -func (ch *channel) Read(data []byte) (int, error) { - if !ch.decided { - return 0, errUndecided - } - return ch.ReadExtended(data, 0) -} - -func (ch *channel) Write(data []byte) (int, error) { - if !ch.decided { - return 0, errUndecided - } - return ch.WriteExtended(data, 0) -} - -func (ch *channel) CloseWrite() error { - if !ch.decided { - return errUndecided - } - ch.sentEOF = true - return ch.sendMessage(channelEOFMsg{ - PeersId: ch.remoteId}) -} - -func (ch *channel) Close() error { - if !ch.decided { - return errUndecided - } - - return ch.sendMessage(channelCloseMsg{ - PeersId: ch.remoteId}) -} - -// Extended returns an io.ReadWriter that sends and receives data on the given, -// SSH extended stream. Such streams are used, for example, for stderr. -func (ch *channel) Extended(code uint32) io.ReadWriter { - if !ch.decided { - return nil - } - return &extChannel{code, ch} -} - -func (ch *channel) Stderr() io.ReadWriter { - return ch.Extended(1) -} - -func (ch *channel) SendRequest(name string, wantReply bool, payload []byte) (bool, error) { - if !ch.decided { - return false, errUndecided - } - - if wantReply { - ch.sentRequestMu.Lock() - defer ch.sentRequestMu.Unlock() - } - - msg := channelRequestMsg{ - PeersId: ch.remoteId, - Request: name, - WantReply: wantReply, - RequestSpecificData: payload, - } - - if err := ch.sendMessage(msg); err != nil { - return false, err - } - - if wantReply { - m, ok := (<-ch.msg) - if !ok { - return false, io.EOF - } - switch m.(type) { - case *channelRequestFailureMsg: - return false, nil - case *channelRequestSuccessMsg: - return true, nil - default: - return false, fmt.Errorf("ssh: unexpected response to channel request: %#v", m) - } - } - - return false, nil -} - -// ackRequest either sends an ack or nack to the channel request. -func (ch *channel) ackRequest(ok bool) error { - if !ch.decided { - return errUndecided - } - - var msg interface{} - if !ok { - msg = channelRequestFailureMsg{ - PeersId: ch.remoteId, - } - } else { - msg = channelRequestSuccessMsg{ - PeersId: ch.remoteId, - } - } - return ch.sendMessage(msg) -} - -func (ch *channel) ChannelType() string { - return ch.chanType -} - -func (ch *channel) ExtraData() []byte { - return ch.extraData -} diff --git a/vendor/golang.org/x/crypto/ssh/cipher.go b/vendor/golang.org/x/crypto/ssh/cipher.go deleted file mode 100644 index 34d3917..0000000 --- a/vendor/golang.org/x/crypto/ssh/cipher.go +++ /dev/null @@ -1,579 +0,0 @@ -// 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 ssh - -import ( - "crypto/aes" - "crypto/cipher" - "crypto/des" - "crypto/rc4" - "crypto/subtle" - "encoding/binary" - "errors" - "fmt" - "hash" - "io" - "io/ioutil" -) - -const ( - packetSizeMultiple = 16 // TODO(huin) this should be determined by the cipher. - - // RFC 4253 section 6.1 defines a minimum packet size of 32768 that implementations - // MUST be able to process (plus a few more kilobytes for padding and mac). The RFC - // indicates implementations SHOULD be able to handle larger packet sizes, but then - // waffles on about reasonable limits. - // - // OpenSSH caps their maxPacket at 256kB so we choose to do - // the same. maxPacket is also used to ensure that uint32 - // length fields do not overflow, so it should remain well - // below 4G. - maxPacket = 256 * 1024 -) - -// noneCipher implements cipher.Stream and provides no encryption. It is used -// by the transport before the first key-exchange. -type noneCipher struct{} - -func (c noneCipher) XORKeyStream(dst, src []byte) { - copy(dst, src) -} - -func newAESCTR(key, iv []byte) (cipher.Stream, error) { - c, err := aes.NewCipher(key) - if err != nil { - return nil, err - } - return cipher.NewCTR(c, iv), nil -} - -func newRC4(key, iv []byte) (cipher.Stream, error) { - return rc4.NewCipher(key) -} - -type streamCipherMode struct { - keySize int - ivSize int - skip int - createFunc func(key, iv []byte) (cipher.Stream, error) -} - -func (c *streamCipherMode) createStream(key, iv []byte) (cipher.Stream, error) { - if len(key) < c.keySize { - panic("ssh: key length too small for cipher") - } - if len(iv) < c.ivSize { - panic("ssh: iv too small for cipher") - } - - stream, err := c.createFunc(key[:c.keySize], iv[:c.ivSize]) - if err != nil { - return nil, err - } - - var streamDump []byte - if c.skip > 0 { - streamDump = make([]byte, 512) - } - - for remainingToDump := c.skip; remainingToDump > 0; { - dumpThisTime := remainingToDump - if dumpThisTime > len(streamDump) { - dumpThisTime = len(streamDump) - } - stream.XORKeyStream(streamDump[:dumpThisTime], streamDump[:dumpThisTime]) - remainingToDump -= dumpThisTime - } - - return stream, nil -} - -// cipherModes documents properties of supported ciphers. Ciphers not included -// are not supported and will not be negotiated, even if explicitly requested in -// ClientConfig.Crypto.Ciphers. -var cipherModes = map[string]*streamCipherMode{ - // Ciphers from RFC4344, which introduced many CTR-based ciphers. Algorithms - // are defined in the order specified in the RFC. - "aes128-ctr": {16, aes.BlockSize, 0, newAESCTR}, - "aes192-ctr": {24, aes.BlockSize, 0, newAESCTR}, - "aes256-ctr": {32, aes.BlockSize, 0, newAESCTR}, - - // Ciphers from RFC4345, which introduces security-improved arcfour ciphers. - // They are defined in the order specified in the RFC. - "arcfour128": {16, 0, 1536, newRC4}, - "arcfour256": {32, 0, 1536, newRC4}, - - // Cipher defined in RFC 4253, which describes SSH Transport Layer Protocol. - // Note that this cipher is not safe, as stated in RFC 4253: "Arcfour (and - // RC4) has problems with weak keys, and should be used with caution." - // RFC4345 introduces improved versions of Arcfour. - "arcfour": {16, 0, 0, newRC4}, - - // AES-GCM is not a stream cipher, so it is constructed with a - // special case. If we add any more non-stream ciphers, we - // should invest a cleaner way to do this. - gcmCipherID: {16, 12, 0, nil}, - - // CBC mode is insecure and so is not included in the default config. - // (See http://www.isg.rhul.ac.uk/~kp/SandPfinal.pdf). If absolutely - // needed, it's possible to specify a custom Config to enable it. - // You should expect that an active attacker can recover plaintext if - // you do. - aes128cbcID: {16, aes.BlockSize, 0, nil}, - - // 3des-cbc is insecure and is disabled by default. - tripledescbcID: {24, des.BlockSize, 0, nil}, -} - -// prefixLen is the length of the packet prefix that contains the packet length -// and number of padding bytes. -const prefixLen = 5 - -// streamPacketCipher is a packetCipher using a stream cipher. -type streamPacketCipher struct { - mac hash.Hash - cipher cipher.Stream - - // The following members are to avoid per-packet allocations. - prefix [prefixLen]byte - seqNumBytes [4]byte - padding [2 * packetSizeMultiple]byte - packetData []byte - macResult []byte -} - -// readPacket reads and decrypt a single packet from the reader argument. -func (s *streamPacketCipher) readPacket(seqNum uint32, r io.Reader) ([]byte, error) { - if _, err := io.ReadFull(r, s.prefix[:]); err != nil { - return nil, err - } - - s.cipher.XORKeyStream(s.prefix[:], s.prefix[:]) - length := binary.BigEndian.Uint32(s.prefix[0:4]) - paddingLength := uint32(s.prefix[4]) - - var macSize uint32 - if s.mac != nil { - s.mac.Reset() - binary.BigEndian.PutUint32(s.seqNumBytes[:], seqNum) - s.mac.Write(s.seqNumBytes[:]) - s.mac.Write(s.prefix[:]) - macSize = uint32(s.mac.Size()) - } - - if length <= paddingLength+1 { - return nil, errors.New("ssh: invalid packet length, packet too small") - } - - if length > maxPacket { - return nil, errors.New("ssh: invalid packet length, packet too large") - } - - // the maxPacket check above ensures that length-1+macSize - // does not overflow. - if uint32(cap(s.packetData)) < length-1+macSize { - s.packetData = make([]byte, length-1+macSize) - } else { - s.packetData = s.packetData[:length-1+macSize] - } - - if _, err := io.ReadFull(r, s.packetData); err != nil { - return nil, err - } - mac := s.packetData[length-1:] - data := s.packetData[:length-1] - s.cipher.XORKeyStream(data, data) - - if s.mac != nil { - s.mac.Write(data) - s.macResult = s.mac.Sum(s.macResult[:0]) - if subtle.ConstantTimeCompare(s.macResult, mac) != 1 { - return nil, errors.New("ssh: MAC failure") - } - } - - return s.packetData[:length-paddingLength-1], nil -} - -// writePacket encrypts and sends a packet of data to the writer argument -func (s *streamPacketCipher) writePacket(seqNum uint32, w io.Writer, rand io.Reader, packet []byte) error { - if len(packet) > maxPacket { - return errors.New("ssh: packet too large") - } - - paddingLength := packetSizeMultiple - (prefixLen+len(packet))%packetSizeMultiple - if paddingLength < 4 { - paddingLength += packetSizeMultiple - } - - length := len(packet) + 1 + paddingLength - binary.BigEndian.PutUint32(s.prefix[:], uint32(length)) - s.prefix[4] = byte(paddingLength) - padding := s.padding[:paddingLength] - if _, err := io.ReadFull(rand, padding); err != nil { - return err - } - - if s.mac != nil { - s.mac.Reset() - binary.BigEndian.PutUint32(s.seqNumBytes[:], seqNum) - s.mac.Write(s.seqNumBytes[:]) - s.mac.Write(s.prefix[:]) - s.mac.Write(packet) - s.mac.Write(padding) - } - - s.cipher.XORKeyStream(s.prefix[:], s.prefix[:]) - s.cipher.XORKeyStream(packet, packet) - s.cipher.XORKeyStream(padding, padding) - - if _, err := w.Write(s.prefix[:]); err != nil { - return err - } - if _, err := w.Write(packet); err != nil { - return err - } - if _, err := w.Write(padding); err != nil { - return err - } - - if s.mac != nil { - s.macResult = s.mac.Sum(s.macResult[:0]) - if _, err := w.Write(s.macResult); err != nil { - return err - } - } - - return nil -} - -type gcmCipher struct { - aead cipher.AEAD - prefix [4]byte - iv []byte - buf []byte -} - -func newGCMCipher(iv, key, macKey []byte) (packetCipher, error) { - c, err := aes.NewCipher(key) - if err != nil { - return nil, err - } - - aead, err := cipher.NewGCM(c) - if err != nil { - return nil, err - } - - return &gcmCipher{ - aead: aead, - iv: iv, - }, nil -} - -const gcmTagSize = 16 - -func (c *gcmCipher) writePacket(seqNum uint32, w io.Writer, rand io.Reader, packet []byte) error { - // Pad out to multiple of 16 bytes. This is different from the - // stream cipher because that encrypts the length too. - padding := byte(packetSizeMultiple - (1+len(packet))%packetSizeMultiple) - if padding < 4 { - padding += packetSizeMultiple - } - - length := uint32(len(packet) + int(padding) + 1) - binary.BigEndian.PutUint32(c.prefix[:], length) - if _, err := w.Write(c.prefix[:]); err != nil { - return err - } - - if cap(c.buf) < int(length) { - c.buf = make([]byte, length) - } else { - c.buf = c.buf[:length] - } - - c.buf[0] = padding - copy(c.buf[1:], packet) - if _, err := io.ReadFull(rand, c.buf[1+len(packet):]); err != nil { - return err - } - c.buf = c.aead.Seal(c.buf[:0], c.iv, c.buf, c.prefix[:]) - if _, err := w.Write(c.buf); err != nil { - return err - } - c.incIV() - - return nil -} - -func (c *gcmCipher) incIV() { - for i := 4 + 7; i >= 4; i-- { - c.iv[i]++ - if c.iv[i] != 0 { - break - } - } -} - -func (c *gcmCipher) readPacket(seqNum uint32, r io.Reader) ([]byte, error) { - if _, err := io.ReadFull(r, c.prefix[:]); err != nil { - return nil, err - } - length := binary.BigEndian.Uint32(c.prefix[:]) - if length > maxPacket { - return nil, errors.New("ssh: max packet length exceeded.") - } - - if cap(c.buf) < int(length+gcmTagSize) { - c.buf = make([]byte, length+gcmTagSize) - } else { - c.buf = c.buf[:length+gcmTagSize] - } - - if _, err := io.ReadFull(r, c.buf); err != nil { - return nil, err - } - - plain, err := c.aead.Open(c.buf[:0], c.iv, c.buf, c.prefix[:]) - if err != nil { - return nil, err - } - c.incIV() - - padding := plain[0] - if padding < 4 || padding >= 20 { - return nil, fmt.Errorf("ssh: illegal padding %d", padding) - } - - if int(padding+1) >= len(plain) { - return nil, fmt.Errorf("ssh: padding %d too large", padding) - } - plain = plain[1 : length-uint32(padding)] - return plain, nil -} - -// cbcCipher implements aes128-cbc cipher defined in RFC 4253 section 6.1 -type cbcCipher struct { - mac hash.Hash - macSize uint32 - decrypter cipher.BlockMode - encrypter cipher.BlockMode - - // The following members are to avoid per-packet allocations. - seqNumBytes [4]byte - packetData []byte - macResult []byte - - // Amount of data we should still read to hide which - // verification error triggered. - oracleCamouflage uint32 -} - -func newCBCCipher(c cipher.Block, iv, key, macKey []byte, algs directionAlgorithms) (packetCipher, error) { - cbc := &cbcCipher{ - mac: macModes[algs.MAC].new(macKey), - decrypter: cipher.NewCBCDecrypter(c, iv), - encrypter: cipher.NewCBCEncrypter(c, iv), - packetData: make([]byte, 1024), - } - if cbc.mac != nil { - cbc.macSize = uint32(cbc.mac.Size()) - } - - return cbc, nil -} - -func newAESCBCCipher(iv, key, macKey []byte, algs directionAlgorithms) (packetCipher, error) { - c, err := aes.NewCipher(key) - if err != nil { - return nil, err - } - - cbc, err := newCBCCipher(c, iv, key, macKey, algs) - if err != nil { - return nil, err - } - - return cbc, nil -} - -func newTripleDESCBCCipher(iv, key, macKey []byte, algs directionAlgorithms) (packetCipher, error) { - c, err := des.NewTripleDESCipher(key) - if err != nil { - return nil, err - } - - cbc, err := newCBCCipher(c, iv, key, macKey, algs) - if err != nil { - return nil, err - } - - return cbc, nil -} - -func maxUInt32(a, b int) uint32 { - if a > b { - return uint32(a) - } - return uint32(b) -} - -const ( - cbcMinPacketSizeMultiple = 8 - cbcMinPacketSize = 16 - cbcMinPaddingSize = 4 -) - -// cbcError represents a verification error that may leak information. -type cbcError string - -func (e cbcError) Error() string { return string(e) } - -func (c *cbcCipher) readPacket(seqNum uint32, r io.Reader) ([]byte, error) { - p, err := c.readPacketLeaky(seqNum, r) - if err != nil { - if _, ok := err.(cbcError); ok { - // Verification error: read a fixed amount of - // data, to make distinguishing between - // failing MAC and failing length check more - // difficult. - io.CopyN(ioutil.Discard, r, int64(c.oracleCamouflage)) - } - } - return p, err -} - -func (c *cbcCipher) readPacketLeaky(seqNum uint32, r io.Reader) ([]byte, error) { - blockSize := c.decrypter.BlockSize() - - // Read the header, which will include some of the subsequent data in the - // case of block ciphers - this is copied back to the payload later. - // How many bytes of payload/padding will be read with this first read. - firstBlockLength := uint32((prefixLen + blockSize - 1) / blockSize * blockSize) - firstBlock := c.packetData[:firstBlockLength] - if _, err := io.ReadFull(r, firstBlock); err != nil { - return nil, err - } - - c.oracleCamouflage = maxPacket + 4 + c.macSize - firstBlockLength - - c.decrypter.CryptBlocks(firstBlock, firstBlock) - length := binary.BigEndian.Uint32(firstBlock[:4]) - if length > maxPacket { - return nil, cbcError("ssh: packet too large") - } - if length+4 < maxUInt32(cbcMinPacketSize, blockSize) { - // The minimum size of a packet is 16 (or the cipher block size, whichever - // is larger) bytes. - return nil, cbcError("ssh: packet too small") - } - // The length of the packet (including the length field but not the MAC) must - // be a multiple of the block size or 8, whichever is larger. - if (length+4)%maxUInt32(cbcMinPacketSizeMultiple, blockSize) != 0 { - return nil, cbcError("ssh: invalid packet length multiple") - } - - paddingLength := uint32(firstBlock[4]) - if paddingLength < cbcMinPaddingSize || length <= paddingLength+1 { - return nil, cbcError("ssh: invalid packet length") - } - - // Positions within the c.packetData buffer: - macStart := 4 + length - paddingStart := macStart - paddingLength - - // Entire packet size, starting before length, ending at end of mac. - entirePacketSize := macStart + c.macSize - - // Ensure c.packetData is large enough for the entire packet data. - if uint32(cap(c.packetData)) < entirePacketSize { - // Still need to upsize and copy, but this should be rare at runtime, only - // on upsizing the packetData buffer. - c.packetData = make([]byte, entirePacketSize) - copy(c.packetData, firstBlock) - } else { - c.packetData = c.packetData[:entirePacketSize] - } - - if n, err := io.ReadFull(r, c.packetData[firstBlockLength:]); err != nil { - return nil, err - } else { - c.oracleCamouflage -= uint32(n) - } - - remainingCrypted := c.packetData[firstBlockLength:macStart] - c.decrypter.CryptBlocks(remainingCrypted, remainingCrypted) - - mac := c.packetData[macStart:] - if c.mac != nil { - c.mac.Reset() - binary.BigEndian.PutUint32(c.seqNumBytes[:], seqNum) - c.mac.Write(c.seqNumBytes[:]) - c.mac.Write(c.packetData[:macStart]) - c.macResult = c.mac.Sum(c.macResult[:0]) - if subtle.ConstantTimeCompare(c.macResult, mac) != 1 { - return nil, cbcError("ssh: MAC failure") - } - } - - return c.packetData[prefixLen:paddingStart], nil -} - -func (c *cbcCipher) writePacket(seqNum uint32, w io.Writer, rand io.Reader, packet []byte) error { - effectiveBlockSize := maxUInt32(cbcMinPacketSizeMultiple, c.encrypter.BlockSize()) - - // Length of encrypted portion of the packet (header, payload, padding). - // Enforce minimum padding and packet size. - encLength := maxUInt32(prefixLen+len(packet)+cbcMinPaddingSize, cbcMinPaddingSize) - // Enforce block size. - encLength = (encLength + effectiveBlockSize - 1) / effectiveBlockSize * effectiveBlockSize - - length := encLength - 4 - paddingLength := int(length) - (1 + len(packet)) - - // Overall buffer contains: header, payload, padding, mac. - // Space for the MAC is reserved in the capacity but not the slice length. - bufferSize := encLength + c.macSize - if uint32(cap(c.packetData)) < bufferSize { - c.packetData = make([]byte, encLength, bufferSize) - } else { - c.packetData = c.packetData[:encLength] - } - - p := c.packetData - - // Packet header. - binary.BigEndian.PutUint32(p, length) - p = p[4:] - p[0] = byte(paddingLength) - - // Payload. - p = p[1:] - copy(p, packet) - - // Padding. - p = p[len(packet):] - if _, err := io.ReadFull(rand, p); err != nil { - return err - } - - if c.mac != nil { - c.mac.Reset() - binary.BigEndian.PutUint32(c.seqNumBytes[:], seqNum) - c.mac.Write(c.seqNumBytes[:]) - c.mac.Write(c.packetData) - // The MAC is now appended into the capacity reserved for it earlier. - c.packetData = c.mac.Sum(c.packetData) - } - - c.encrypter.CryptBlocks(c.packetData[:encLength], c.packetData[:encLength]) - - if _, err := w.Write(c.packetData); err != nil { - return err - } - - return nil -} diff --git a/vendor/golang.org/x/crypto/ssh/cipher_test.go b/vendor/golang.org/x/crypto/ssh/cipher_test.go deleted file mode 100644 index 54b92b6..0000000 --- a/vendor/golang.org/x/crypto/ssh/cipher_test.go +++ /dev/null @@ -1,127 +0,0 @@ -// 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 ssh - -import ( - "bytes" - "crypto" - "crypto/aes" - "crypto/rand" - "testing" -) - -func TestDefaultCiphersExist(t *testing.T) { - for _, cipherAlgo := range supportedCiphers { - if _, ok := cipherModes[cipherAlgo]; !ok { - t.Errorf("default cipher %q is unknown", cipherAlgo) - } - } -} - -func TestPacketCiphers(t *testing.T) { - // Still test aes128cbc cipher althought it's commented out. - cipherModes[aes128cbcID] = &streamCipherMode{16, aes.BlockSize, 0, nil} - defer delete(cipherModes, aes128cbcID) - - for cipher := range cipherModes { - kr := &kexResult{Hash: crypto.SHA1} - algs := directionAlgorithms{ - Cipher: cipher, - MAC: "hmac-sha1", - Compression: "none", - } - client, err := newPacketCipher(clientKeys, algs, kr) - if err != nil { - t.Errorf("newPacketCipher(client, %q): %v", cipher, err) - continue - } - server, err := newPacketCipher(clientKeys, algs, kr) - if err != nil { - t.Errorf("newPacketCipher(client, %q): %v", cipher, err) - continue - } - - want := "bla bla" - input := []byte(want) - buf := &bytes.Buffer{} - if err := client.writePacket(0, buf, rand.Reader, input); err != nil { - t.Errorf("writePacket(%q): %v", cipher, err) - continue - } - - packet, err := server.readPacket(0, buf) - if err != nil { - t.Errorf("readPacket(%q): %v", cipher, err) - continue - } - - if string(packet) != want { - t.Errorf("roundtrip(%q): got %q, want %q", cipher, packet, want) - } - } -} - -func TestCBCOracleCounterMeasure(t *testing.T) { - cipherModes[aes128cbcID] = &streamCipherMode{16, aes.BlockSize, 0, nil} - defer delete(cipherModes, aes128cbcID) - - kr := &kexResult{Hash: crypto.SHA1} - algs := directionAlgorithms{ - Cipher: aes128cbcID, - MAC: "hmac-sha1", - Compression: "none", - } - client, err := newPacketCipher(clientKeys, algs, kr) - if err != nil { - t.Fatalf("newPacketCipher(client): %v", err) - } - - want := "bla bla" - input := []byte(want) - buf := &bytes.Buffer{} - if err := client.writePacket(0, buf, rand.Reader, input); err != nil { - t.Errorf("writePacket: %v", err) - } - - packetSize := buf.Len() - buf.Write(make([]byte, 2*maxPacket)) - - // We corrupt each byte, but this usually will only test the - // 'packet too large' or 'MAC failure' cases. - lastRead := -1 - for i := 0; i < packetSize; i++ { - server, err := newPacketCipher(clientKeys, algs, kr) - if err != nil { - t.Fatalf("newPacketCipher(client): %v", err) - } - - fresh := &bytes.Buffer{} - fresh.Write(buf.Bytes()) - fresh.Bytes()[i] ^= 0x01 - - before := fresh.Len() - _, err = server.readPacket(0, fresh) - if err == nil { - t.Errorf("corrupt byte %d: readPacket succeeded ", i) - continue - } - if _, ok := err.(cbcError); !ok { - t.Errorf("corrupt byte %d: got %v (%T), want cbcError", i, err, err) - continue - } - - after := fresh.Len() - bytesRead := before - after - if bytesRead < maxPacket { - t.Errorf("corrupt byte %d: read %d bytes, want more than %d", i, bytesRead, maxPacket) - continue - } - - if i > 0 && bytesRead != lastRead { - t.Errorf("corrupt byte %d: read %d bytes, want %d bytes read", i, bytesRead, lastRead) - } - lastRead = bytesRead - } -} diff --git a/vendor/golang.org/x/crypto/ssh/client.go b/vendor/golang.org/x/crypto/ssh/client.go deleted file mode 100644 index 0212a20..0000000 --- a/vendor/golang.org/x/crypto/ssh/client.go +++ /dev/null @@ -1,213 +0,0 @@ -// 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 ssh - -import ( - "errors" - "fmt" - "net" - "sync" - "time" -) - -// Client implements a traditional SSH client that supports shells, -// subprocesses, port forwarding and tunneled dialing. -type Client struct { - Conn - - forwards forwardList // forwarded tcpip connections from the remote side - mu sync.Mutex - channelHandlers map[string]chan NewChannel -} - -// HandleChannelOpen returns a channel on which NewChannel requests -// for the given type are sent. If the type already is being handled, -// nil is returned. The channel is closed when the connection is closed. -func (c *Client) HandleChannelOpen(channelType string) <-chan NewChannel { - c.mu.Lock() - defer c.mu.Unlock() - if c.channelHandlers == nil { - // The SSH channel has been closed. - c := make(chan NewChannel) - close(c) - return c - } - - ch := c.channelHandlers[channelType] - if ch != nil { - return nil - } - - ch = make(chan NewChannel, 16) - c.channelHandlers[channelType] = ch - return ch -} - -// NewClient creates a Client on top of the given connection. -func NewClient(c Conn, chans <-chan NewChannel, reqs <-chan *Request) *Client { - conn := &Client{ - Conn: c, - channelHandlers: make(map[string]chan NewChannel, 1), - } - - go conn.handleGlobalRequests(reqs) - go conn.handleChannelOpens(chans) - go func() { - conn.Wait() - conn.forwards.closeAll() - }() - go conn.forwards.handleChannels(conn.HandleChannelOpen("forwarded-tcpip")) - return conn -} - -// NewClientConn establishes an authenticated SSH connection using c -// as the underlying transport. The Request and NewChannel channels -// must be serviced or the connection will hang. -func NewClientConn(c net.Conn, addr string, config *ClientConfig) (Conn, <-chan NewChannel, <-chan *Request, error) { - fullConf := *config - fullConf.SetDefaults() - conn := &connection{ - sshConn: sshConn{conn: c}, - } - - if err := conn.clientHandshake(addr, &fullConf); err != nil { - c.Close() - return nil, nil, nil, fmt.Errorf("ssh: handshake failed: %v", err) - } - conn.mux = newMux(conn.transport) - return conn, conn.mux.incomingChannels, conn.mux.incomingRequests, nil -} - -// clientHandshake performs the client side key exchange. See RFC 4253 Section -// 7. -func (c *connection) clientHandshake(dialAddress string, config *ClientConfig) error { - if config.ClientVersion != "" { - c.clientVersion = []byte(config.ClientVersion) - } else { - c.clientVersion = []byte(packageVersion) - } - var err error - c.serverVersion, err = exchangeVersions(c.sshConn.conn, c.clientVersion) - if err != nil { - return err - } - - c.transport = newClientTransport( - newTransport(c.sshConn.conn, config.Rand, true /* is client */), - c.clientVersion, c.serverVersion, config, dialAddress, c.sshConn.RemoteAddr()) - if err := c.transport.requestInitialKeyChange(); err != nil { - return err - } - - // We just did the key change, so the session ID is established. - c.sessionID = c.transport.getSessionID() - - return c.clientAuthenticate(config) -} - -// verifyHostKeySignature verifies the host key obtained in the key -// exchange. -func verifyHostKeySignature(hostKey PublicKey, result *kexResult) error { - sig, rest, ok := parseSignatureBody(result.Signature) - if len(rest) > 0 || !ok { - return errors.New("ssh: signature parse error") - } - - return hostKey.Verify(result.H, sig) -} - -// NewSession opens a new Session for this client. (A session is a remote -// execution of a program.) -func (c *Client) NewSession() (*Session, error) { - ch, in, err := c.OpenChannel("session", nil) - if err != nil { - return nil, err - } - return newSession(ch, in) -} - -func (c *Client) handleGlobalRequests(incoming <-chan *Request) { - for r := range incoming { - // This handles keepalive messages and matches - // the behaviour of OpenSSH. - r.Reply(false, nil) - } -} - -// handleChannelOpens channel open messages from the remote side. -func (c *Client) handleChannelOpens(in <-chan NewChannel) { - for ch := range in { - c.mu.Lock() - handler := c.channelHandlers[ch.ChannelType()] - c.mu.Unlock() - - if handler != nil { - handler <- ch - } else { - ch.Reject(UnknownChannelType, fmt.Sprintf("unknown channel type: %v", ch.ChannelType())) - } - } - - c.mu.Lock() - for _, ch := range c.channelHandlers { - close(ch) - } - c.channelHandlers = nil - c.mu.Unlock() -} - -// Dial starts a client connection to the given SSH server. It is a -// convenience function that connects to the given network address, -// initiates the SSH handshake, and then sets up a Client. For access -// to incoming channels and requests, use net.Dial with NewClientConn -// instead. -func Dial(network, addr string, config *ClientConfig) (*Client, error) { - conn, err := net.DialTimeout(network, addr, config.Timeout) - if err != nil { - return nil, err - } - c, chans, reqs, err := NewClientConn(conn, addr, config) - if err != nil { - return nil, err - } - return NewClient(c, chans, reqs), nil -} - -// A ClientConfig structure is used to configure a Client. It must not be -// modified after having been passed to an SSH function. -type ClientConfig struct { - // Config contains configuration that is shared between clients and - // servers. - Config - - // User contains the username to authenticate as. - User string - - // Auth contains possible authentication methods to use with the - // server. Only the first instance of a particular RFC 4252 method will - // be used during authentication. - Auth []AuthMethod - - // HostKeyCallback, if not nil, is called during the cryptographic - // handshake to validate the server's host key. A nil HostKeyCallback - // implies that all host keys are accepted. - HostKeyCallback func(hostname string, remote net.Addr, key PublicKey) error - - // ClientVersion contains the version identification string that will - // 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 - // 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. - HostKeyAlgorithms []string - - // Timeout is the maximum amount of time for the TCP connection to establish. - // - // A Timeout of zero means no timeout. - Timeout time.Duration -} diff --git a/vendor/golang.org/x/crypto/ssh/client_auth.go b/vendor/golang.org/x/crypto/ssh/client_auth.go deleted file mode 100644 index 294af0d..0000000 --- a/vendor/golang.org/x/crypto/ssh/client_auth.go +++ /dev/null @@ -1,473 +0,0 @@ -// 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 ssh - -import ( - "bytes" - "errors" - "fmt" - "io" -) - -// clientAuthenticate authenticates with the remote server. See RFC 4252. -func (c *connection) clientAuthenticate(config *ClientConfig) error { - // initiate user auth session - if err := c.transport.writePacket(Marshal(&serviceRequestMsg{serviceUserAuth})); err != nil { - return err - } - packet, err := c.transport.readPacket() - if err != nil { - return err - } - var serviceAccept serviceAcceptMsg - if err := Unmarshal(packet, &serviceAccept); err != nil { - return err - } - - // during the authentication phase the client first attempts the "none" method - // then any untried methods suggested by the server. - tried := make(map[string]bool) - var lastMethods []string - for auth := AuthMethod(new(noneAuth)); auth != nil; { - ok, methods, err := auth.auth(c.transport.getSessionID(), config.User, c.transport, config.Rand) - if err != nil { - return err - } - if ok { - // success - return nil - } - tried[auth.method()] = true - if methods == nil { - methods = lastMethods - } - lastMethods = methods - - auth = nil - - findNext: - for _, a := range config.Auth { - candidateMethod := a.method() - if tried[candidateMethod] { - continue - } - for _, meth := range methods { - if meth == candidateMethod { - auth = a - break findNext - } - } - } - } - return fmt.Errorf("ssh: unable to authenticate, attempted methods %v, no supported methods remain", keys(tried)) -} - -func keys(m map[string]bool) []string { - s := make([]string, 0, len(m)) - - for key := range m { - s = append(s, key) - } - return s -} - -// An AuthMethod represents an instance of an RFC 4252 authentication method. -type AuthMethod interface { - // auth authenticates user over transport t. - // Returns true if authentication is successful. - // 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) (bool, []string, error) - - // method returns the RFC 4252 method name. - method() string -} - -// "none" authentication, RFC 4252 section 5.2. -type noneAuth int - -func (n *noneAuth) auth(session []byte, user string, c packetConn, rand io.Reader) (bool, []string, error) { - if err := c.writePacket(Marshal(&userAuthRequestMsg{ - User: user, - Service: serviceSSH, - Method: "none", - })); err != nil { - return false, nil, err - } - - return handleAuthResponse(c) -} - -func (n *noneAuth) method() string { - return "none" -} - -// passwordCallback is an AuthMethod that fetches the password through -// 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) (bool, []string, error) { - type passwordAuthMsg struct { - User string `sshtype:"50"` - Service string - Method string - Reply bool - Password string - } - - pw, err := cb() - // REVIEW NOTE: is there a need to support skipping a password attempt? - // The program may only find out that the user doesn't have a password - // when prompting. - if err != nil { - return false, nil, err - } - - if err := c.writePacket(Marshal(&passwordAuthMsg{ - User: user, - Service: serviceSSH, - Method: cb.method(), - Reply: false, - Password: pw, - })); err != nil { - return false, nil, err - } - - return handleAuthResponse(c) -} - -func (cb passwordCallback) method() string { - return "password" -} - -// Password returns an AuthMethod using the given password. -func Password(secret string) AuthMethod { - return passwordCallback(func() (string, error) { return secret, nil }) -} - -// PasswordCallback returns an AuthMethod that uses a callback for -// fetching a password. -func PasswordCallback(prompt func() (secret string, err error)) AuthMethod { - return passwordCallback(prompt) -} - -type publickeyAuthMsg struct { - User string `sshtype:"50"` - Service string - Method string - // HasSig indicates to the receiver packet that the auth request is signed and - // should be used for authentication of the request. - HasSig bool - Algoname string - PubKey []byte - // Sig is tagged with "rest" so Marshal will exclude it during - // validateKey - Sig []byte `ssh:"rest"` -} - -// publicKeyCallback is an AuthMethod that uses a set of key -// pairs for authentication. -type publicKeyCallback func() ([]Signer, error) - -func (cb publicKeyCallback) method() string { - return "publickey" -} - -func (cb publicKeyCallback) auth(session []byte, user string, c packetConn, rand io.Reader) (bool, []string, error) { - // Authentication is performed in two stages. The first stage sends an - // enquiry to test if each key is acceptable to the remote. The second - // stage attempts to authenticate with the valid keys obtained in the - // first stage. - - signers, err := cb() - if err != nil { - return false, nil, err - } - var validKeys []Signer - for _, signer := range signers { - if ok, err := validateKey(signer.PublicKey(), user, c); ok { - validKeys = append(validKeys, signer) - } else { - if err != nil { - return false, nil, err - } - } - } - - // methods that may continue if this auth is not successful. - var methods []string - for _, signer := range validKeys { - pub := signer.PublicKey() - - pubKey := pub.Marshal() - sign, err := signer.Sign(rand, buildDataSignedForAuth(session, userAuthRequestMsg{ - User: user, - Service: serviceSSH, - Method: cb.method(), - }, []byte(pub.Type()), pubKey)) - if err != nil { - return false, nil, err - } - - // manually wrap the serialized signature in a string - s := Marshal(sign) - sig := make([]byte, stringLength(len(s))) - marshalString(sig, s) - msg := publickeyAuthMsg{ - User: user, - Service: serviceSSH, - Method: cb.method(), - HasSig: true, - Algoname: pub.Type(), - PubKey: pubKey, - Sig: sig, - } - p := Marshal(&msg) - if err := c.writePacket(p); err != nil { - return false, nil, err - } - var success bool - success, methods, err = handleAuthResponse(c) - if err != nil { - return false, nil, err - } - if success { - return success, methods, err - } - } - return false, methods, nil -} - -// validateKey validates the key provided is acceptable to the server. -func validateKey(key PublicKey, user string, c packetConn) (bool, error) { - pubKey := key.Marshal() - msg := publickeyAuthMsg{ - User: user, - Service: serviceSSH, - Method: "publickey", - HasSig: false, - Algoname: key.Type(), - PubKey: pubKey, - } - if err := c.writePacket(Marshal(&msg)); err != nil { - return false, err - } - - return confirmKeyAck(key, c) -} - -func confirmKeyAck(key PublicKey, c packetConn) (bool, error) { - pubKey := key.Marshal() - algoname := key.Type() - - for { - packet, err := c.readPacket() - if err != nil { - return false, err - } - switch packet[0] { - case msgUserAuthBanner: - // TODO(gpaul): add callback to present the banner to the user - case msgUserAuthPubKeyOk: - var msg userAuthPubKeyOkMsg - if err := Unmarshal(packet, &msg); err != nil { - return false, err - } - if msg.Algo != algoname || !bytes.Equal(msg.PubKey, pubKey) { - return false, nil - } - return true, nil - case msgUserAuthFailure: - return false, nil - default: - return false, unexpectedMessageError(msgUserAuthSuccess, packet[0]) - } - } -} - -// PublicKeys returns an AuthMethod that uses the given key -// pairs. -func PublicKeys(signers ...Signer) AuthMethod { - return publicKeyCallback(func() ([]Signer, error) { return signers, nil }) -} - -// PublicKeysCallback returns an AuthMethod that runs the given -// function to obtain a list of key pairs. -func PublicKeysCallback(getSigners func() (signers []Signer, err error)) AuthMethod { - return publicKeyCallback(getSigners) -} - -// handleAuthResponse returns whether the preceding authentication request succeeded -// along with a list of remaining authentication methods to try next and -// an error if an unexpected response was received. -func handleAuthResponse(c packetConn) (bool, []string, error) { - for { - packet, err := c.readPacket() - if err != nil { - return false, nil, err - } - - switch packet[0] { - case msgUserAuthBanner: - // TODO: add callback to present the banner to the user - case msgUserAuthFailure: - var msg userAuthFailureMsg - if err := Unmarshal(packet, &msg); err != nil { - return false, nil, err - } - return false, msg.Methods, nil - case msgUserAuthSuccess: - return true, nil, nil - default: - return false, nil, unexpectedMessageError(msgUserAuthSuccess, packet[0]) - } - } -} - -// KeyboardInteractiveChallenge should print questions, optionally -// 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 -// 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) - -// KeyboardInteractive returns a AuthMethod using a prompt/response -// sequence controlled by the server. -func KeyboardInteractive(challenge KeyboardInteractiveChallenge) AuthMethod { - return challenge -} - -func (cb KeyboardInteractiveChallenge) method() string { - return "keyboard-interactive" -} - -func (cb KeyboardInteractiveChallenge) auth(session []byte, user string, c packetConn, rand io.Reader) (bool, []string, error) { - type initiateMsg struct { - User string `sshtype:"50"` - Service string - Method string - Language string - Submethods string - } - - if err := c.writePacket(Marshal(&initiateMsg{ - User: user, - Service: serviceSSH, - Method: "keyboard-interactive", - })); err != nil { - return false, nil, err - } - - for { - packet, err := c.readPacket() - if err != nil { - return false, nil, err - } - - // like handleAuthResponse, but with less options. - switch packet[0] { - case msgUserAuthBanner: - // TODO: Print banners during userauth. - continue - case msgUserAuthInfoRequest: - // OK - case msgUserAuthFailure: - var msg userAuthFailureMsg - if err := Unmarshal(packet, &msg); err != nil { - return false, nil, err - } - return false, msg.Methods, nil - case msgUserAuthSuccess: - return true, nil, nil - default: - return false, nil, unexpectedMessageError(msgUserAuthInfoRequest, packet[0]) - } - - var msg userAuthInfoRequestMsg - if err := Unmarshal(packet, &msg); err != nil { - return false, nil, err - } - - // Manually unpack the prompt/echo pairs. - rest := msg.Prompts - var prompts []string - var echos []bool - for i := 0; i < int(msg.NumPrompts); i++ { - prompt, r, ok := parseString(rest) - if !ok || len(r) == 0 { - return false, nil, errors.New("ssh: prompt format error") - } - prompts = append(prompts, string(prompt)) - echos = append(echos, r[0] != 0) - rest = r[1:] - } - - if len(rest) != 0 { - return false, nil, errors.New("ssh: extra data following keyboard-interactive pairs") - } - - answers, err := cb(msg.User, msg.Instruction, prompts, echos) - if err != nil { - return false, nil, err - } - - if len(answers) != len(prompts) { - return false, nil, errors.New("ssh: not enough answers from keyboard-interactive callback") - } - responseLength := 1 + 4 - for _, a := range answers { - responseLength += stringLength(len(a)) - } - serialized := make([]byte, responseLength) - p := serialized - p[0] = msgUserAuthInfoResponse - p = p[1:] - p = marshalUint32(p, uint32(len(answers))) - for _, a := range answers { - p = marshalString(p, []byte(a)) - } - - if err := c.writePacket(serialized); err != nil { - return false, nil, err - } - } -} - -type retryableAuthMethod struct { - authMethod AuthMethod - maxTries int -} - -func (r *retryableAuthMethod) auth(session []byte, user string, c packetConn, rand io.Reader) (ok bool, methods []string, err error) { - for i := 0; r.maxTries <= 0 || i < r.maxTries; i++ { - ok, methods, err = r.authMethod.auth(session, user, c, rand) - if ok || err != nil { // either success or error terminate - return ok, methods, err - } - } - return ok, methods, err -} - -func (r *retryableAuthMethod) method() string { - return r.authMethod.method() -} - -// RetryableAuthMethod is a decorator for other auth methods enabling them to -// be retried up to maxTries before considering that AuthMethod itself failed. -// If maxTries is <= 0, will retry indefinitely -// -// This is useful for interactive clients using challenge/response type -// authentication (e.g. Keyboard-Interactive, Password, etc) where the user -// could mistype their response resulting in the server issuing a -// SSH_MSG_USERAUTH_FAILURE (rfc4252 #8 [password] and rfc4256 #3.4 -// [keyboard-interactive]); Without this decorator, the non-retryable -// AuthMethod would be removed from future consideration, and never tried again -// (and so the user would never be able to retry their entry). -func RetryableAuthMethod(auth AuthMethod, maxTries int) AuthMethod { - return &retryableAuthMethod{authMethod: auth, maxTries: maxTries} -} diff --git a/vendor/golang.org/x/crypto/ssh/client_auth_test.go b/vendor/golang.org/x/crypto/ssh/client_auth_test.go deleted file mode 100644 index 2fa3103..0000000 --- a/vendor/golang.org/x/crypto/ssh/client_auth_test.go +++ /dev/null @@ -1,439 +0,0 @@ -// 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 ssh - -import ( - "bytes" - "crypto/rand" - "errors" - "fmt" - "strings" - "testing" -) - -type keyboardInteractive map[string]string - -func (cr keyboardInteractive) Challenge(user string, instruction string, questions []string, echos []bool) ([]string, error) { - var answers []string - for _, q := range questions { - answers = append(answers, cr[q]) - } - return answers, nil -} - -// reused internally by tests -var clientPassword = "tiger" - -// tryAuth runs a handshake with a given config against an SSH server -// with config serverConfig -func tryAuth(t *testing.T, config *ClientConfig) error { - c1, c2, err := netPipe() - if err != nil { - t.Fatalf("netPipe: %v", err) - } - defer c1.Close() - defer c2.Close() - - certChecker := CertChecker{ - IsAuthority: func(k PublicKey) bool { - return bytes.Equal(k.Marshal(), testPublicKeys["ecdsa"].Marshal()) - }, - UserKeyFallback: func(conn ConnMetadata, key PublicKey) (*Permissions, error) { - if conn.User() == "testuser" && bytes.Equal(key.Marshal(), testPublicKeys["rsa"].Marshal()) { - return nil, nil - } - - return nil, fmt.Errorf("pubkey for %q not acceptable", conn.User()) - }, - IsRevoked: func(c *Certificate) bool { - return c.Serial == 666 - }, - } - - serverConfig := &ServerConfig{ - PasswordCallback: func(conn ConnMetadata, pass []byte) (*Permissions, error) { - if conn.User() == "testuser" && string(pass) == clientPassword { - return nil, nil - } - return nil, errors.New("password auth failed") - }, - PublicKeyCallback: certChecker.Authenticate, - KeyboardInteractiveCallback: func(conn ConnMetadata, challenge KeyboardInteractiveChallenge) (*Permissions, error) { - ans, err := challenge("user", - "instruction", - []string{"question1", "question2"}, - []bool{true, true}) - if err != nil { - return nil, err - } - ok := conn.User() == "testuser" && ans[0] == "answer1" && ans[1] == "answer2" - if ok { - challenge("user", "motd", nil, nil) - return nil, nil - } - return nil, errors.New("keyboard-interactive failed") - }, - AuthLogCallback: func(conn ConnMetadata, method string, err error) { - t.Logf("user %q, method %q: %v", conn.User(), method, err) - }, - } - serverConfig.AddHostKey(testSigners["rsa"]) - - go newServer(c1, serverConfig) - _, _, _, err = NewClientConn(c2, "", config) - return err -} - -func TestClientAuthPublicKey(t *testing.T) { - config := &ClientConfig{ - User: "testuser", - Auth: []AuthMethod{ - PublicKeys(testSigners["rsa"]), - }, - } - if err := tryAuth(t, config); err != nil { - t.Fatalf("unable to dial remote side: %s", err) - } -} - -func TestAuthMethodPassword(t *testing.T) { - config := &ClientConfig{ - User: "testuser", - Auth: []AuthMethod{ - Password(clientPassword), - }, - } - - if err := tryAuth(t, config); err != nil { - t.Fatalf("unable to dial remote side: %s", err) - } -} - -func TestAuthMethodFallback(t *testing.T) { - var passwordCalled bool - config := &ClientConfig{ - User: "testuser", - Auth: []AuthMethod{ - PublicKeys(testSigners["rsa"]), - PasswordCallback( - func() (string, error) { - passwordCalled = true - return "WRONG", nil - }), - }, - } - - if err := tryAuth(t, config); err != nil { - t.Fatalf("unable to dial remote side: %s", err) - } - - if passwordCalled { - t.Errorf("password auth tried before public-key auth.") - } -} - -func TestAuthMethodWrongPassword(t *testing.T) { - config := &ClientConfig{ - User: "testuser", - Auth: []AuthMethod{ - Password("wrong"), - PublicKeys(testSigners["rsa"]), - }, - } - - if err := tryAuth(t, config); err != nil { - t.Fatalf("unable to dial remote side: %s", err) - } -} - -func TestAuthMethodKeyboardInteractive(t *testing.T) { - answers := keyboardInteractive(map[string]string{ - "question1": "answer1", - "question2": "answer2", - }) - config := &ClientConfig{ - User: "testuser", - Auth: []AuthMethod{ - KeyboardInteractive(answers.Challenge), - }, - } - - if err := tryAuth(t, config); err != nil { - t.Fatalf("unable to dial remote side: %s", err) - } -} - -func TestAuthMethodWrongKeyboardInteractive(t *testing.T) { - answers := keyboardInteractive(map[string]string{ - "question1": "answer1", - "question2": "WRONG", - }) - config := &ClientConfig{ - User: "testuser", - Auth: []AuthMethod{ - KeyboardInteractive(answers.Challenge), - }, - } - - if err := tryAuth(t, config); err == nil { - t.Fatalf("wrong answers should not have authenticated with KeyboardInteractive") - } -} - -// the mock server will only authenticate ssh-rsa keys -func TestAuthMethodInvalidPublicKey(t *testing.T) { - config := &ClientConfig{ - User: "testuser", - Auth: []AuthMethod{ - PublicKeys(testSigners["dsa"]), - }, - } - - if err := tryAuth(t, config); err == nil { - t.Fatalf("dsa private key should not have authenticated with rsa public key") - } -} - -// the client should authenticate with the second key -func TestAuthMethodRSAandDSA(t *testing.T) { - config := &ClientConfig{ - User: "testuser", - Auth: []AuthMethod{ - PublicKeys(testSigners["dsa"], testSigners["rsa"]), - }, - } - if err := tryAuth(t, config); err != nil { - t.Fatalf("client could not authenticate with rsa key: %v", err) - } -} - -func TestClientHMAC(t *testing.T) { - for _, mac := range supportedMACs { - config := &ClientConfig{ - User: "testuser", - Auth: []AuthMethod{ - PublicKeys(testSigners["rsa"]), - }, - Config: Config{ - MACs: []string{mac}, - }, - } - if err := tryAuth(t, config); err != nil { - t.Fatalf("client could not authenticate with mac algo %s: %v", mac, err) - } - } -} - -// issue 4285. -func TestClientUnsupportedCipher(t *testing.T) { - config := &ClientConfig{ - User: "testuser", - Auth: []AuthMethod{ - PublicKeys(), - }, - Config: Config{ - Ciphers: []string{"aes128-cbc"}, // not currently supported - }, - } - if err := tryAuth(t, config); err == nil { - t.Errorf("expected no ciphers in common") - } -} - -func TestClientUnsupportedKex(t *testing.T) { - config := &ClientConfig{ - User: "testuser", - Auth: []AuthMethod{ - PublicKeys(), - }, - Config: Config{ - KeyExchanges: []string{"diffie-hellman-group-exchange-sha256"}, // not currently supported - }, - } - if err := tryAuth(t, config); err == nil || !strings.Contains(err.Error(), "common algorithm") { - t.Errorf("got %v, expected 'common algorithm'", err) - } -} - -func TestClientLoginCert(t *testing.T) { - cert := &Certificate{ - Key: testPublicKeys["rsa"], - ValidBefore: CertTimeInfinity, - CertType: UserCert, - } - cert.SignCert(rand.Reader, testSigners["ecdsa"]) - certSigner, err := NewCertSigner(cert, testSigners["rsa"]) - if err != nil { - t.Fatalf("NewCertSigner: %v", err) - } - - clientConfig := &ClientConfig{ - User: "user", - } - clientConfig.Auth = append(clientConfig.Auth, PublicKeys(certSigner)) - - t.Log("should succeed") - if err := tryAuth(t, clientConfig); err != nil { - t.Errorf("cert login failed: %v", err) - } - - t.Log("corrupted signature") - cert.Signature.Blob[0]++ - if err := tryAuth(t, clientConfig); err == nil { - t.Errorf("cert login passed with corrupted sig") - } - - t.Log("revoked") - cert.Serial = 666 - cert.SignCert(rand.Reader, testSigners["ecdsa"]) - if err := tryAuth(t, clientConfig); err == nil { - t.Errorf("revoked cert login succeeded") - } - cert.Serial = 1 - - t.Log("sign with wrong key") - cert.SignCert(rand.Reader, testSigners["dsa"]) - if err := tryAuth(t, clientConfig); err == nil { - t.Errorf("cert login passed with non-authoritive key") - } - - t.Log("host cert") - cert.CertType = HostCert - cert.SignCert(rand.Reader, testSigners["ecdsa"]) - if err := tryAuth(t, clientConfig); err == nil { - t.Errorf("cert login passed with wrong type") - } - cert.CertType = UserCert - - t.Log("principal specified") - cert.ValidPrincipals = []string{"user"} - cert.SignCert(rand.Reader, testSigners["ecdsa"]) - if err := tryAuth(t, clientConfig); err != nil { - t.Errorf("cert login failed: %v", err) - } - - t.Log("wrong principal specified") - cert.ValidPrincipals = []string{"fred"} - cert.SignCert(rand.Reader, testSigners["ecdsa"]) - if err := tryAuth(t, clientConfig); err == nil { - t.Errorf("cert login passed with wrong principal") - } - cert.ValidPrincipals = nil - - t.Log("added critical option") - cert.CriticalOptions = map[string]string{"root-access": "yes"} - cert.SignCert(rand.Reader, testSigners["ecdsa"]) - if err := tryAuth(t, clientConfig); err == nil { - t.Errorf("cert login passed with unrecognized critical option") - } - - t.Log("allowed source address") - cert.CriticalOptions = map[string]string{"source-address": "127.0.0.42/24"} - cert.SignCert(rand.Reader, testSigners["ecdsa"]) - if err := tryAuth(t, clientConfig); err != nil { - t.Errorf("cert login with source-address failed: %v", err) - } - - t.Log("disallowed source address") - cert.CriticalOptions = map[string]string{"source-address": "127.0.0.42"} - cert.SignCert(rand.Reader, testSigners["ecdsa"]) - if err := tryAuth(t, clientConfig); err == nil { - t.Errorf("cert login with source-address succeeded") - } -} - -func testPermissionsPassing(withPermissions bool, t *testing.T) { - serverConfig := &ServerConfig{ - PublicKeyCallback: func(conn ConnMetadata, key PublicKey) (*Permissions, error) { - if conn.User() == "nopermissions" { - return nil, nil - } else { - return &Permissions{}, nil - } - }, - } - serverConfig.AddHostKey(testSigners["rsa"]) - - clientConfig := &ClientConfig{ - Auth: []AuthMethod{ - PublicKeys(testSigners["rsa"]), - }, - } - if withPermissions { - clientConfig.User = "permissions" - } else { - clientConfig.User = "nopermissions" - } - - c1, c2, err := netPipe() - if err != nil { - t.Fatalf("netPipe: %v", err) - } - defer c1.Close() - defer c2.Close() - - go NewClientConn(c2, "", clientConfig) - serverConn, err := newServer(c1, serverConfig) - if err != nil { - t.Fatal(err) - } - if p := serverConn.Permissions; (p != nil) != withPermissions { - t.Fatalf("withPermissions is %t, but Permissions object is %#v", withPermissions, p) - } -} - -func TestPermissionsPassing(t *testing.T) { - testPermissionsPassing(true, t) -} - -func TestNoPermissionsPassing(t *testing.T) { - testPermissionsPassing(false, t) -} - -func TestRetryableAuth(t *testing.T) { - n := 0 - passwords := []string{"WRONG1", "WRONG2"} - - config := &ClientConfig{ - User: "testuser", - Auth: []AuthMethod{ - RetryableAuthMethod(PasswordCallback(func() (string, error) { - p := passwords[n] - n++ - return p, nil - }), 2), - PublicKeys(testSigners["rsa"]), - }, - } - - if err := tryAuth(t, config); err != nil { - t.Fatalf("unable to dial remote side: %s", err) - } - if n != 2 { - t.Fatalf("Did not try all passwords") - } -} - -func ExampleRetryableAuthMethod(t *testing.T) { - user := "testuser" - NumberOfPrompts := 3 - - // Normally this would be a callback that prompts the user to answer the - // provided questions - Cb := func(user, instruction string, questions []string, echos []bool) (answers []string, err error) { - return []string{"answer1", "answer2"}, nil - } - - config := &ClientConfig{ - User: user, - Auth: []AuthMethod{ - RetryableAuthMethod(KeyboardInteractiveChallenge(Cb), NumberOfPrompts), - }, - } - - if err := tryAuth(t, config); err != nil { - t.Fatalf("unable to dial remote side: %s", err) - } -} diff --git a/vendor/golang.org/x/crypto/ssh/client_test.go b/vendor/golang.org/x/crypto/ssh/client_test.go deleted file mode 100644 index 1fe790c..0000000 --- a/vendor/golang.org/x/crypto/ssh/client_test.go +++ /dev/null @@ -1,39 +0,0 @@ -// 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 ssh - -import ( - "net" - "testing" -) - -func testClientVersion(t *testing.T, config *ClientConfig, expected string) { - clientConn, serverConn := net.Pipe() - defer clientConn.Close() - receivedVersion := make(chan string, 1) - go func() { - version, err := readVersion(serverConn) - if err != nil { - receivedVersion <- "" - } else { - receivedVersion <- string(version) - } - serverConn.Close() - }() - NewClientConn(clientConn, "", config) - actual := <-receivedVersion - if actual != expected { - t.Fatalf("got %s; want %s", actual, expected) - } -} - -func TestCustomClientVersion(t *testing.T) { - version := "Test-Client-Version-0.0" - testClientVersion(t, &ClientConfig{ClientVersion: version}, version) -} - -func TestDefaultClientVersion(t *testing.T) { - testClientVersion(t, &ClientConfig{}, packageVersion) -} diff --git a/vendor/golang.org/x/crypto/ssh/common.go b/vendor/golang.org/x/crypto/ssh/common.go deleted file mode 100644 index de029d6..0000000 --- a/vendor/golang.org/x/crypto/ssh/common.go +++ /dev/null @@ -1,356 +0,0 @@ -// 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 ssh - -import ( - "crypto" - "crypto/rand" - "fmt" - "io" - "sync" - - _ "crypto/sha1" - _ "crypto/sha256" - _ "crypto/sha512" -) - -// These are string constants in the SSH protocol. -const ( - compressionNone = "none" - serviceUserAuth = "ssh-userauth" - serviceSSH = "ssh-connection" -) - -// supportedCiphers specifies the supported ciphers in preference order. -var supportedCiphers = []string{ - "aes128-ctr", "aes192-ctr", "aes256-ctr", - "aes128-gcm@openssh.com", - "arcfour256", "arcfour128", -} - -// supportedKexAlgos specifies the supported key-exchange algorithms in -// preference order. -var supportedKexAlgos = []string{ - kexAlgoCurve25519SHA256, - // 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, -} - -// supportedKexAlgos specifies the supported host-key algorithms (i.e. methods -// of authenticating servers) in preference order. -var supportedHostKeyAlgos = []string{ - CertAlgoRSAv01, CertAlgoDSAv01, CertAlgoECDSA256v01, - CertAlgoECDSA384v01, CertAlgoECDSA521v01, - - KeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoECDSA521, - KeyAlgoRSA, KeyAlgoDSA, - - KeyAlgoED25519, -} - -// supportedMACs specifies a default set of MAC algorithms in preference order. -// This is based on RFC 4253, section 6.4, but with hmac-md5 variants removed -// because they have reached the end of their useful life. -var supportedMACs = []string{ - "hmac-sha2-256", "hmac-sha1", "hmac-sha1-96", -} - -var supportedCompressions = []string{compressionNone} - -// hashFuncs keeps the mapping of supported algorithms to their respective -// hashes needed for signature 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, -} - -// unexpectedMessageError results when the SSH message that we received didn't -// match what we wanted. -func unexpectedMessageError(expected, got uint8) error { - return fmt.Errorf("ssh: unexpected message type %d (expected %d)", got, expected) -} - -// parseError results from a malformed SSH message. -func parseError(tag uint8) error { - return fmt.Errorf("ssh: parse error in message type %d", tag) -} - -func findCommon(what string, client []string, server []string) (common string, err error) { - for _, c := range client { - for _, s := range server { - if c == s { - return c, nil - } - } - } - return "", fmt.Errorf("ssh: no common algorithm for %s; client offered: %v, server offered: %v", what, client, server) -} - -type directionAlgorithms struct { - Cipher string - MAC string - Compression string -} - -type algorithms struct { - kex string - hostKey string - w directionAlgorithms - r directionAlgorithms -} - -func findAgreedAlgorithms(clientKexInit, serverKexInit *kexInitMsg) (algs *algorithms, err error) { - result := &algorithms{} - - result.kex, err = findCommon("key exchange", clientKexInit.KexAlgos, serverKexInit.KexAlgos) - if err != nil { - return - } - - result.hostKey, err = findCommon("host key", clientKexInit.ServerHostKeyAlgos, serverKexInit.ServerHostKeyAlgos) - if err != nil { - return - } - - result.w.Cipher, err = findCommon("client to server cipher", clientKexInit.CiphersClientServer, serverKexInit.CiphersClientServer) - if err != nil { - return - } - - result.r.Cipher, err = findCommon("server to client cipher", clientKexInit.CiphersServerClient, serverKexInit.CiphersServerClient) - if err != nil { - return - } - - result.w.MAC, err = findCommon("client to server MAC", clientKexInit.MACsClientServer, serverKexInit.MACsClientServer) - if err != nil { - return - } - - result.r.MAC, err = findCommon("server to client MAC", clientKexInit.MACsServerClient, serverKexInit.MACsServerClient) - if err != nil { - return - } - - result.w.Compression, err = findCommon("client to server compression", clientKexInit.CompressionClientServer, serverKexInit.CompressionClientServer) - if err != nil { - return - } - - result.r.Compression, err = findCommon("server to client compression", clientKexInit.CompressionServerClient, serverKexInit.CompressionServerClient) - if err != nil { - return - } - - return result, nil -} - -// If rekeythreshold is too small, we can't make any progress sending -// stuff. -const minRekeyThreshold uint64 = 256 - -// Config contains configuration data common to both ServerConfig and -// ClientConfig. -type Config struct { - // Rand provides the source of entropy for cryptographic - // primitives. If Rand is nil, the cryptographic random reader - // in package crypto/rand will be used. - Rand io.Reader - - // The maximum number of bytes sent or received after which a - // new key is negotiated. It must be at least 256. If - // unspecified, 1 gigabyte is used. - RekeyThreshold uint64 - - // The allowed key exchanges algorithms. If unspecified then a - // default set of algorithms is used. - KeyExchanges []string - - // The allowed cipher algorithms. If unspecified then a sensible - // default is used. - Ciphers []string - - // The allowed MAC algorithms. If unspecified then a sensible default - // is used. - MACs []string -} - -// SetDefaults sets sensible values for unset fields in config. This is -// exported for testing: Configs passed to SSH functions are copied and have -// default values set automatically. -func (c *Config) SetDefaults() { - if c.Rand == nil { - c.Rand = rand.Reader - } - if c.Ciphers == nil { - c.Ciphers = supportedCiphers - } - var ciphers []string - for _, c := range c.Ciphers { - if cipherModes[c] != nil { - // reject the cipher if we have no cipherModes definition - ciphers = append(ciphers, c) - } - } - c.Ciphers = ciphers - - if c.KeyExchanges == nil { - c.KeyExchanges = supportedKexAlgos - } - - if c.MACs == nil { - c.MACs = supportedMACs - } - - if c.RekeyThreshold == 0 { - // RFC 4253, section 9 suggests rekeying after 1G. - c.RekeyThreshold = 1 << 30 - } - if c.RekeyThreshold < minRekeyThreshold { - c.RekeyThreshold = minRekeyThreshold - } -} - -// 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 { - data := struct { - Session []byte - Type byte - User string - Service string - Method string - Sign bool - Algo []byte - PubKey []byte - }{ - sessionId, - msgUserAuthRequest, - req.User, - req.Service, - req.Method, - true, - algo, - pubKey, - } - return Marshal(data) -} - -func appendU16(buf []byte, n uint16) []byte { - return append(buf, byte(n>>8), byte(n)) -} - -func appendU32(buf []byte, n uint32) []byte { - return append(buf, byte(n>>24), byte(n>>16), byte(n>>8), byte(n)) -} - -func appendU64(buf []byte, n uint64) []byte { - return append(buf, - byte(n>>56), byte(n>>48), byte(n>>40), byte(n>>32), - byte(n>>24), byte(n>>16), byte(n>>8), byte(n)) -} - -func appendInt(buf []byte, n int) []byte { - return appendU32(buf, uint32(n)) -} - -func appendString(buf []byte, s string) []byte { - buf = appendU32(buf, uint32(len(s))) - buf = append(buf, s...) - return buf -} - -func appendBool(buf []byte, b bool) []byte { - if b { - return append(buf, 1) - } - return append(buf, 0) -} - -// newCond is a helper to hide the fact that there is no usable zero -// value for sync.Cond. -func newCond() *sync.Cond { return sync.NewCond(new(sync.Mutex)) } - -// window represents the buffer available to clients -// wishing to write to a channel. -type window struct { - *sync.Cond - win uint32 // RFC 4254 5.2 says the window size can grow to 2^32-1 - writeWaiters int - closed bool -} - -// add adds win to the amount of window available -// for consumers. -func (w *window) add(win uint32) bool { - // a zero sized window adjust is a noop. - if win == 0 { - return true - } - w.L.Lock() - if w.win+win < win { - w.L.Unlock() - return false - } - w.win += win - // It is unusual that multiple goroutines would be attempting to reserve - // window space, but not guaranteed. Use broadcast to notify all waiters - // that additional window is available. - w.Broadcast() - w.L.Unlock() - return true -} - -// close sets the window to closed, so all reservations fail -// immediately. -func (w *window) close() { - w.L.Lock() - w.closed = true - w.Broadcast() - w.L.Unlock() -} - -// reserve reserves win from the available window capacity. -// If no capacity remains, reserve will block. reserve may -// return less than requested. -func (w *window) reserve(win uint32) (uint32, error) { - var err error - w.L.Lock() - w.writeWaiters++ - w.Broadcast() - for w.win == 0 && !w.closed { - w.Wait() - } - w.writeWaiters-- - if w.win < win { - win = w.win - } - w.win -= win - if w.closed { - err = io.EOF - } - w.L.Unlock() - return win, err -} - -// waitWriterBlocked waits until some goroutine is blocked for further -// writes. It is used in tests only. -func (w *window) waitWriterBlocked() { - w.Cond.L.Lock() - for w.writeWaiters == 0 { - w.Cond.Wait() - } - w.Cond.L.Unlock() -} diff --git a/vendor/golang.org/x/crypto/ssh/connection.go b/vendor/golang.org/x/crypto/ssh/connection.go deleted file mode 100644 index 979d919..0000000 --- a/vendor/golang.org/x/crypto/ssh/connection.go +++ /dev/null @@ -1,144 +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 ssh - -import ( - "fmt" - "net" -) - -// OpenChannelError is returned if the other side rejects an -// OpenChannel request. -type OpenChannelError struct { - Reason RejectionReason - Message string -} - -func (e *OpenChannelError) Error() string { - return fmt.Sprintf("ssh: rejected: %s (%s)", e.Reason, e.Message) -} - -// ConnMetadata holds metadata for the connection. -type ConnMetadata interface { - // User returns the user ID for this connection. - // It is empty if no authentication is used. - User() string - - // SessionID returns the sesson hash, also denoted by H. - SessionID() []byte - - // ClientVersion returns the client's version string as hashed - // into the session ID. - ClientVersion() []byte - - // ServerVersion returns the server's version string as hashed - // into the session ID. - ServerVersion() []byte - - // RemoteAddr returns the remote address for this connection. - RemoteAddr() net.Addr - - // LocalAddr returns the local address for this connection. - LocalAddr() net.Addr -} - -// Conn represents an SSH connection for both server and client roles. -// Conn is the basis for implementing an application layer, such -// as ClientConn, which implements the traditional shell access for -// clients. -type Conn interface { - ConnMetadata - - // SendRequest sends a global request, and returns the - // reply. If wantReply is true, it returns the response status - // and payload. See also RFC4254, section 4. - SendRequest(name string, wantReply bool, payload []byte) (bool, []byte, error) - - // OpenChannel tries to open an channel. If the request is - // rejected, it returns *OpenChannelError. On success it returns - // the SSH Channel and a Go channel for incoming, out-of-band - // requests. The Go channel must be serviced, or the - // connection will hang. - OpenChannel(name string, data []byte) (Channel, <-chan *Request, error) - - // Close closes the underlying network connection - Close() error - - // Wait blocks until the connection has shut down, and returns the - // error causing the shutdown. - Wait() error - - // TODO(hanwen): consider exposing: - // RequestKeyChange - // Disconnect -} - -// DiscardRequests consumes and rejects all requests from the -// passed-in channel. -func DiscardRequests(in <-chan *Request) { - for req := range in { - if req.WantReply { - req.Reply(false, nil) - } - } -} - -// A connection represents an incoming connection. -type connection struct { - transport *handshakeTransport - sshConn - - // The connection protocol. - *mux -} - -func (c *connection) Close() error { - return c.sshConn.conn.Close() -} - -// sshconn provides net.Conn metadata, but disallows direct reads and -// writes. -type sshConn struct { - conn net.Conn - - user string - sessionID []byte - clientVersion []byte - serverVersion []byte -} - -func dup(src []byte) []byte { - dst := make([]byte, len(src)) - copy(dst, src) - return dst -} - -func (c *sshConn) User() string { - return c.user -} - -func (c *sshConn) RemoteAddr() net.Addr { - return c.conn.RemoteAddr() -} - -func (c *sshConn) Close() error { - return c.conn.Close() -} - -func (c *sshConn) LocalAddr() net.Addr { - return c.conn.LocalAddr() -} - -func (c *sshConn) SessionID() []byte { - return dup(c.sessionID) -} - -func (c *sshConn) ClientVersion() []byte { - return dup(c.clientVersion) -} - -func (c *sshConn) ServerVersion() []byte { - return dup(c.serverVersion) -} diff --git a/vendor/golang.org/x/crypto/ssh/doc.go b/vendor/golang.org/x/crypto/ssh/doc.go deleted file mode 100644 index d6be894..0000000 --- a/vendor/golang.org/x/crypto/ssh/doc.go +++ /dev/null @@ -1,18 +0,0 @@ -// 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 ssh implements an SSH client and server. - -SSH is a transport security protocol, an authentication protocol and a -family of application protocols. The most typical application level -protocol is a remote shell and this is specifically implemented. However, -the multiplexed nature of SSH is exposed to users that wish to support -others. - -References: - [PROTOCOL.certkeys]: http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/PROTOCOL.certkeys?rev=HEAD - [SSH-PARAMETERS]: http://www.iana.org/assignments/ssh-parameters/ssh-parameters.xml#ssh-parameters-1 -*/ -package ssh // import "golang.org/x/crypto/ssh" diff --git a/vendor/golang.org/x/crypto/ssh/example_test.go b/vendor/golang.org/x/crypto/ssh/example_test.go deleted file mode 100644 index 25f9951..0000000 --- a/vendor/golang.org/x/crypto/ssh/example_test.go +++ /dev/null @@ -1,243 +0,0 @@ -// 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 ssh_test - -import ( - "bytes" - "fmt" - "io/ioutil" - "log" - "net" - "net/http" - - "golang.org/x/crypto/ssh" - "golang.org/x/crypto/ssh/terminal" -) - -func ExampleNewServerConn() { - // An SSH server is represented by a ServerConfig, which holds - // certificate details and handles authentication of ServerConns. - config := &ssh.ServerConfig{ - PasswordCallback: func(c ssh.ConnMetadata, pass []byte) (*ssh.Permissions, error) { - // Should use constant-time compare (or better, salt+hash) in - // a production setting. - if c.User() == "testuser" && string(pass) == "tiger" { - return nil, nil - } - return nil, fmt.Errorf("password rejected for %q", c.User()) - }, - } - - privateBytes, err := ioutil.ReadFile("id_rsa") - if err != nil { - panic("Failed to load private key") - } - - private, err := ssh.ParsePrivateKey(privateBytes) - if err != nil { - panic("Failed to parse private key") - } - - config.AddHostKey(private) - - // Once a ServerConfig has been configured, connections can be - // accepted. - listener, err := net.Listen("tcp", "0.0.0.0:2022") - if err != nil { - panic("failed to listen for connection") - } - nConn, err := listener.Accept() - if err != nil { - panic("failed to accept incoming connection") - } - - // Before use, a handshake must be performed on the incoming - // net.Conn. - _, chans, reqs, err := ssh.NewServerConn(nConn, config) - if err != nil { - panic("failed to handshake") - } - // The incoming Request channel must be serviced. - go ssh.DiscardRequests(reqs) - - // Service the incoming Channel channel. - for newChannel := range chans { - // Channels have a type, depending on the application level - // protocol intended. In the case of a shell, the type is - // "session" and ServerShell may be used to present a simple - // terminal interface. - if newChannel.ChannelType() != "session" { - newChannel.Reject(ssh.UnknownChannelType, "unknown channel type") - continue - } - channel, requests, err := newChannel.Accept() - if err != nil { - panic("could not accept channel.") - } - - // Sessions have out-of-band requests such as "shell", - // "pty-req" and "env". Here we handle only the - // "shell" request. - go func(in <-chan *ssh.Request) { - for req := range in { - ok := false - switch req.Type { - case "shell": - ok = true - if len(req.Payload) > 0 { - // We don't accept any - // commands, only the - // default shell. - ok = false - } - } - req.Reply(ok, nil) - } - }(requests) - - term := terminal.NewTerminal(channel, "> ") - - go func() { - defer channel.Close() - for { - line, err := term.ReadLine() - if err != nil { - break - } - fmt.Println(line) - } - }() - } -} - -func ExampleDial() { - // An SSH client is represented with a ClientConn. - // - // To authenticate with the remote server you must pass at least one - // implementation of AuthMethod via the Auth field in ClientConfig. - config := &ssh.ClientConfig{ - User: "username", - Auth: []ssh.AuthMethod{ - ssh.Password("yourpassword"), - }, - } - client, err := ssh.Dial("tcp", "yourserver.com:22", config) - if err != nil { - panic("Failed to dial: " + err.Error()) - } - - // Each ClientConn can support multiple interactive sessions, - // represented by a Session. - session, err := client.NewSession() - if err != nil { - panic("Failed to create session: " + err.Error()) - } - defer session.Close() - - // Once a Session is created, you can execute a single command on - // the remote side using the Run method. - var b bytes.Buffer - session.Stdout = &b - if err := session.Run("/usr/bin/whoami"); err != nil { - panic("Failed to run: " + err.Error()) - } - fmt.Println(b.String()) -} - -func ExamplePublicKeys() { - // A public key may be used to authenticate against the remote - // server by using an unencrypted PEM-encoded private key file. - // - // If you have an encrypted private key, the crypto/x509 package - // can be used to decrypt it. - key, err := ioutil.ReadFile("/home/user/.ssh/id_rsa") - if err != nil { - log.Fatalf("unable to read private key: %v", err) - } - - // Create the Signer for this private key. - signer, err := ssh.ParsePrivateKey(key) - if err != nil { - log.Fatalf("unable to parse private key: %v", err) - } - - config := &ssh.ClientConfig{ - User: "user", - Auth: []ssh.AuthMethod{ - // Use the PublicKeys method for remote authentication. - ssh.PublicKeys(signer), - }, - } - - // Connect to the remote server and perform the SSH handshake. - client, err := ssh.Dial("tcp", "host.com:22", config) - if err != nil { - log.Fatalf("unable to connect: %v", err) - } - defer client.Close() -} - -func ExampleClient_Listen() { - config := &ssh.ClientConfig{ - User: "username", - Auth: []ssh.AuthMethod{ - ssh.Password("password"), - }, - } - // Dial your ssh server. - conn, err := ssh.Dial("tcp", "localhost:22", config) - if err != nil { - log.Fatalf("unable to connect: %s", err) - } - defer conn.Close() - - // Request the remote side to open port 8080 on all interfaces. - l, err := conn.Listen("tcp", "0.0.0.0:8080") - if err != nil { - log.Fatalf("unable to register tcp forward: %v", err) - } - defer l.Close() - - // Serve HTTP with your SSH server acting as a reverse proxy. - http.Serve(l, http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) { - fmt.Fprintf(resp, "Hello world!\n") - })) -} - -func ExampleSession_RequestPty() { - // Create client config - config := &ssh.ClientConfig{ - User: "username", - Auth: []ssh.AuthMethod{ - ssh.Password("password"), - }, - } - // Connect to ssh server - conn, err := ssh.Dial("tcp", "localhost:22", config) - if err != nil { - log.Fatalf("unable to connect: %s", err) - } - defer conn.Close() - // Create a session - session, err := conn.NewSession() - if err != nil { - log.Fatalf("unable to create session: %s", err) - } - defer session.Close() - // Set up terminal modes - modes := ssh.TerminalModes{ - ssh.ECHO: 0, // disable echoing - ssh.TTY_OP_ISPEED: 14400, // input speed = 14.4kbaud - ssh.TTY_OP_OSPEED: 14400, // output speed = 14.4kbaud - } - // Request pseudo terminal - if err := session.RequestPty("xterm", 80, 40, modes); err != nil { - log.Fatalf("request for pseudo terminal failed: %s", err) - } - // Start remote shell - if err := session.Shell(); err != nil { - log.Fatalf("failed to start shell: %s", err) - } -} diff --git a/vendor/golang.org/x/crypto/ssh/handshake.go b/vendor/golang.org/x/crypto/ssh/handshake.go deleted file mode 100644 index ae26191..0000000 --- a/vendor/golang.org/x/crypto/ssh/handshake.go +++ /dev/null @@ -1,451 +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 ssh - -import ( - "crypto/rand" - "errors" - "fmt" - "io" - "log" - "net" - "sync" -) - -// debugHandshake, if set, prints messages sent and received. Key -// exchange messages are printed as if DH were used, so the debug -// messages are wrong when using ECDH. -const debugHandshake = false - -// keyingTransport is a packet based transport that supports key -// changes. It need not be thread-safe. It should pass through -// msgNewKeys in both directions. -type keyingTransport interface { - packetConn - - // prepareKeyChange sets up a key change. The key change for a - // direction will be effected if a msgNewKeys message is sent - // or received. - prepareKeyChange(*algorithms, *kexResult) error -} - -// handshakeTransport implements rekeying on top of a keyingTransport -// and offers a thread-safe writePacket() interface. -type handshakeTransport struct { - conn keyingTransport - config *Config - - serverVersion []byte - clientVersion []byte - - // hostKeys is non-empty if we are the server. In that case, - // it contains all host keys that can be used to sign the - // connection. - hostKeys []Signer - - // hostKeyAlgorithms is non-empty if we are the client. In that case, - // we accept these key types from the server as host key. - hostKeyAlgorithms []string - - // On read error, incoming is closed, and readError is set. - incoming chan []byte - readError error - - // data for host key checking - hostKeyCallback func(hostname string, remote net.Addr, key PublicKey) error - dialAddress string - remoteAddr net.Addr - - readSinceKex uint64 - - // Protects the writing side of the connection - mu sync.Mutex - cond *sync.Cond - sentInitPacket []byte - sentInitMsg *kexInitMsg - writtenSinceKex uint64 - writeError error - - // The session ID or nil if first kex did not complete yet. - sessionID []byte -} - -func newHandshakeTransport(conn keyingTransport, config *Config, clientVersion, serverVersion []byte) *handshakeTransport { - t := &handshakeTransport{ - conn: conn, - serverVersion: serverVersion, - clientVersion: clientVersion, - incoming: make(chan []byte, 16), - config: config, - } - t.cond = sync.NewCond(&t.mu) - return t -} - -func newClientTransport(conn keyingTransport, clientVersion, serverVersion []byte, config *ClientConfig, dialAddr string, addr net.Addr) *handshakeTransport { - t := newHandshakeTransport(conn, &config.Config, clientVersion, serverVersion) - t.dialAddress = dialAddr - t.remoteAddr = addr - t.hostKeyCallback = config.HostKeyCallback - if config.HostKeyAlgorithms != nil { - t.hostKeyAlgorithms = config.HostKeyAlgorithms - } else { - t.hostKeyAlgorithms = supportedHostKeyAlgos - } - go t.readLoop() - return t -} - -func newServerTransport(conn keyingTransport, clientVersion, serverVersion []byte, config *ServerConfig) *handshakeTransport { - t := newHandshakeTransport(conn, &config.Config, clientVersion, serverVersion) - t.hostKeys = config.hostKeys - go t.readLoop() - return t -} - -func (t *handshakeTransport) getSessionID() []byte { - return t.sessionID -} - -func (t *handshakeTransport) id() string { - if len(t.hostKeys) > 0 { - return "server" - } - return "client" -} - -func (t *handshakeTransport) readPacket() ([]byte, error) { - p, ok := <-t.incoming - if !ok { - return nil, t.readError - } - return p, nil -} - -func (t *handshakeTransport) readLoop() { - for { - p, err := t.readOnePacket() - if err != nil { - t.readError = err - close(t.incoming) - break - } - if p[0] == msgIgnore || p[0] == msgDebug { - continue - } - t.incoming <- p - } - - // If we can't read, declare the writing part dead too. - t.mu.Lock() - defer t.mu.Unlock() - if t.writeError == nil { - t.writeError = t.readError - } - t.cond.Broadcast() -} - -func (t *handshakeTransport) readOnePacket() ([]byte, error) { - if t.readSinceKex > t.config.RekeyThreshold { - if err := t.requestKeyChange(); err != nil { - return nil, err - } - } - - p, err := t.conn.readPacket() - if err != nil { - return nil, err - } - - t.readSinceKex += uint64(len(p)) - if debugHandshake { - if p[0] == msgChannelData || p[0] == msgChannelExtendedData { - log.Printf("%s got data (packet %d bytes)", t.id(), len(p)) - } else { - msg, err := decode(p) - log.Printf("%s got %T %v (%v)", t.id(), msg, msg, err) - } - } - if p[0] != msgKexInit { - return p, nil - } - - t.mu.Lock() - - firstKex := t.sessionID == nil - - err = t.enterKeyExchangeLocked(p) - if err != nil { - // drop connection - t.conn.Close() - t.writeError = err - } - - if debugHandshake { - log.Printf("%s exited key exchange (first %v), err %v", t.id(), firstKex, err) - } - - // Unblock writers. - t.sentInitMsg = nil - t.sentInitPacket = nil - t.cond.Broadcast() - t.writtenSinceKex = 0 - t.mu.Unlock() - - if err != nil { - return nil, err - } - - t.readSinceKex = 0 - - // By default, a key exchange is hidden from higher layers by - // translating it into msgIgnore. - successPacket := []byte{msgIgnore} - if firstKex { - // sendKexInit() for the first kex waits for - // msgNewKeys so the authentication process is - // guaranteed to happen over an encrypted transport. - successPacket = []byte{msgNewKeys} - } - - return successPacket, nil -} - -// keyChangeCategory describes whether a key exchange is the first on a -// connection, or a subsequent one. -type keyChangeCategory bool - -const ( - firstKeyExchange keyChangeCategory = true - subsequentKeyExchange keyChangeCategory = false -) - -// sendKexInit sends a key change message, and returns the message -// that was sent. After initiating the key change, all writes will be -// blocked until the change is done, and a failed key change will -// close the underlying transport. This function is safe for -// concurrent use by multiple goroutines. -func (t *handshakeTransport) sendKexInit(isFirst keyChangeCategory) error { - var err error - - t.mu.Lock() - // If this is the initial key change, but we already have a sessionID, - // then do nothing because the key exchange has already completed - // asynchronously. - if !isFirst || t.sessionID == nil { - _, _, err = t.sendKexInitLocked(isFirst) - } - t.mu.Unlock() - if err != nil { - return err - } - if isFirst { - if packet, err := t.readPacket(); err != nil { - return err - } else if packet[0] != msgNewKeys { - return unexpectedMessageError(msgNewKeys, packet[0]) - } - } - return nil -} - -func (t *handshakeTransport) requestInitialKeyChange() error { - return t.sendKexInit(firstKeyExchange) -} - -func (t *handshakeTransport) requestKeyChange() error { - return t.sendKexInit(subsequentKeyExchange) -} - -// sendKexInitLocked sends a key change message. t.mu must be locked -// while this happens. -func (t *handshakeTransport) sendKexInitLocked(isFirst keyChangeCategory) (*kexInitMsg, []byte, error) { - // kexInits may be sent either in response to the other side, - // or because our side wants to initiate a key change, so we - // may have already sent a kexInit. In that case, don't send a - // second kexInit. - if t.sentInitMsg != nil { - return t.sentInitMsg, t.sentInitPacket, nil - } - - msg := &kexInitMsg{ - KexAlgos: t.config.KeyExchanges, - CiphersClientServer: t.config.Ciphers, - CiphersServerClient: t.config.Ciphers, - MACsClientServer: t.config.MACs, - MACsServerClient: t.config.MACs, - CompressionClientServer: supportedCompressions, - CompressionServerClient: supportedCompressions, - } - io.ReadFull(rand.Reader, msg.Cookie[:]) - - if len(t.hostKeys) > 0 { - for _, k := range t.hostKeys { - msg.ServerHostKeyAlgos = append( - msg.ServerHostKeyAlgos, k.PublicKey().Type()) - } - } else { - msg.ServerHostKeyAlgos = t.hostKeyAlgorithms - } - packet := Marshal(msg) - - // writePacket destroys the contents, so save a copy. - packetCopy := make([]byte, len(packet)) - copy(packetCopy, packet) - - if err := t.conn.writePacket(packetCopy); err != nil { - return nil, nil, err - } - - t.sentInitMsg = msg - t.sentInitPacket = packet - return msg, packet, nil -} - -func (t *handshakeTransport) writePacket(p []byte) error { - t.mu.Lock() - defer t.mu.Unlock() - - if t.writtenSinceKex > t.config.RekeyThreshold { - t.sendKexInitLocked(subsequentKeyExchange) - } - for t.sentInitMsg != nil && t.writeError == nil { - t.cond.Wait() - } - if t.writeError != nil { - return t.writeError - } - t.writtenSinceKex += uint64(len(p)) - - switch p[0] { - case msgKexInit: - return errors.New("ssh: only handshakeTransport can send kexInit") - case msgNewKeys: - return errors.New("ssh: only handshakeTransport can send newKeys") - default: - return t.conn.writePacket(p) - } -} - -func (t *handshakeTransport) Close() error { - return t.conn.Close() -} - -// enterKeyExchange runs the key exchange. t.mu must be held while running this. -func (t *handshakeTransport) enterKeyExchangeLocked(otherInitPacket []byte) error { - if debugHandshake { - log.Printf("%s entered key exchange", t.id()) - } - myInit, myInitPacket, err := t.sendKexInitLocked(subsequentKeyExchange) - if err != nil { - return err - } - - otherInit := &kexInitMsg{} - if err := Unmarshal(otherInitPacket, otherInit); err != nil { - return err - } - - magics := handshakeMagics{ - clientVersion: t.clientVersion, - serverVersion: t.serverVersion, - clientKexInit: otherInitPacket, - serverKexInit: myInitPacket, - } - - clientInit := otherInit - serverInit := myInit - if len(t.hostKeys) == 0 { - clientInit = myInit - serverInit = otherInit - - magics.clientKexInit = myInitPacket - magics.serverKexInit = otherInitPacket - } - - algs, err := findAgreedAlgorithms(clientInit, serverInit) - if err != nil { - return err - } - - // We don't send FirstKexFollows, but we handle receiving it. - if otherInit.FirstKexFollows && algs.kex != otherInit.KexAlgos[0] { - // other side sent a kex message for the wrong algorithm, - // which we have to ignore. - if _, err := t.conn.readPacket(); err != nil { - return err - } - } - - kex, ok := kexAlgoMap[algs.kex] - if !ok { - return fmt.Errorf("ssh: unexpected key exchange algorithm %v", algs.kex) - } - - var result *kexResult - if len(t.hostKeys) > 0 { - result, err = t.server(kex, algs, &magics) - } else { - result, err = t.client(kex, algs, &magics) - } - - if err != nil { - return err - } - - if t.sessionID == nil { - t.sessionID = result.H - } - result.SessionID = t.sessionID - - t.conn.prepareKeyChange(algs, result) - if err = t.conn.writePacket([]byte{msgNewKeys}); err != nil { - return err - } - if packet, err := t.conn.readPacket(); err != nil { - return err - } else if packet[0] != msgNewKeys { - return unexpectedMessageError(msgNewKeys, packet[0]) - } - - 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 - } - } - - r, err := kex.Server(t.conn, t.config.Rand, magics, hostKey) - return r, err -} - -func (t *handshakeTransport) client(kex kexAlgorithm, algs *algorithms, magics *handshakeMagics) (*kexResult, error) { - result, err := kex.Client(t.conn, t.config.Rand, magics) - if err != nil { - return nil, err - } - - hostKey, err := ParsePublicKey(result.HostKey) - if err != nil { - return nil, err - } - - if err := verifyHostKeySignature(hostKey, result); err != nil { - return nil, err - } - - if t.hostKeyCallback != nil { - err = t.hostKeyCallback(t.dialAddress, t.remoteAddr, hostKey) - if err != nil { - return nil, err - } - } - - return result, nil -} diff --git a/vendor/golang.org/x/crypto/ssh/handshake_test.go b/vendor/golang.org/x/crypto/ssh/handshake_test.go deleted file mode 100644 index da53d3a..0000000 --- a/vendor/golang.org/x/crypto/ssh/handshake_test.go +++ /dev/null @@ -1,486 +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 ssh - -import ( - "bytes" - "crypto/rand" - "errors" - "fmt" - "net" - "reflect" - "runtime" - "strings" - "sync" - "testing" -) - -type testChecker struct { - calls []string -} - -func (t *testChecker) Check(dialAddr string, addr net.Addr, key PublicKey) error { - if dialAddr == "bad" { - return fmt.Errorf("dialAddr is bad") - } - - if tcpAddr, ok := addr.(*net.TCPAddr); !ok || tcpAddr == nil { - return fmt.Errorf("testChecker: got %T want *net.TCPAddr", addr) - } - - t.calls = append(t.calls, fmt.Sprintf("%s %v %s %x", dialAddr, addr, key.Type(), key.Marshal())) - - return nil -} - -// netPipe is analogous to net.Pipe, but it uses a real net.Conn, and -// therefore is buffered (net.Pipe deadlocks if both sides start with -// a write.) -func netPipe() (net.Conn, net.Conn, error) { - listener, err := net.Listen("tcp", "127.0.0.1:0") - if err != nil { - return nil, nil, err - } - defer listener.Close() - c1, err := net.Dial("tcp", listener.Addr().String()) - if err != nil { - return nil, nil, err - } - - c2, err := listener.Accept() - if err != nil { - c1.Close() - return nil, nil, err - } - - return c1, c2, nil -} - -func handshakePair(clientConf *ClientConfig, addr string) (client *handshakeTransport, server *handshakeTransport, err error) { - a, b, err := netPipe() - if err != nil { - return nil, nil, err - } - - trC := newTransport(a, rand.Reader, true) - trS := newTransport(b, rand.Reader, false) - clientConf.SetDefaults() - - v := []byte("version") - client = newClientTransport(trC, v, v, clientConf, addr, a.RemoteAddr()) - - serverConf := &ServerConfig{} - serverConf.AddHostKey(testSigners["ecdsa"]) - serverConf.AddHostKey(testSigners["rsa"]) - serverConf.SetDefaults() - server = newServerTransport(trS, v, v, serverConf) - - return client, server, nil -} - -func TestHandshakeBasic(t *testing.T) { - if runtime.GOOS == "plan9" { - t.Skip("see golang.org/issue/7237") - } - checker := &testChecker{} - trC, trS, err := handshakePair(&ClientConfig{HostKeyCallback: checker.Check}, "addr") - if err != nil { - t.Fatalf("handshakePair: %v", err) - } - - defer trC.Close() - defer trS.Close() - - go func() { - // Client writes a bunch of stuff, and does a key - // change in the middle. This should not confuse the - // handshake in progress - for i := 0; i < 10; i++ { - p := []byte{msgRequestSuccess, byte(i)} - if err := trC.writePacket(p); err != nil { - t.Fatalf("sendPacket: %v", err) - } - if i == 5 { - // halfway through, we request a key change. - err := trC.sendKexInit(subsequentKeyExchange) - if err != nil { - t.Fatalf("sendKexInit: %v", err) - } - } - } - trC.Close() - }() - - // Server checks that client messages come in cleanly - i := 0 - for { - p, err := trS.readPacket() - if err != nil { - break - } - if p[0] == msgNewKeys { - continue - } - want := []byte{msgRequestSuccess, byte(i)} - if bytes.Compare(p, want) != 0 { - t.Errorf("message %d: got %q, want %q", i, p, want) - } - i++ - } - if i != 10 { - t.Errorf("received %d messages, want 10.", i) - } - - // If all went well, we registered exactly 1 key change. - if len(checker.calls) != 1 { - t.Fatalf("got %d host key checks, want 1", len(checker.calls)) - } - - pub := testSigners["ecdsa"].PublicKey() - want := fmt.Sprintf("%s %v %s %x", "addr", trC.remoteAddr, pub.Type(), pub.Marshal()) - if want != checker.calls[0] { - t.Errorf("got %q want %q for host key check", checker.calls[0], want) - } -} - -func TestHandshakeError(t *testing.T) { - checker := &testChecker{} - trC, trS, err := handshakePair(&ClientConfig{HostKeyCallback: checker.Check}, "bad") - if err != nil { - t.Fatalf("handshakePair: %v", err) - } - defer trC.Close() - defer trS.Close() - - // send a packet - packet := []byte{msgRequestSuccess, 42} - if err := trC.writePacket(packet); err != nil { - t.Errorf("writePacket: %v", err) - } - - // Now request a key change. - err = trC.sendKexInit(subsequentKeyExchange) - if err != nil { - t.Errorf("sendKexInit: %v", err) - } - - // the key change will fail, and afterwards we can't write. - if err := trC.writePacket([]byte{msgRequestSuccess, 43}); err == nil { - t.Errorf("writePacket after botched rekey succeeded.") - } - - readback, err := trS.readPacket() - if err != nil { - t.Fatalf("server closed too soon: %v", err) - } - if bytes.Compare(readback, packet) != 0 { - t.Errorf("got %q want %q", readback, packet) - } - readback, err = trS.readPacket() - if err == nil { - t.Errorf("got a message %q after failed key change", readback) - } -} - -func TestForceFirstKex(t *testing.T) { - checker := &testChecker{} - trC, trS, err := handshakePair(&ClientConfig{HostKeyCallback: checker.Check}, "addr") - if err != nil { - t.Fatalf("handshakePair: %v", err) - } - - defer trC.Close() - defer trS.Close() - - trC.writePacket(Marshal(&serviceRequestMsg{serviceUserAuth})) - - // We setup the initial key exchange, but the remote side - // tries to send serviceRequestMsg in cleartext, which is - // disallowed. - - err = trS.sendKexInit(firstKeyExchange) - if err == nil { - t.Errorf("server first kex init should reject unexpected packet") - } -} - -func TestHandshakeTwice(t *testing.T) { - checker := &testChecker{} - trC, trS, err := handshakePair(&ClientConfig{HostKeyCallback: checker.Check}, "addr") - if err != nil { - t.Fatalf("handshakePair: %v", err) - } - - defer trC.Close() - defer trS.Close() - - // Both sides should ask for the first key exchange first. - err = trS.sendKexInit(firstKeyExchange) - if err != nil { - t.Errorf("server sendKexInit: %v", err) - } - - err = trC.sendKexInit(firstKeyExchange) - if err != nil { - t.Errorf("client sendKexInit: %v", err) - } - - sent := 0 - // send a packet - packet := make([]byte, 5) - packet[0] = msgRequestSuccess - if err := trC.writePacket(packet); err != nil { - t.Errorf("writePacket: %v", err) - } - sent++ - - // Send another packet. Use a fresh one, since writePacket destroys. - packet = make([]byte, 5) - packet[0] = msgRequestSuccess - if err := trC.writePacket(packet); err != nil { - t.Errorf("writePacket: %v", err) - } - sent++ - - // 2nd key change. - err = trC.sendKexInit(subsequentKeyExchange) - if err != nil { - t.Errorf("sendKexInit: %v", err) - } - - packet = make([]byte, 5) - packet[0] = msgRequestSuccess - if err := trC.writePacket(packet); err != nil { - t.Errorf("writePacket: %v", err) - } - sent++ - - packet = make([]byte, 5) - packet[0] = msgRequestSuccess - for i := 0; i < sent; i++ { - msg, err := trS.readPacket() - if err != nil { - t.Fatalf("server closed too soon: %v", err) - } - - if bytes.Compare(msg, packet) != 0 { - t.Errorf("packet %d: got %q want %q", i, msg, packet) - } - } - if len(checker.calls) != 2 { - t.Errorf("got %d key changes, want 2", len(checker.calls)) - } -} - -func TestHandshakeAutoRekeyWrite(t *testing.T) { - checker := &testChecker{} - clientConf := &ClientConfig{HostKeyCallback: checker.Check} - clientConf.RekeyThreshold = 500 - trC, trS, err := handshakePair(clientConf, "addr") - if err != nil { - t.Fatalf("handshakePair: %v", err) - } - defer trC.Close() - defer trS.Close() - - for i := 0; i < 5; i++ { - packet := make([]byte, 251) - packet[0] = msgRequestSuccess - if err := trC.writePacket(packet); err != nil { - t.Errorf("writePacket: %v", err) - } - } - - j := 0 - for ; j < 5; j++ { - _, err := trS.readPacket() - if err != nil { - break - } - } - - if j != 5 { - t.Errorf("got %d, want 5 messages", j) - } - - if len(checker.calls) != 2 { - t.Errorf("got %d key changes, wanted 2", len(checker.calls)) - } -} - -type syncChecker struct { - called chan int -} - -func (t *syncChecker) Check(dialAddr string, addr net.Addr, key PublicKey) error { - t.called <- 1 - return nil -} - -func TestHandshakeAutoRekeyRead(t *testing.T) { - sync := &syncChecker{make(chan int, 2)} - clientConf := &ClientConfig{ - HostKeyCallback: sync.Check, - } - clientConf.RekeyThreshold = 500 - - trC, trS, err := handshakePair(clientConf, "addr") - if err != nil { - t.Fatalf("handshakePair: %v", err) - } - defer trC.Close() - defer trS.Close() - - packet := make([]byte, 501) - packet[0] = msgRequestSuccess - if err := trS.writePacket(packet); err != nil { - t.Fatalf("writePacket: %v", err) - } - // While we read out the packet, a key change will be - // initiated. - if _, err := trC.readPacket(); err != nil { - t.Fatalf("readPacket(client): %v", err) - } - - <-sync.called -} - -// errorKeyingTransport generates errors after a given number of -// read/write operations. -type errorKeyingTransport struct { - packetConn - readLeft, writeLeft int -} - -func (n *errorKeyingTransport) prepareKeyChange(*algorithms, *kexResult) error { - return nil -} -func (n *errorKeyingTransport) getSessionID() []byte { - return nil -} - -func (n *errorKeyingTransport) writePacket(packet []byte) error { - if n.writeLeft == 0 { - n.Close() - return errors.New("barf") - } - - n.writeLeft-- - return n.packetConn.writePacket(packet) -} - -func (n *errorKeyingTransport) readPacket() ([]byte, error) { - if n.readLeft == 0 { - n.Close() - return nil, errors.New("barf") - } - - n.readLeft-- - return n.packetConn.readPacket() -} - -func TestHandshakeErrorHandlingRead(t *testing.T) { - for i := 0; i < 20; i++ { - testHandshakeErrorHandlingN(t, i, -1) - } -} - -func TestHandshakeErrorHandlingWrite(t *testing.T) { - for i := 0; i < 20; i++ { - testHandshakeErrorHandlingN(t, -1, i) - } -} - -// testHandshakeErrorHandlingN runs handshakes, injecting errors. If -// handshakeTransport deadlocks, the go runtime will detect it and -// panic. -func testHandshakeErrorHandlingN(t *testing.T, readLimit, writeLimit int) { - msg := Marshal(&serviceRequestMsg{strings.Repeat("x", int(minRekeyThreshold)/4)}) - - a, b := memPipe() - defer a.Close() - defer b.Close() - - key := testSigners["ecdsa"] - serverConf := Config{RekeyThreshold: minRekeyThreshold} - serverConf.SetDefaults() - serverConn := newHandshakeTransport(&errorKeyingTransport{a, readLimit, writeLimit}, &serverConf, []byte{'a'}, []byte{'b'}) - serverConn.hostKeys = []Signer{key} - go serverConn.readLoop() - - clientConf := Config{RekeyThreshold: 10 * minRekeyThreshold} - clientConf.SetDefaults() - clientConn := newHandshakeTransport(&errorKeyingTransport{b, -1, -1}, &clientConf, []byte{'a'}, []byte{'b'}) - clientConn.hostKeyAlgorithms = []string{key.PublicKey().Type()} - go clientConn.readLoop() - - var wg sync.WaitGroup - wg.Add(4) - - for _, hs := range []packetConn{serverConn, clientConn} { - go func(c packetConn) { - for { - err := c.writePacket(msg) - if err != nil { - break - } - } - wg.Done() - }(hs) - go func(c packetConn) { - for { - _, err := c.readPacket() - if err != nil { - break - } - } - wg.Done() - }(hs) - } - - wg.Wait() -} - -func TestDisconnect(t *testing.T) { - if runtime.GOOS == "plan9" { - t.Skip("see golang.org/issue/7237") - } - checker := &testChecker{} - trC, trS, err := handshakePair(&ClientConfig{HostKeyCallback: checker.Check}, "addr") - if err != nil { - t.Fatalf("handshakePair: %v", err) - } - - defer trC.Close() - defer trS.Close() - - trC.writePacket([]byte{msgRequestSuccess, 0, 0}) - errMsg := &disconnectMsg{ - Reason: 42, - Message: "such is life", - } - trC.writePacket(Marshal(errMsg)) - trC.writePacket([]byte{msgRequestSuccess, 0, 0}) - - packet, err := trS.readPacket() - if err != nil { - t.Fatalf("readPacket 1: %v", err) - } - if packet[0] != msgRequestSuccess { - t.Errorf("got packet %v, want packet type %d", packet, msgRequestSuccess) - } - - _, err = trS.readPacket() - if err == nil { - t.Errorf("readPacket 2 succeeded") - } else if !reflect.DeepEqual(err, errMsg) { - t.Errorf("got error %#v, want %#v", err, errMsg) - } - - _, err = trS.readPacket() - if err == nil { - t.Errorf("readPacket 3 succeeded") - } -} diff --git a/vendor/golang.org/x/crypto/ssh/kex.go b/vendor/golang.org/x/crypto/ssh/kex.go deleted file mode 100644 index 9285ee3..0000000 --- a/vendor/golang.org/x/crypto/ssh/kex.go +++ /dev/null @@ -1,526 +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 ssh - -import ( - "crypto" - "crypto/ecdsa" - "crypto/elliptic" - "crypto/rand" - "crypto/subtle" - "errors" - "io" - "math/big" - - "golang.org/x/crypto/curve25519" -) - -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" -) - -// kexResult captures the outcome of a key exchange. -type kexResult struct { - // Session hash. See also RFC 4253, section 8. - H []byte - - // Shared secret. See also RFC 4253, section 8. - K []byte - - // Host key as hashed into H. - HostKey []byte - - // Signature of H. - Signature []byte - - // A cryptographic hash function that matches the security - // level of the key exchange algorithm. It is used for - // calculating H, and for deriving keys from H and K. - Hash crypto.Hash - - // The session ID, which is the first H computed. This is used - // to derive key material inside the transport. - SessionID []byte -} - -// handshakeMagics contains data that is always included in the -// session hash. -type handshakeMagics struct { - clientVersion, serverVersion []byte - clientKexInit, serverKexInit []byte -} - -func (m *handshakeMagics) write(w io.Writer) { - writeString(w, m.clientVersion) - writeString(w, m.serverVersion) - writeString(w, m.clientKexInit) - writeString(w, m.serverKexInit) -} - -// 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) - - // Client runs the client-side key agreement. Caller is - // responsible for verifying the host key signature. - Client(p packetConn, rand io.Reader, magics *handshakeMagics) (*kexResult, error) -} - -// dhGroup is a multiplicative group suitable for implementing Diffie-Hellman key agreement. -type dhGroup struct { - g, p *big.Int -} - -func (group *dhGroup) diffieHellman(theirPublic, myPrivate *big.Int) (*big.Int, error) { - if theirPublic.Sign() <= 0 || theirPublic.Cmp(group.p) >= 0 { - return nil, errors.New("ssh: DH parameter out of bounds") - } - return new(big.Int).Exp(theirPublic, myPrivate, group.p), nil -} - -func (group *dhGroup) Client(c packetConn, randSource io.Reader, magics *handshakeMagics) (*kexResult, error) { - hashFunc := crypto.SHA1 - - x, err := rand.Int(randSource, group.p) - if err != nil { - return nil, err - } - X := new(big.Int).Exp(group.g, x, group.p) - kexDHInit := kexDHInitMsg{ - X: X, - } - if err := c.writePacket(Marshal(&kexDHInit)); err != nil { - return nil, err - } - - packet, err := c.readPacket() - if err != nil { - return nil, err - } - - var kexDHReply kexDHReplyMsg - if err = Unmarshal(packet, &kexDHReply); err != nil { - return nil, err - } - - kInt, err := group.diffieHellman(kexDHReply.Y, x) - if err != nil { - return nil, err - } - - h := hashFunc.New() - magics.write(h) - writeString(h, kexDHReply.HostKey) - writeInt(h, X) - writeInt(h, kexDHReply.Y) - K := make([]byte, intLength(kInt)) - marshalInt(K, kInt) - h.Write(K) - - return &kexResult{ - H: h.Sum(nil), - K: K, - HostKey: kexDHReply.HostKey, - Signature: kexDHReply.Signature, - Hash: crypto.SHA1, - }, nil -} - -func (group *dhGroup) Server(c packetConn, randSource io.Reader, magics *handshakeMagics, priv Signer) (result *kexResult, err error) { - hashFunc := crypto.SHA1 - packet, err := c.readPacket() - if err != nil { - return - } - var kexDHInit kexDHInitMsg - if err = Unmarshal(packet, &kexDHInit); err != nil { - return - } - - y, err := rand.Int(randSource, group.p) - if err != nil { - return - } - - Y := new(big.Int).Exp(group.g, y, group.p) - kInt, err := group.diffieHellman(kexDHInit.X, y) - if err != nil { - return nil, err - } - - hostKeyBytes := priv.PublicKey().Marshal() - - h := hashFunc.New() - magics.write(h) - writeString(h, hostKeyBytes) - writeInt(h, kexDHInit.X) - writeInt(h, Y) - - K := make([]byte, intLength(kInt)) - marshalInt(K, kInt) - h.Write(K) - - H := h.Sum(nil) - - // H is already a hash, but the hostkey signing will apply its - // own key-specific hash algorithm. - sig, err := signAndMarshal(priv, randSource, H) - if err != nil { - return nil, err - } - - kexDHReply := kexDHReplyMsg{ - HostKey: hostKeyBytes, - Y: Y, - Signature: sig, - } - packet = Marshal(&kexDHReply) - - err = c.writePacket(packet) - return &kexResult{ - H: H, - K: K, - HostKey: hostKeyBytes, - Signature: sig, - Hash: crypto.SHA1, - }, nil -} - -// ecdh performs Elliptic Curve Diffie-Hellman key exchange as -// described in RFC 5656, section 4. -type ecdh struct { - curve elliptic.Curve -} - -func (kex *ecdh) Client(c packetConn, rand io.Reader, magics *handshakeMagics) (*kexResult, error) { - ephKey, err := ecdsa.GenerateKey(kex.curve, rand) - if err != nil { - return nil, err - } - - kexInit := kexECDHInitMsg{ - ClientPubKey: elliptic.Marshal(kex.curve, ephKey.PublicKey.X, ephKey.PublicKey.Y), - } - - serialized := Marshal(&kexInit) - if err := c.writePacket(serialized); err != nil { - return nil, err - } - - packet, err := c.readPacket() - if err != nil { - return nil, err - } - - var reply kexECDHReplyMsg - if err = Unmarshal(packet, &reply); err != nil { - return nil, err - } - - x, y, err := unmarshalECKey(kex.curve, reply.EphemeralPubKey) - if err != nil { - return nil, err - } - - // generate shared secret - secret, _ := kex.curve.ScalarMult(x, y, ephKey.D.Bytes()) - - h := ecHash(kex.curve).New() - magics.write(h) - writeString(h, reply.HostKey) - writeString(h, kexInit.ClientPubKey) - writeString(h, reply.EphemeralPubKey) - K := make([]byte, intLength(secret)) - marshalInt(K, secret) - h.Write(K) - - return &kexResult{ - H: h.Sum(nil), - K: K, - HostKey: reply.HostKey, - Signature: reply.Signature, - Hash: ecHash(kex.curve), - }, nil -} - -// unmarshalECKey parses and checks an EC key. -func unmarshalECKey(curve elliptic.Curve, pubkey []byte) (x, y *big.Int, err error) { - x, y = elliptic.Unmarshal(curve, pubkey) - if x == nil { - return nil, nil, errors.New("ssh: elliptic.Unmarshal failure") - } - if !validateECPublicKey(curve, x, y) { - return nil, nil, errors.New("ssh: public key not on curve") - } - return x, y, nil -} - -// validateECPublicKey checks that the point is a valid public key for -// the given curve. See [SEC1], 3.2.2 -func validateECPublicKey(curve elliptic.Curve, x, y *big.Int) bool { - if x.Sign() == 0 && y.Sign() == 0 { - return false - } - - if x.Cmp(curve.Params().P) >= 0 { - return false - } - - if y.Cmp(curve.Params().P) >= 0 { - return false - } - - if !curve.IsOnCurve(x, y) { - return false - } - - // We don't check if N * PubKey == 0, since - // - // - the NIST curves have cofactor = 1, so this is implicit. - // (We don't foresee an implementation that supports non NIST - // curves) - // - // - for ephemeral keys, we don't need to worry about small - // subgroup attacks. - return true -} - -func (kex *ecdh) Server(c packetConn, rand io.Reader, magics *handshakeMagics, priv Signer) (result *kexResult, err error) { - packet, err := c.readPacket() - if err != nil { - return nil, err - } - - var kexECDHInit kexECDHInitMsg - if err = Unmarshal(packet, &kexECDHInit); err != nil { - return nil, err - } - - clientX, clientY, err := unmarshalECKey(kex.curve, kexECDHInit.ClientPubKey) - if err != nil { - return nil, err - } - - // We could cache this key across multiple users/multiple - // connection attempts, but the benefit is small. OpenSSH - // generates a new key for each incoming connection. - ephKey, err := ecdsa.GenerateKey(kex.curve, rand) - if err != nil { - return nil, err - } - - hostKeyBytes := priv.PublicKey().Marshal() - - serializedEphKey := elliptic.Marshal(kex.curve, ephKey.PublicKey.X, ephKey.PublicKey.Y) - - // generate shared secret - secret, _ := kex.curve.ScalarMult(clientX, clientY, ephKey.D.Bytes()) - - h := ecHash(kex.curve).New() - magics.write(h) - writeString(h, hostKeyBytes) - writeString(h, kexECDHInit.ClientPubKey) - writeString(h, serializedEphKey) - - K := make([]byte, intLength(secret)) - marshalInt(K, secret) - h.Write(K) - - H := h.Sum(nil) - - // H is already a hash, but the hostkey signing will apply its - // own key-specific hash algorithm. - sig, err := signAndMarshal(priv, rand, H) - if err != nil { - return nil, err - } - - reply := kexECDHReplyMsg{ - EphemeralPubKey: serializedEphKey, - HostKey: hostKeyBytes, - Signature: sig, - } - - serialized := Marshal(&reply) - if err := c.writePacket(serialized); err != nil { - return nil, err - } - - return &kexResult{ - H: H, - K: K, - HostKey: reply.HostKey, - Signature: sig, - Hash: ecHash(kex.curve), - }, nil -} - -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. - p, _ := new(big.Int).SetString("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF", 16) - kexAlgoMap[kexAlgoDH1SHA1] = &dhGroup{ - g: new(big.Int).SetInt64(2), - p: p, - } - - // 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, - } - - kexAlgoMap[kexAlgoECDH521] = &ecdh{elliptic.P521()} - kexAlgoMap[kexAlgoECDH384] = &ecdh{elliptic.P384()} - kexAlgoMap[kexAlgoECDH256] = &ecdh{elliptic.P256()} - kexAlgoMap[kexAlgoCurve25519SHA256] = &curve25519sha256{} -} - -// 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 -type curve25519sha256 struct{} - -type curve25519KeyPair struct { - priv [32]byte - pub [32]byte -} - -func (kp *curve25519KeyPair) generate(rand io.Reader) error { - if _, err := io.ReadFull(rand, kp.priv[:]); err != nil { - return err - } - curve25519.ScalarBaseMult(&kp.pub, &kp.priv) - return nil -} - -// curve25519Zeros is just an array of 32 zero bytes so that we have something -// convenient to compare against in order to reject curve25519 points with the -// wrong order. -var curve25519Zeros [32]byte - -func (kex *curve25519sha256) Client(c packetConn, rand io.Reader, magics *handshakeMagics) (*kexResult, error) { - var kp curve25519KeyPair - if err := kp.generate(rand); err != nil { - return nil, err - } - if err := c.writePacket(Marshal(&kexECDHInitMsg{kp.pub[:]})); err != nil { - return nil, err - } - - packet, err := c.readPacket() - if err != nil { - return nil, err - } - - var reply kexECDHReplyMsg - if err = Unmarshal(packet, &reply); err != nil { - return nil, err - } - if len(reply.EphemeralPubKey) != 32 { - return nil, errors.New("ssh: peer's curve25519 public value has wrong length") - } - - var servPub, secret [32]byte - copy(servPub[:], reply.EphemeralPubKey) - curve25519.ScalarMult(&secret, &kp.priv, &servPub) - if subtle.ConstantTimeCompare(secret[:], curve25519Zeros[:]) == 1 { - return nil, errors.New("ssh: peer's curve25519 public value has wrong order") - } - - h := crypto.SHA256.New() - magics.write(h) - writeString(h, reply.HostKey) - writeString(h, kp.pub[:]) - writeString(h, reply.EphemeralPubKey) - - kInt := new(big.Int).SetBytes(secret[:]) - K := make([]byte, intLength(kInt)) - marshalInt(K, kInt) - h.Write(K) - - return &kexResult{ - H: h.Sum(nil), - K: K, - HostKey: reply.HostKey, - Signature: reply.Signature, - Hash: crypto.SHA256, - }, nil -} - -func (kex *curve25519sha256) Server(c packetConn, rand io.Reader, magics *handshakeMagics, priv Signer) (result *kexResult, err error) { - packet, err := c.readPacket() - if err != nil { - return - } - var kexInit kexECDHInitMsg - if err = Unmarshal(packet, &kexInit); err != nil { - return - } - - if len(kexInit.ClientPubKey) != 32 { - return nil, errors.New("ssh: peer's curve25519 public value has wrong length") - } - - var kp curve25519KeyPair - if err := kp.generate(rand); err != nil { - return nil, err - } - - var clientPub, secret [32]byte - copy(clientPub[:], kexInit.ClientPubKey) - curve25519.ScalarMult(&secret, &kp.priv, &clientPub) - if subtle.ConstantTimeCompare(secret[:], curve25519Zeros[:]) == 1 { - return nil, errors.New("ssh: peer's curve25519 public value has wrong order") - } - - hostKeyBytes := priv.PublicKey().Marshal() - - h := crypto.SHA256.New() - magics.write(h) - writeString(h, hostKeyBytes) - writeString(h, kexInit.ClientPubKey) - writeString(h, kp.pub[:]) - - kInt := new(big.Int).SetBytes(secret[:]) - K := make([]byte, intLength(kInt)) - marshalInt(K, kInt) - h.Write(K) - - H := h.Sum(nil) - - sig, err := signAndMarshal(priv, rand, H) - if err != nil { - return nil, err - } - - reply := kexECDHReplyMsg{ - EphemeralPubKey: kp.pub[:], - HostKey: hostKeyBytes, - Signature: sig, - } - if err := c.writePacket(Marshal(&reply)); err != nil { - return nil, err - } - return &kexResult{ - H: H, - K: K, - HostKey: hostKeyBytes, - Signature: sig, - Hash: crypto.SHA256, - }, nil -} diff --git a/vendor/golang.org/x/crypto/ssh/kex_test.go b/vendor/golang.org/x/crypto/ssh/kex_test.go deleted file mode 100644 index 12ca0ac..0000000 --- a/vendor/golang.org/x/crypto/ssh/kex_test.go +++ /dev/null @@ -1,50 +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 ssh - -// Key exchange tests. - -import ( - "crypto/rand" - "reflect" - "testing" -) - -func TestKexes(t *testing.T) { - type kexResultErr struct { - result *kexResult - err error - } - - for name, kex := range kexAlgoMap { - a, b := memPipe() - - s := make(chan kexResultErr, 1) - c := make(chan kexResultErr, 1) - var magics handshakeMagics - go func() { - r, e := kex.Client(a, rand.Reader, &magics) - a.Close() - c <- kexResultErr{r, e} - }() - go func() { - r, e := kex.Server(b, rand.Reader, &magics, testSigners["ecdsa"]) - b.Close() - s <- kexResultErr{r, e} - }() - - clientRes := <-c - serverRes := <-s - if clientRes.err != nil { - t.Errorf("client: %v", clientRes.err) - } - if serverRes.err != nil { - t.Errorf("server: %v", serverRes.err) - } - if !reflect.DeepEqual(clientRes.result, serverRes.result) { - t.Errorf("kex %q: mismatch %#v, %#v", name, clientRes.result, serverRes.result) - } - } -} diff --git a/vendor/golang.org/x/crypto/ssh/keys.go b/vendor/golang.org/x/crypto/ssh/keys.go deleted file mode 100644 index d6167e7..0000000 --- a/vendor/golang.org/x/crypto/ssh/keys.go +++ /dev/null @@ -1,846 +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. - -package ssh - -import ( - "bytes" - "crypto" - "crypto/dsa" - "crypto/ecdsa" - "crypto/elliptic" - "crypto/rsa" - "crypto/x509" - "encoding/asn1" - "encoding/base64" - "encoding/pem" - "errors" - "fmt" - "io" - "math/big" - "strings" - - "golang.org/x/crypto/ed25519" -) - -// These constants represent the algorithm names for key types supported by this -// package. -const ( - KeyAlgoRSA = "ssh-rsa" - KeyAlgoDSA = "ssh-dss" - KeyAlgoECDSA256 = "ecdsa-sha2-nistp256" - KeyAlgoECDSA384 = "ecdsa-sha2-nistp384" - KeyAlgoECDSA521 = "ecdsa-sha2-nistp521" - KeyAlgoED25519 = "ssh-ed25519" -) - -// parsePubKey parses a public key of the given algorithm. -// Use ParsePublicKey for keys with prepended algorithm. -func parsePubKey(in []byte, algo string) (pubKey PublicKey, rest []byte, err error) { - switch algo { - case KeyAlgoRSA: - return parseRSA(in) - case KeyAlgoDSA: - return parseDSA(in) - case KeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoECDSA521: - return parseECDSA(in) - case KeyAlgoED25519: - return parseED25519(in) - case CertAlgoRSAv01, CertAlgoDSAv01, CertAlgoECDSA256v01, CertAlgoECDSA384v01, CertAlgoECDSA521v01, CertAlgoED25519v01: - cert, err := parseCert(in, certToPrivAlgo(algo)) - if err != nil { - return nil, nil, err - } - return cert, nil, nil - } - return nil, nil, fmt.Errorf("ssh: unknown key algorithm: %v", algo) -} - -// parseAuthorizedKey parses a public key in OpenSSH authorized_keys format -// (see sshd(8) manual page) once the options and key type fields have been -// removed. -func parseAuthorizedKey(in []byte) (out PublicKey, comment string, err error) { - in = bytes.TrimSpace(in) - - i := bytes.IndexAny(in, " \t") - if i == -1 { - i = len(in) - } - base64Key := in[:i] - - key := make([]byte, base64.StdEncoding.DecodedLen(len(base64Key))) - n, err := base64.StdEncoding.Decode(key, base64Key) - if err != nil { - return nil, "", err - } - key = key[:n] - out, err = ParsePublicKey(key) - if err != nil { - return nil, "", err - } - comment = string(bytes.TrimSpace(in[i:])) - return out, comment, nil -} - -// ParseKnownHosts parses an entry in the format of the known_hosts file. -// -// The known_hosts format is documented in the sshd(8) manual page. This -// function will parse a single entry from in. On successful return, marker -// will contain the optional marker value (i.e. "cert-authority" or "revoked") -// or else be empty, hosts will contain the hosts that this entry matches, -// pubKey will contain the public key and comment will contain any trailing -// comment at the end of the line. See the sshd(8) manual page for the various -// forms that a host string can take. -// -// The unparsed remainder of the input will be returned in rest. This function -// can be called repeatedly to parse multiple entries. -// -// If no entries were found in the input then err will be io.EOF. Otherwise a -// non-nil err value indicates a parse error. -func ParseKnownHosts(in []byte) (marker string, hosts []string, pubKey PublicKey, comment string, rest []byte, err error) { - for len(in) > 0 { - end := bytes.IndexByte(in, '\n') - if end != -1 { - rest = in[end+1:] - in = in[:end] - } else { - rest = nil - } - - end = bytes.IndexByte(in, '\r') - if end != -1 { - in = in[:end] - } - - in = bytes.TrimSpace(in) - if len(in) == 0 || in[0] == '#' { - in = rest - continue - } - - i := bytes.IndexAny(in, " \t") - if i == -1 { - in = rest - continue - } - - // Strip out the begining of the known_host key. - // This is either an optional marker or a (set of) hostname(s). - keyFields := bytes.Fields(in) - if len(keyFields) < 3 || len(keyFields) > 5 { - return "", nil, nil, "", nil, errors.New("ssh: invalid entry in known_hosts data") - } - - // keyFields[0] is either "@cert-authority", "@revoked" or a comma separated - // list of hosts - marker := "" - if keyFields[0][0] == '@' { - marker = string(keyFields[0][1:]) - keyFields = keyFields[1:] - } - - hosts := string(keyFields[0]) - // keyFields[1] contains the key type (e.g. “ssh-rsa”). - // However, that information is duplicated inside the - // base64-encoded key and so is ignored here. - - key := bytes.Join(keyFields[2:], []byte(" ")) - if pubKey, comment, err = parseAuthorizedKey(key); err != nil { - return "", nil, nil, "", nil, err - } - - return marker, strings.Split(hosts, ","), pubKey, comment, rest, nil - } - - return "", nil, nil, "", nil, io.EOF -} - -// ParseAuthorizedKeys parses a public key from an authorized_keys -// file used in OpenSSH according to the sshd(8) manual page. -func ParseAuthorizedKey(in []byte) (out PublicKey, comment string, options []string, rest []byte, err error) { - for len(in) > 0 { - end := bytes.IndexByte(in, '\n') - if end != -1 { - rest = in[end+1:] - in = in[:end] - } else { - rest = nil - } - - end = bytes.IndexByte(in, '\r') - if end != -1 { - in = in[:end] - } - - in = bytes.TrimSpace(in) - if len(in) == 0 || in[0] == '#' { - in = rest - continue - } - - i := bytes.IndexAny(in, " \t") - if i == -1 { - in = rest - continue - } - - if out, comment, err = parseAuthorizedKey(in[i:]); err == nil { - return out, comment, options, rest, nil - } - - // No key type recognised. Maybe there's an options field at - // the beginning. - var b byte - inQuote := false - var candidateOptions []string - optionStart := 0 - for i, b = range in { - isEnd := !inQuote && (b == ' ' || b == '\t') - if (b == ',' && !inQuote) || isEnd { - if i-optionStart > 0 { - candidateOptions = append(candidateOptions, string(in[optionStart:i])) - } - optionStart = i + 1 - } - if isEnd { - break - } - if b == '"' && (i == 0 || (i > 0 && in[i-1] != '\\')) { - inQuote = !inQuote - } - } - for i < len(in) && (in[i] == ' ' || in[i] == '\t') { - i++ - } - if i == len(in) { - // Invalid line: unmatched quote - in = rest - continue - } - - in = in[i:] - i = bytes.IndexAny(in, " \t") - if i == -1 { - in = rest - continue - } - - if out, comment, err = parseAuthorizedKey(in[i:]); err == nil { - options = candidateOptions - return out, comment, options, rest, nil - } - - in = rest - continue - } - - return nil, "", nil, nil, errors.New("ssh: no key found") -} - -// ParsePublicKey parses an SSH public key formatted for use in -// the SSH wire protocol according to RFC 4253, section 6.6. -func ParsePublicKey(in []byte) (out PublicKey, err error) { - algo, in, ok := parseString(in) - if !ok { - return nil, errShortRead - } - var rest []byte - out, rest, err = parsePubKey(in, string(algo)) - if len(rest) > 0 { - return nil, errors.New("ssh: trailing junk in public key") - } - - return out, err -} - -// MarshalAuthorizedKey serializes key for inclusion in an OpenSSH -// authorized_keys file. The return value ends with newline. -func MarshalAuthorizedKey(key PublicKey) []byte { - b := &bytes.Buffer{} - b.WriteString(key.Type()) - b.WriteByte(' ') - e := base64.NewEncoder(base64.StdEncoding, b) - e.Write(key.Marshal()) - e.Close() - b.WriteByte('\n') - return b.Bytes() -} - -// PublicKey is an abstraction of different types of public keys. -type PublicKey interface { - // Type returns the key's type, e.g. "ssh-rsa". - Type() string - - // Marshal returns the serialized key data in SSH wire format, - // with the name prefix. - Marshal() []byte - - // Verify that sig is a signature on the given data using this - // key. This function will hash the data appropriately first. - Verify(data []byte, sig *Signature) error -} - -// A Signer can create signatures that verify against a public key. -type Signer interface { - // PublicKey returns an associated PublicKey instance. - PublicKey() PublicKey - - // Sign returns raw signature for the given data. This method - // will apply the hash specified for the keytype to the data. - Sign(rand io.Reader, data []byte) (*Signature, error) -} - -type rsaPublicKey rsa.PublicKey - -func (r *rsaPublicKey) Type() string { - return "ssh-rsa" -} - -// parseRSA parses an RSA key according to RFC 4253, section 6.6. -func parseRSA(in []byte) (out PublicKey, rest []byte, err error) { - var w struct { - E *big.Int - N *big.Int - Rest []byte `ssh:"rest"` - } - if err := Unmarshal(in, &w); err != nil { - return nil, nil, err - } - - if w.E.BitLen() > 24 { - return nil, nil, errors.New("ssh: exponent too large") - } - e := w.E.Int64() - if e < 3 || e&1 == 0 { - return nil, nil, errors.New("ssh: incorrect exponent") - } - - var key rsa.PublicKey - key.E = int(e) - key.N = w.N - return (*rsaPublicKey)(&key), w.Rest, nil -} - -func (r *rsaPublicKey) Marshal() []byte { - e := new(big.Int).SetInt64(int64(r.E)) - // RSA publickey struct layout should match the struct used by - // parseRSACert in the x/crypto/ssh/agent package. - wirekey := struct { - Name string - E *big.Int - N *big.Int - }{ - KeyAlgoRSA, - e, - r.N, - } - return Marshal(&wirekey) -} - -func (r *rsaPublicKey) Verify(data []byte, sig *Signature) error { - if sig.Format != r.Type() { - return fmt.Errorf("ssh: signature type %s for key type %s", sig.Format, r.Type()) - } - h := crypto.SHA1.New() - h.Write(data) - digest := h.Sum(nil) - return rsa.VerifyPKCS1v15((*rsa.PublicKey)(r), crypto.SHA1, digest, sig.Blob) -} - -type dsaPublicKey dsa.PublicKey - -func (r *dsaPublicKey) Type() string { - return "ssh-dss" -} - -// parseDSA parses an DSA key according to RFC 4253, section 6.6. -func parseDSA(in []byte) (out PublicKey, rest []byte, err error) { - var w struct { - P, Q, G, Y *big.Int - Rest []byte `ssh:"rest"` - } - if err := Unmarshal(in, &w); err != nil { - return nil, nil, err - } - - key := &dsaPublicKey{ - Parameters: dsa.Parameters{ - P: w.P, - Q: w.Q, - G: w.G, - }, - Y: w.Y, - } - return key, w.Rest, nil -} - -func (k *dsaPublicKey) Marshal() []byte { - // DSA publickey struct layout should match the struct used by - // parseDSACert in the x/crypto/ssh/agent package. - w := struct { - Name string - P, Q, G, Y *big.Int - }{ - k.Type(), - k.P, - k.Q, - k.G, - k.Y, - } - - return Marshal(&w) -} - -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.Write(data) - digest := h.Sum(nil) - - // Per RFC 4253, section 6.6, - // The value for 'dss_signature_blob' is encoded as a string containing - // r, followed by s (which are 160-bit integers, without lengths or - // padding, unsigned, and in network byte order). - // For DSS purposes, sig.Blob should be exactly 40 bytes in length. - if len(sig.Blob) != 40 { - return errors.New("ssh: DSA signature parse error") - } - r := new(big.Int).SetBytes(sig.Blob[:20]) - s := new(big.Int).SetBytes(sig.Blob[20:]) - if dsa.Verify((*dsa.PublicKey)(k), digest, r, s) { - return nil - } - return errors.New("ssh: signature did not verify") -} - -type dsaPrivateKey struct { - *dsa.PrivateKey -} - -func (k *dsaPrivateKey) PublicKey() PublicKey { - return (*dsaPublicKey)(&k.PrivateKey.PublicKey) -} - -func (k *dsaPrivateKey) Sign(rand io.Reader, data []byte) (*Signature, error) { - h := crypto.SHA1.New() - h.Write(data) - digest := h.Sum(nil) - r, s, err := dsa.Sign(rand, k.PrivateKey, digest) - if err != nil { - return nil, err - } - - sig := make([]byte, 40) - rb := r.Bytes() - sb := s.Bytes() - - copy(sig[20-len(rb):20], rb) - copy(sig[40-len(sb):], sb) - - return &Signature{ - Format: k.PublicKey().Type(), - Blob: sig, - }, nil -} - -type ecdsaPublicKey ecdsa.PublicKey - -func (key *ecdsaPublicKey) Type() string { - return "ecdsa-sha2-" + key.nistID() -} - -func (key *ecdsaPublicKey) nistID() string { - switch key.Params().BitSize { - case 256: - return "nistp256" - case 384: - return "nistp384" - case 521: - return "nistp521" - } - panic("ssh: unsupported ecdsa key size") -} - -type ed25519PublicKey ed25519.PublicKey - -func (key ed25519PublicKey) Type() string { - return KeyAlgoED25519 -} - -func parseED25519(in []byte) (out PublicKey, rest []byte, err error) { - var w struct { - KeyBytes []byte - Rest []byte `ssh:"rest"` - } - - if err := Unmarshal(in, &w); err != nil { - return nil, nil, err - } - - key := ed25519.PublicKey(w.KeyBytes) - - return (ed25519PublicKey)(key), w.Rest, nil -} - -func (key ed25519PublicKey) Marshal() []byte { - w := struct { - Name string - KeyBytes []byte - }{ - KeyAlgoED25519, - []byte(key), - } - return Marshal(&w) -} - -func (key ed25519PublicKey) Verify(b []byte, sig *Signature) error { - if sig.Format != key.Type() { - return fmt.Errorf("ssh: signature type %s for key type %s", sig.Format, key.Type()) - } - - edKey := (ed25519.PublicKey)(key) - if ok := ed25519.Verify(edKey, b, sig.Blob); !ok { - return errors.New("ssh: signature did not verify") - } - - return nil -} - -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 { - Curve string - KeyBytes []byte - Rest []byte `ssh:"rest"` - } - - if err := Unmarshal(in, &w); err != nil { - return nil, nil, err - } - - key := new(ecdsa.PublicKey) - - switch w.Curve { - case "nistp256": - key.Curve = elliptic.P256() - case "nistp384": - key.Curve = elliptic.P384() - case "nistp521": - key.Curve = elliptic.P521() - default: - return nil, nil, errors.New("ssh: unsupported curve") - } - - key.X, key.Y = elliptic.Unmarshal(key.Curve, w.KeyBytes) - if key.X == nil || key.Y == nil { - return nil, nil, errors.New("ssh: invalid curve point") - } - return (*ecdsaPublicKey)(key), w.Rest, nil -} - -func (key *ecdsaPublicKey) Marshal() []byte { - // See RFC 5656, section 3.1. - keyBytes := elliptic.Marshal(key.Curve, key.X, key.Y) - // ECDSA publickey struct layout should match the struct used by - // parseECDSACert in the x/crypto/ssh/agent package. - w := struct { - Name string - ID string - Key []byte - }{ - key.Type(), - key.nistID(), - keyBytes, - } - - return Marshal(&w) -} - -func (key *ecdsaPublicKey) Verify(data []byte, sig *Signature) error { - if sig.Format != key.Type() { - return fmt.Errorf("ssh: signature type %s for key type %s", sig.Format, key.Type()) - } - - h := ecHash(key.Curve).New() - h.Write(data) - digest := h.Sum(nil) - - // Per RFC 5656, section 3.1.2, - // The ecdsa_signature_blob value has the following specific encoding: - // mpint r - // mpint s - var ecSig struct { - R *big.Int - S *big.Int - } - - if err := Unmarshal(sig.Blob, &ecSig); err != nil { - return err - } - - if ecdsa.Verify((*ecdsa.PublicKey)(key), digest, ecSig.R, ecSig.S) { - return nil - } - return errors.New("ssh: signature did not verify") -} - -// NewSignerFromKey takes an *rsa.PrivateKey, *dsa.PrivateKey, -// *ecdsa.PrivateKey or any other crypto.Signer and returns a corresponding -// Signer instance. ECDSA keys must use P-256, P-384 or P-521. -func NewSignerFromKey(key interface{}) (Signer, error) { - switch key := key.(type) { - case crypto.Signer: - return NewSignerFromSigner(key) - case *dsa.PrivateKey: - return &dsaPrivateKey{key}, nil - default: - return nil, fmt.Errorf("ssh: unsupported key type %T", key) - } -} - -type wrappedSigner struct { - signer crypto.Signer - pubKey PublicKey -} - -// NewSignerFromSigner takes any crypto.Signer implementation and -// returns a corresponding Signer interface. This can be used, for -// example, with keys kept in hardware modules. -func NewSignerFromSigner(signer crypto.Signer) (Signer, error) { - pubKey, err := NewPublicKey(signer.Public()) - if err != nil { - return nil, err - } - - return &wrappedSigner{signer, pubKey}, nil -} - -func (s *wrappedSigner) PublicKey() PublicKey { - return s.pubKey -} - -func (s *wrappedSigner) Sign(rand io.Reader, data []byte) (*Signature, error) { - var hashFunc crypto.Hash - - switch key := s.pubKey.(type) { - case *rsaPublicKey, *dsaPublicKey: - hashFunc = crypto.SHA1 - case *ecdsaPublicKey: - hashFunc = ecHash(key.Curve) - case ed25519PublicKey: - default: - return nil, fmt.Errorf("ssh: unsupported key type %T", key) - } - - var digest []byte - if hashFunc != 0 { - h := hashFunc.New() - h.Write(data) - digest = h.Sum(nil) - } else { - digest = data - } - - signature, err := s.signer.Sign(rand, digest, hashFunc) - if err != nil { - return nil, err - } - - // crypto.Signer.Sign is expected to return an ASN.1-encoded signature - // for ECDSA and DSA, but that's not the encoding expected by SSH, so - // re-encode. - switch s.pubKey.(type) { - case *ecdsaPublicKey, *dsaPublicKey: - type asn1Signature struct { - R, S *big.Int - } - asn1Sig := new(asn1Signature) - _, err := asn1.Unmarshal(signature, asn1Sig) - if err != nil { - return nil, err - } - - switch s.pubKey.(type) { - case *ecdsaPublicKey: - signature = Marshal(asn1Sig) - - case *dsaPublicKey: - signature = make([]byte, 40) - r := asn1Sig.R.Bytes() - s := asn1Sig.S.Bytes() - copy(signature[20-len(r):20], r) - copy(signature[40-len(s):40], s) - } - } - - return &Signature{ - Format: s.pubKey.Type(), - Blob: signature, - }, nil -} - -// NewPublicKey takes an *rsa.PublicKey, *dsa.PublicKey, *ecdsa.PublicKey, -// ed25519.PublicKey, or any other crypto.Signer and returns a corresponding -// Signer instance. ECDSA keys must use P-256, P-384 or P-521. -func NewPublicKey(key interface{}) (PublicKey, error) { - switch key := key.(type) { - case *rsa.PublicKey: - return (*rsaPublicKey)(key), nil - case *ecdsa.PublicKey: - if !supportedEllipticCurve(key.Curve) { - return nil, errors.New("ssh: only P-256, P-384 and P-521 EC keys are supported.") - } - return (*ecdsaPublicKey)(key), nil - case *dsa.PublicKey: - return (*dsaPublicKey)(key), nil - case ed25519.PublicKey: - return (ed25519PublicKey)(key), nil - default: - return nil, fmt.Errorf("ssh: unsupported key type %T", key) - } -} - -// ParsePrivateKey returns a Signer from a PEM encoded private key. It supports -// the same keys as ParseRawPrivateKey. -func ParsePrivateKey(pemBytes []byte) (Signer, error) { - key, err := ParseRawPrivateKey(pemBytes) - if err != nil { - return nil, err - } - - return NewSignerFromKey(key) -} - -// ParseRawPrivateKey returns a private key from a PEM encoded private key. It -// supports RSA (PKCS#1), DSA (OpenSSL), and ECDSA private keys. -func ParseRawPrivateKey(pemBytes []byte) (interface{}, error) { - block, _ := pem.Decode(pemBytes) - if block == nil { - return nil, errors.New("ssh: no key found") - } - - switch block.Type { - case "RSA PRIVATE KEY": - return x509.ParsePKCS1PrivateKey(block.Bytes) - case "EC PRIVATE KEY": - return x509.ParseECPrivateKey(block.Bytes) - case "DSA PRIVATE KEY": - return ParseDSAPrivateKey(block.Bytes) - case "OPENSSH PRIVATE KEY": - return parseOpenSSHPrivateKey(block.Bytes) - default: - return nil, fmt.Errorf("ssh: unsupported key type %q", block.Type) - } -} - -// ParseDSAPrivateKey returns a DSA private key from its ASN.1 DER encoding, as -// specified by the OpenSSL DSA man page. -func ParseDSAPrivateKey(der []byte) (*dsa.PrivateKey, error) { - var k struct { - Version int - P *big.Int - Q *big.Int - G *big.Int - Priv *big.Int - Pub *big.Int - } - rest, err := asn1.Unmarshal(der, &k) - if err != nil { - return nil, errors.New("ssh: failed to parse DSA key: " + err.Error()) - } - if len(rest) > 0 { - return nil, errors.New("ssh: garbage after DSA key") - } - - return &dsa.PrivateKey{ - PublicKey: dsa.PublicKey{ - Parameters: dsa.Parameters{ - P: k.P, - Q: k.Q, - G: k.G, - }, - Y: k.Priv, - }, - X: k.Pub, - }, nil -} - -// Implemented based on the documentation at -// https://github.com/openssh/openssh-portable/blob/master/PROTOCOL.key -func parseOpenSSHPrivateKey(key []byte) (*ed25519.PrivateKey, error) { - magic := append([]byte("openssh-key-v1"), 0) - if !bytes.Equal(magic, key[0:len(magic)]) { - return nil, errors.New("ssh: invalid openssh private key format") - } - remaining := key[len(magic):] - - var w struct { - CipherName string - KdfName string - KdfOpts string - NumKeys uint32 - PubKey []byte - PrivKeyBlock []byte - } - - if err := Unmarshal(remaining, &w); err != nil { - return nil, err - } - - pk1 := struct { - Check1 uint32 - Check2 uint32 - Keytype string - Pub []byte - Priv []byte - Comment string - Pad []byte `ssh:"rest"` - }{} - - if err := Unmarshal(w.PrivKeyBlock, &pk1); err != nil { - return nil, err - } - - if pk1.Check1 != pk1.Check2 { - return nil, errors.New("ssh: checkint mismatch") - } - - // we only handle ed25519 keys currently - if pk1.Keytype != KeyAlgoED25519 { - return nil, errors.New("ssh: unhandled key type") - } - - for i, b := range pk1.Pad { - if int(b) != i+1 { - return nil, errors.New("ssh: padding not as expected") - } - } - - if len(pk1.Priv) != ed25519.PrivateKeySize { - return nil, errors.New("ssh: private key unexpected length") - } - - pk := ed25519.PrivateKey(make([]byte, ed25519.PrivateKeySize)) - copy(pk, pk1.Priv) - return &pk, nil -} diff --git a/vendor/golang.org/x/crypto/ssh/keys_test.go b/vendor/golang.org/x/crypto/ssh/keys_test.go deleted file mode 100644 index 4c4c5be..0000000 --- a/vendor/golang.org/x/crypto/ssh/keys_test.go +++ /dev/null @@ -1,440 +0,0 @@ -// 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 ssh - -import ( - "bytes" - "crypto/dsa" - "crypto/ecdsa" - "crypto/elliptic" - "crypto/rand" - "crypto/rsa" - "encoding/base64" - "fmt" - "reflect" - "strings" - "testing" - - "golang.org/x/crypto/ed25519" - "golang.org/x/crypto/ssh/testdata" -) - -func rawKey(pub PublicKey) interface{} { - switch k := pub.(type) { - case *rsaPublicKey: - return (*rsa.PublicKey)(k) - case *dsaPublicKey: - return (*dsa.PublicKey)(k) - case *ecdsaPublicKey: - return (*ecdsa.PublicKey)(k) - case ed25519PublicKey: - return (ed25519.PublicKey)(k) - case *Certificate: - return k - } - panic("unknown key type") -} - -func TestKeyMarshalParse(t *testing.T) { - for _, priv := range testSigners { - pub := priv.PublicKey() - roundtrip, err := ParsePublicKey(pub.Marshal()) - if err != nil { - t.Errorf("ParsePublicKey(%T): %v", pub, err) - } - - k1 := rawKey(pub) - k2 := rawKey(roundtrip) - - if !reflect.DeepEqual(k1, k2) { - t.Errorf("got %#v in roundtrip, want %#v", k2, k1) - } - } -} - -func TestUnsupportedCurves(t *testing.T) { - raw, err := ecdsa.GenerateKey(elliptic.P224(), rand.Reader) - if err != nil { - t.Fatalf("GenerateKey: %v", err) - } - - if _, err = NewSignerFromKey(raw); err == nil || !strings.Contains(err.Error(), "only P-256") { - t.Fatalf("NewPrivateKey should not succeed with P-224, got: %v", err) - } - - if _, err = NewPublicKey(&raw.PublicKey); err == nil || !strings.Contains(err.Error(), "only P-256") { - t.Fatalf("NewPublicKey should not succeed with P-224, got: %v", err) - } -} - -func TestNewPublicKey(t *testing.T) { - for _, k := range testSigners { - raw := rawKey(k.PublicKey()) - // Skip certificates, as NewPublicKey does not support them. - if _, ok := raw.(*Certificate); ok { - continue - } - pub, err := NewPublicKey(raw) - if err != nil { - t.Errorf("NewPublicKey(%#v): %v", raw, err) - } - if !reflect.DeepEqual(k.PublicKey(), pub) { - t.Errorf("NewPublicKey(%#v) = %#v, want %#v", raw, pub, k.PublicKey()) - } - } -} - -func TestKeySignVerify(t *testing.T) { - for _, priv := range testSigners { - pub := priv.PublicKey() - - data := []byte("sign me") - sig, err := priv.Sign(rand.Reader, data) - if err != nil { - t.Fatalf("Sign(%T): %v", priv, err) - } - - if err := pub.Verify(data, sig); err != nil { - t.Errorf("publicKey.Verify(%T): %v", priv, err) - } - sig.Blob[5]++ - if err := pub.Verify(data, sig); err == nil { - t.Errorf("publicKey.Verify on broken sig did not fail") - } - } -} - -func TestParseRSAPrivateKey(t *testing.T) { - key := testPrivateKeys["rsa"] - - rsa, ok := key.(*rsa.PrivateKey) - if !ok { - t.Fatalf("got %T, want *rsa.PrivateKey", rsa) - } - - if err := rsa.Validate(); err != nil { - t.Errorf("Validate: %v", err) - } -} - -func TestParseECPrivateKey(t *testing.T) { - key := testPrivateKeys["ecdsa"] - - ecKey, ok := key.(*ecdsa.PrivateKey) - if !ok { - t.Fatalf("got %T, want *ecdsa.PrivateKey", ecKey) - } - - if !validateECPublicKey(ecKey.Curve, ecKey.X, ecKey.Y) { - t.Fatalf("public key does not validate.") - } -} - -func TestParseDSA(t *testing.T) { - // We actually exercise the ParsePrivateKey codepath here, as opposed to - // using the ParseRawPrivateKey+NewSignerFromKey path that testdata_test.go - // uses. - s, err := ParsePrivateKey(testdata.PEMBytes["dsa"]) - if err != nil { - t.Fatalf("ParsePrivateKey returned error: %s", err) - } - - data := []byte("sign me") - sig, err := s.Sign(rand.Reader, data) - if err != nil { - t.Fatalf("dsa.Sign: %v", err) - } - - if err := s.PublicKey().Verify(data, sig); err != nil { - t.Errorf("Verify failed: %v", err) - } -} - -// Tests for authorized_keys parsing. - -// getTestKey returns a public key, and its base64 encoding. -func getTestKey() (PublicKey, string) { - k := testPublicKeys["rsa"] - - b := &bytes.Buffer{} - e := base64.NewEncoder(base64.StdEncoding, b) - e.Write(k.Marshal()) - e.Close() - - return k, b.String() -} - -func TestMarshalParsePublicKey(t *testing.T) { - pub, pubSerialized := getTestKey() - line := fmt.Sprintf("%s %s user@host", pub.Type(), pubSerialized) - - authKeys := MarshalAuthorizedKey(pub) - actualFields := strings.Fields(string(authKeys)) - if len(actualFields) == 0 { - t.Fatalf("failed authKeys: %v", authKeys) - } - - // drop the comment - expectedFields := strings.Fields(line)[0:2] - - if !reflect.DeepEqual(actualFields, expectedFields) { - t.Errorf("got %v, expected %v", actualFields, expectedFields) - } - - actPub, _, _, _, err := ParseAuthorizedKey([]byte(line)) - if err != nil { - t.Fatalf("cannot parse %v: %v", line, err) - } - if !reflect.DeepEqual(actPub, pub) { - t.Errorf("got %v, expected %v", actPub, pub) - } -} - -type authResult struct { - pubKey PublicKey - options []string - comments string - rest string - ok bool -} - -func testAuthorizedKeys(t *testing.T, authKeys []byte, expected []authResult) { - rest := authKeys - var values []authResult - for len(rest) > 0 { - var r authResult - var err error - r.pubKey, r.comments, r.options, rest, err = ParseAuthorizedKey(rest) - r.ok = (err == nil) - t.Log(err) - r.rest = string(rest) - values = append(values, r) - } - - if !reflect.DeepEqual(values, expected) { - t.Errorf("got %#v, expected %#v", values, expected) - } -} - -func TestAuthorizedKeyBasic(t *testing.T) { - pub, pubSerialized := getTestKey() - line := "ssh-rsa " + pubSerialized + " user@host" - testAuthorizedKeys(t, []byte(line), - []authResult{ - {pub, nil, "user@host", "", true}, - }) -} - -func TestAuth(t *testing.T) { - pub, pubSerialized := getTestKey() - authWithOptions := []string{ - `# comments to ignore before any keys...`, - ``, - `env="HOME=/home/root",no-port-forwarding ssh-rsa ` + pubSerialized + ` user@host`, - `# comments to ignore, along with a blank line`, - ``, - `env="HOME=/home/root2" ssh-rsa ` + pubSerialized + ` user2@host2`, - ``, - `# more comments, plus a invalid entry`, - `ssh-rsa data-that-will-not-parse user@host3`, - } - for _, eol := range []string{"\n", "\r\n"} { - authOptions := strings.Join(authWithOptions, eol) - rest2 := strings.Join(authWithOptions[3:], eol) - rest3 := strings.Join(authWithOptions[6:], eol) - testAuthorizedKeys(t, []byte(authOptions), []authResult{ - {pub, []string{`env="HOME=/home/root"`, "no-port-forwarding"}, "user@host", rest2, true}, - {pub, []string{`env="HOME=/home/root2"`}, "user2@host2", rest3, true}, - {nil, nil, "", "", false}, - }) - } -} - -func TestAuthWithQuotedSpaceInEnv(t *testing.T) { - pub, pubSerialized := getTestKey() - authWithQuotedSpaceInEnv := []byte(`env="HOME=/home/root dir",no-port-forwarding ssh-rsa ` + pubSerialized + ` user@host`) - testAuthorizedKeys(t, []byte(authWithQuotedSpaceInEnv), []authResult{ - {pub, []string{`env="HOME=/home/root dir"`, "no-port-forwarding"}, "user@host", "", true}, - }) -} - -func TestAuthWithQuotedCommaInEnv(t *testing.T) { - pub, pubSerialized := getTestKey() - authWithQuotedCommaInEnv := []byte(`env="HOME=/home/root,dir",no-port-forwarding ssh-rsa ` + pubSerialized + ` user@host`) - testAuthorizedKeys(t, []byte(authWithQuotedCommaInEnv), []authResult{ - {pub, []string{`env="HOME=/home/root,dir"`, "no-port-forwarding"}, "user@host", "", true}, - }) -} - -func TestAuthWithQuotedQuoteInEnv(t *testing.T) { - pub, pubSerialized := getTestKey() - authWithQuotedQuoteInEnv := []byte(`env="HOME=/home/\"root dir",no-port-forwarding` + "\t" + `ssh-rsa` + "\t" + pubSerialized + ` user@host`) - authWithDoubleQuotedQuote := []byte(`no-port-forwarding,env="HOME=/home/ \"root dir\"" ssh-rsa ` + pubSerialized + "\t" + `user@host`) - testAuthorizedKeys(t, []byte(authWithQuotedQuoteInEnv), []authResult{ - {pub, []string{`env="HOME=/home/\"root dir"`, "no-port-forwarding"}, "user@host", "", true}, - }) - - testAuthorizedKeys(t, []byte(authWithDoubleQuotedQuote), []authResult{ - {pub, []string{"no-port-forwarding", `env="HOME=/home/ \"root dir\""`}, "user@host", "", true}, - }) -} - -func TestAuthWithInvalidSpace(t *testing.T) { - _, pubSerialized := getTestKey() - authWithInvalidSpace := []byte(`env="HOME=/home/root dir", no-port-forwarding ssh-rsa ` + pubSerialized + ` user@host -#more to follow but still no valid keys`) - testAuthorizedKeys(t, []byte(authWithInvalidSpace), []authResult{ - {nil, nil, "", "", false}, - }) -} - -func TestAuthWithMissingQuote(t *testing.T) { - pub, pubSerialized := getTestKey() - authWithMissingQuote := []byte(`env="HOME=/home/root,no-port-forwarding ssh-rsa ` + pubSerialized + ` user@host -env="HOME=/home/root",shared-control ssh-rsa ` + pubSerialized + ` user@host`) - - testAuthorizedKeys(t, []byte(authWithMissingQuote), []authResult{ - {pub, []string{`env="HOME=/home/root"`, `shared-control`}, "user@host", "", true}, - }) -} - -func TestInvalidEntry(t *testing.T) { - authInvalid := []byte(`ssh-rsa`) - _, _, _, _, err := ParseAuthorizedKey(authInvalid) - if err == nil { - t.Errorf("got valid entry for %q", authInvalid) - } -} - -var knownHostsParseTests = []struct { - input string - err string - - marker string - comment string - hosts []string - rest string -} { - { - "", - "EOF", - - "", "", nil, "", - }, - { - "# Just a comment", - "EOF", - - "", "", nil, "", - }, - { - " \t ", - "EOF", - - "", "", nil, "", - }, - { - "localhost ssh-rsa {RSAPUB}", - "", - - "", "", []string{"localhost"}, "", - }, - { - "localhost\tssh-rsa {RSAPUB}", - "", - - "", "", []string{"localhost"}, "", - }, - { - "localhost\tssh-rsa {RSAPUB}\tcomment comment", - "", - - "", "comment comment", []string{"localhost"}, "", - }, - { - "localhost\tssh-rsa {RSAPUB}\tcomment comment\n", - "", - - "", "comment comment", []string{"localhost"}, "", - }, - { - "localhost\tssh-rsa {RSAPUB}\tcomment comment\r\n", - "", - - "", "comment comment", []string{"localhost"}, "", - }, - { - "localhost\tssh-rsa {RSAPUB}\tcomment comment\r\nnext line", - "", - - "", "comment comment", []string{"localhost"}, "next line", - }, - { - "localhost,[host2:123]\tssh-rsa {RSAPUB}\tcomment comment", - "", - - "", "comment comment", []string{"localhost","[host2:123]"}, "", - }, - { - "@marker \tlocalhost,[host2:123]\tssh-rsa {RSAPUB}", - "", - - "marker", "", []string{"localhost","[host2:123]"}, "", - }, - { - "@marker \tlocalhost,[host2:123]\tssh-rsa aabbccdd", - "short read", - - "", "", nil, "", - }, -} - -func TestKnownHostsParsing(t *testing.T) { - rsaPub, rsaPubSerialized := getTestKey() - - for i, test := range knownHostsParseTests { - var expectedKey PublicKey - const rsaKeyToken = "{RSAPUB}" - - input := test.input - if strings.Contains(input, rsaKeyToken) { - expectedKey = rsaPub - input = strings.Replace(test.input, rsaKeyToken, rsaPubSerialized, -1) - } - - marker, hosts, pubKey, comment, rest, err := ParseKnownHosts([]byte(input)) - if err != nil { - if len(test.err) == 0 { - t.Errorf("#%d: unexpectedly failed with %q", i, err) - } else if !strings.Contains(err.Error(), test.err) { - t.Errorf("#%d: expected error containing %q, but got %q", i, test.err, err) - } - continue - } else if len(test.err) != 0 { - t.Errorf("#%d: succeeded but expected error including %q", i, test.err) - continue - } - - if !reflect.DeepEqual(expectedKey, pubKey) { - t.Errorf("#%d: expected key %#v, but got %#v", i, expectedKey, pubKey) - } - - if marker != test.marker { - t.Errorf("#%d: expected marker %q, but got %q", i, test.marker, marker) - } - - if comment != test.comment { - t.Errorf("#%d: expected comment %q, but got %q", i, test.comment, comment) - } - - if !reflect.DeepEqual(test.hosts, hosts) { - t.Errorf("#%d: expected hosts %#v, but got %#v", i, test.hosts, hosts) - } - - if rest := string(rest); rest != test.rest { - t.Errorf("#%d: expected remaining input to be %q, but got %q", i, test.rest, rest) - } - } -} diff --git a/vendor/golang.org/x/crypto/ssh/mac.go b/vendor/golang.org/x/crypto/ssh/mac.go deleted file mode 100644 index 07744ad..0000000 --- a/vendor/golang.org/x/crypto/ssh/mac.go +++ /dev/null @@ -1,57 +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. - -package ssh - -// Message authentication support - -import ( - "crypto/hmac" - "crypto/sha1" - "crypto/sha256" - "hash" -) - -type macMode struct { - keySize int - new func(key []byte) hash.Hash -} - -// truncatingMAC wraps around a hash.Hash and truncates the output digest to -// a given size. -type truncatingMAC struct { - length int - hmac hash.Hash -} - -func (t truncatingMAC) Write(data []byte) (int, error) { - return t.hmac.Write(data) -} - -func (t truncatingMAC) Sum(in []byte) []byte { - out := t.hmac.Sum(in) - return out[:len(in)+t.length] -} - -func (t truncatingMAC) Reset() { - t.hmac.Reset() -} - -func (t truncatingMAC) Size() int { - return t.length -} - -func (t truncatingMAC) BlockSize() int { return t.hmac.BlockSize() } - -var macModes = map[string]*macMode{ - "hmac-sha2-256": {32, func(key []byte) hash.Hash { - return hmac.New(sha256.New, key) - }}, - "hmac-sha1": {20, func(key []byte) hash.Hash { - return hmac.New(sha1.New, key) - }}, - "hmac-sha1-96": {20, func(key []byte) hash.Hash { - return truncatingMAC{12, hmac.New(sha1.New, key)} - }}, -} diff --git a/vendor/golang.org/x/crypto/ssh/mempipe_test.go b/vendor/golang.org/x/crypto/ssh/mempipe_test.go deleted file mode 100644 index 8697cd6..0000000 --- a/vendor/golang.org/x/crypto/ssh/mempipe_test.go +++ /dev/null @@ -1,110 +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 ssh - -import ( - "io" - "sync" - "testing" -) - -// An in-memory packetConn. It is safe to call Close and writePacket -// from different goroutines. -type memTransport struct { - eof bool - pending [][]byte - write *memTransport - sync.Mutex - *sync.Cond -} - -func (t *memTransport) readPacket() ([]byte, error) { - t.Lock() - defer t.Unlock() - for { - if len(t.pending) > 0 { - r := t.pending[0] - t.pending = t.pending[1:] - return r, nil - } - if t.eof { - return nil, io.EOF - } - t.Cond.Wait() - } -} - -func (t *memTransport) closeSelf() error { - t.Lock() - defer t.Unlock() - if t.eof { - return io.EOF - } - t.eof = true - t.Cond.Broadcast() - return nil -} - -func (t *memTransport) Close() error { - err := t.write.closeSelf() - t.closeSelf() - return err -} - -func (t *memTransport) writePacket(p []byte) error { - t.write.Lock() - defer t.write.Unlock() - if t.write.eof { - return io.EOF - } - c := make([]byte, len(p)) - copy(c, p) - t.write.pending = append(t.write.pending, c) - t.write.Cond.Signal() - return nil -} - -func memPipe() (a, b packetConn) { - t1 := memTransport{} - t2 := memTransport{} - t1.write = &t2 - t2.write = &t1 - t1.Cond = sync.NewCond(&t1.Mutex) - t2.Cond = sync.NewCond(&t2.Mutex) - return &t1, &t2 -} - -func TestMemPipe(t *testing.T) { - a, b := memPipe() - if err := a.writePacket([]byte{42}); err != nil { - t.Fatalf("writePacket: %v", err) - } - if err := a.Close(); err != nil { - t.Fatal("Close: ", err) - } - p, err := b.readPacket() - if err != nil { - t.Fatal("readPacket: ", err) - } - if len(p) != 1 || p[0] != 42 { - t.Fatalf("got %v, want {42}", p) - } - p, err = b.readPacket() - if err != io.EOF { - t.Fatalf("got %v, %v, want EOF", p, err) - } -} - -func TestDoubleClose(t *testing.T) { - a, _ := memPipe() - err := a.Close() - if err != nil { - t.Errorf("Close: %v", err) - } - err = a.Close() - if err != io.EOF { - t.Errorf("expect EOF on double close.") - } -} diff --git a/vendor/golang.org/x/crypto/ssh/messages.go b/vendor/golang.org/x/crypto/ssh/messages.go deleted file mode 100644 index e6ecd3a..0000000 --- a/vendor/golang.org/x/crypto/ssh/messages.go +++ /dev/null @@ -1,758 +0,0 @@ -// 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 ssh - -import ( - "bytes" - "encoding/binary" - "errors" - "fmt" - "io" - "math/big" - "reflect" - "strconv" - "strings" -) - -// These are SSH message type numbers. They are scattered around several -// documents but many were taken from [SSH-PARAMETERS]. -const ( - msgIgnore = 2 - msgUnimplemented = 3 - msgDebug = 4 - msgNewKeys = 21 - - // Standard authentication messages - msgUserAuthSuccess = 52 - msgUserAuthBanner = 53 -) - -// SSH messages: -// -// These structures mirror the wire format of the corresponding SSH messages. -// They are marshaled using reflection with the marshal and unmarshal functions -// in this file. The only wrinkle is that a final member of type []byte with a -// ssh tag of "rest" receives the remainder of a packet when unmarshaling. - -// See RFC 4253, section 11.1. -const msgDisconnect = 1 - -// disconnectMsg is the message that signals a disconnect. It is also -// the error type returned from mux.Wait() -type disconnectMsg struct { - Reason uint32 `sshtype:"1"` - Message string - Language string -} - -func (d *disconnectMsg) Error() string { - return fmt.Sprintf("ssh: disconnect, reason %d: %s", d.Reason, d.Message) -} - -// See RFC 4253, section 7.1. -const msgKexInit = 20 - -type kexInitMsg struct { - Cookie [16]byte `sshtype:"20"` - KexAlgos []string - ServerHostKeyAlgos []string - CiphersClientServer []string - CiphersServerClient []string - MACsClientServer []string - MACsServerClient []string - CompressionClientServer []string - CompressionServerClient []string - LanguagesClientServer []string - LanguagesServerClient []string - FirstKexFollows bool - Reserved uint32 -} - -// See RFC 4253, section 8. - -// Diffie-Helman -const msgKexDHInit = 30 - -type kexDHInitMsg struct { - X *big.Int `sshtype:"30"` -} - -const msgKexECDHInit = 30 - -type kexECDHInitMsg struct { - ClientPubKey []byte `sshtype:"30"` -} - -const msgKexECDHReply = 31 - -type kexECDHReplyMsg struct { - HostKey []byte `sshtype:"31"` - EphemeralPubKey []byte - Signature []byte -} - -const msgKexDHReply = 31 - -type kexDHReplyMsg struct { - HostKey []byte `sshtype:"31"` - Y *big.Int - Signature []byte -} - -// See RFC 4253, section 10. -const msgServiceRequest = 5 - -type serviceRequestMsg struct { - Service string `sshtype:"5"` -} - -// See RFC 4253, section 10. -const msgServiceAccept = 6 - -type serviceAcceptMsg struct { - Service string `sshtype:"6"` -} - -// See RFC 4252, section 5. -const msgUserAuthRequest = 50 - -type userAuthRequestMsg struct { - User string `sshtype:"50"` - Service string - Method string - Payload []byte `ssh:"rest"` -} - -// Used for debug printouts of packets. -type userAuthSuccessMsg struct { -} - -// See RFC 4252, section 5.1 -const msgUserAuthFailure = 51 - -type userAuthFailureMsg struct { - Methods []string `sshtype:"51"` - PartialSuccess bool -} - -// See RFC 4256, section 3.2 -const msgUserAuthInfoRequest = 60 -const msgUserAuthInfoResponse = 61 - -type userAuthInfoRequestMsg struct { - User string `sshtype:"60"` - Instruction string - DeprecatedLanguage string - NumPrompts uint32 - Prompts []byte `ssh:"rest"` -} - -// See RFC 4254, section 5.1. -const msgChannelOpen = 90 - -type channelOpenMsg struct { - ChanType string `sshtype:"90"` - PeersId uint32 - PeersWindow uint32 - MaxPacketSize uint32 - TypeSpecificData []byte `ssh:"rest"` -} - -const msgChannelExtendedData = 95 -const msgChannelData = 94 - -// Used for debug print outs of packets. -type channelDataMsg struct { - PeersId uint32 `sshtype:"94"` - Length uint32 - Rest []byte `ssh:"rest"` -} - -// See RFC 4254, section 5.1. -const msgChannelOpenConfirm = 91 - -type channelOpenConfirmMsg struct { - PeersId uint32 `sshtype:"91"` - MyId uint32 - MyWindow uint32 - MaxPacketSize uint32 - TypeSpecificData []byte `ssh:"rest"` -} - -// See RFC 4254, section 5.1. -const msgChannelOpenFailure = 92 - -type channelOpenFailureMsg struct { - PeersId uint32 `sshtype:"92"` - Reason RejectionReason - Message string - Language string -} - -const msgChannelRequest = 98 - -type channelRequestMsg struct { - PeersId uint32 `sshtype:"98"` - Request string - WantReply bool - RequestSpecificData []byte `ssh:"rest"` -} - -// See RFC 4254, section 5.4. -const msgChannelSuccess = 99 - -type channelRequestSuccessMsg struct { - PeersId uint32 `sshtype:"99"` -} - -// See RFC 4254, section 5.4. -const msgChannelFailure = 100 - -type channelRequestFailureMsg struct { - PeersId uint32 `sshtype:"100"` -} - -// See RFC 4254, section 5.3 -const msgChannelClose = 97 - -type channelCloseMsg struct { - PeersId uint32 `sshtype:"97"` -} - -// See RFC 4254, section 5.3 -const msgChannelEOF = 96 - -type channelEOFMsg struct { - PeersId uint32 `sshtype:"96"` -} - -// See RFC 4254, section 4 -const msgGlobalRequest = 80 - -type globalRequestMsg struct { - Type string `sshtype:"80"` - WantReply bool - Data []byte `ssh:"rest"` -} - -// See RFC 4254, section 4 -const msgRequestSuccess = 81 - -type globalRequestSuccessMsg struct { - Data []byte `ssh:"rest" sshtype:"81"` -} - -// See RFC 4254, section 4 -const msgRequestFailure = 82 - -type globalRequestFailureMsg struct { - Data []byte `ssh:"rest" sshtype:"82"` -} - -// See RFC 4254, section 5.2 -const msgChannelWindowAdjust = 93 - -type windowAdjustMsg struct { - PeersId uint32 `sshtype:"93"` - AdditionalBytes uint32 -} - -// See RFC 4252, section 7 -const msgUserAuthPubKeyOk = 60 - -type userAuthPubKeyOkMsg struct { - Algo string `sshtype:"60"` - PubKey []byte -} - -// typeTags returns the possible type bytes for the given reflect.Type, which -// should be a struct. The possible values are separated by a '|' character. -func typeTags(structType reflect.Type) (tags []byte) { - tagStr := structType.Field(0).Tag.Get("sshtype") - - for _, tag := range strings.Split(tagStr, "|") { - i, err := strconv.Atoi(tag) - if err == nil { - tags = append(tags, byte(i)) - } - } - - return tags -} - -func fieldError(t reflect.Type, field int, problem string) error { - if problem != "" { - problem = ": " + problem - } - return fmt.Errorf("ssh: unmarshal error for field %s of type %s%s", t.Field(field).Name, t.Name(), problem) -} - -var errShortRead = errors.New("ssh: short read") - -// Unmarshal parses data in SSH wire format into a structure. The out -// argument should be a pointer to struct. If the first member of the -// struct has the "sshtype" tag set to a '|'-separated set of numbers -// in decimal, the packet must start with one of those numbers. In -// case of error, Unmarshal returns a ParseError or -// UnexpectedMessageError. -func Unmarshal(data []byte, out interface{}) error { - v := reflect.ValueOf(out).Elem() - structType := v.Type() - expectedTypes := typeTags(structType) - - var expectedType byte - if len(expectedTypes) > 0 { - expectedType = expectedTypes[0] - } - - if len(data) == 0 { - return parseError(expectedType) - } - - if len(expectedTypes) > 0 { - goodType := false - for _, e := range expectedTypes { - if e > 0 && data[0] == e { - goodType = true - break - } - } - if !goodType { - return fmt.Errorf("ssh: unexpected message type %d (expected one of %v)", data[0], expectedTypes) - } - data = data[1:] - } - - var ok bool - for i := 0; i < v.NumField(); i++ { - field := v.Field(i) - t := field.Type() - switch t.Kind() { - case reflect.Bool: - if len(data) < 1 { - return errShortRead - } - field.SetBool(data[0] != 0) - data = data[1:] - case reflect.Array: - if t.Elem().Kind() != reflect.Uint8 { - return fieldError(structType, i, "array of unsupported type") - } - if len(data) < t.Len() { - return errShortRead - } - for j, n := 0, t.Len(); j < n; j++ { - field.Index(j).Set(reflect.ValueOf(data[j])) - } - data = data[t.Len():] - case reflect.Uint64: - var u64 uint64 - if u64, data, ok = parseUint64(data); !ok { - return errShortRead - } - field.SetUint(u64) - case reflect.Uint32: - var u32 uint32 - if u32, data, ok = parseUint32(data); !ok { - return errShortRead - } - field.SetUint(uint64(u32)) - case reflect.Uint8: - if len(data) < 1 { - return errShortRead - } - field.SetUint(uint64(data[0])) - data = data[1:] - case reflect.String: - var s []byte - if s, data, ok = parseString(data); !ok { - return fieldError(structType, i, "") - } - field.SetString(string(s)) - case reflect.Slice: - switch t.Elem().Kind() { - case reflect.Uint8: - if structType.Field(i).Tag.Get("ssh") == "rest" { - field.Set(reflect.ValueOf(data)) - data = nil - } else { - var s []byte - if s, data, ok = parseString(data); !ok { - return errShortRead - } - field.Set(reflect.ValueOf(s)) - } - case reflect.String: - var nl []string - if nl, data, ok = parseNameList(data); !ok { - return errShortRead - } - field.Set(reflect.ValueOf(nl)) - default: - return fieldError(structType, i, "slice of unsupported type") - } - case reflect.Ptr: - if t == bigIntType { - var n *big.Int - if n, data, ok = parseInt(data); !ok { - return errShortRead - } - field.Set(reflect.ValueOf(n)) - } else { - return fieldError(structType, i, "pointer to unsupported type") - } - default: - return fieldError(structType, i, fmt.Sprintf("unsupported type: %v", t)) - } - } - - if len(data) != 0 { - return parseError(expectedType) - } - - return nil -} - -// Marshal serializes the message in msg to SSH wire format. The msg -// argument should be a struct or pointer to struct. If the first -// member has the "sshtype" tag set to a number in decimal, that -// number is prepended to the result. If the last of member has the -// "ssh" tag set to "rest", its contents are appended to the output. -func Marshal(msg interface{}) []byte { - out := make([]byte, 0, 64) - return marshalStruct(out, msg) -} - -func marshalStruct(out []byte, msg interface{}) []byte { - v := reflect.Indirect(reflect.ValueOf(msg)) - msgTypes := typeTags(v.Type()) - if len(msgTypes) > 0 { - out = append(out, msgTypes[0]) - } - - for i, n := 0, v.NumField(); i < n; i++ { - field := v.Field(i) - switch t := field.Type(); t.Kind() { - case reflect.Bool: - var v uint8 - if field.Bool() { - v = 1 - } - out = append(out, v) - case reflect.Array: - if t.Elem().Kind() != reflect.Uint8 { - panic(fmt.Sprintf("array of non-uint8 in field %d: %T", i, field.Interface())) - } - for j, l := 0, t.Len(); j < l; j++ { - out = append(out, uint8(field.Index(j).Uint())) - } - case reflect.Uint32: - out = appendU32(out, uint32(field.Uint())) - case reflect.Uint64: - out = appendU64(out, uint64(field.Uint())) - case reflect.Uint8: - out = append(out, uint8(field.Uint())) - case reflect.String: - s := field.String() - out = appendInt(out, len(s)) - out = append(out, s...) - case reflect.Slice: - switch t.Elem().Kind() { - case reflect.Uint8: - if v.Type().Field(i).Tag.Get("ssh") != "rest" { - out = appendInt(out, field.Len()) - } - out = append(out, field.Bytes()...) - case reflect.String: - offset := len(out) - out = appendU32(out, 0) - if n := field.Len(); n > 0 { - for j := 0; j < n; j++ { - f := field.Index(j) - if j != 0 { - out = append(out, ',') - } - out = append(out, f.String()...) - } - // overwrite length value - binary.BigEndian.PutUint32(out[offset:], uint32(len(out)-offset-4)) - } - default: - panic(fmt.Sprintf("slice of unknown type in field %d: %T", i, field.Interface())) - } - case reflect.Ptr: - if t == bigIntType { - var n *big.Int - nValue := reflect.ValueOf(&n) - nValue.Elem().Set(field) - needed := intLength(n) - oldLength := len(out) - - if cap(out)-len(out) < needed { - newOut := make([]byte, len(out), 2*(len(out)+needed)) - copy(newOut, out) - out = newOut - } - out = out[:oldLength+needed] - marshalInt(out[oldLength:], n) - } else { - panic(fmt.Sprintf("pointer to unknown type in field %d: %T", i, field.Interface())) - } - } - } - - return out -} - -var bigOne = big.NewInt(1) - -func parseString(in []byte) (out, rest []byte, ok bool) { - if len(in) < 4 { - return - } - length := binary.BigEndian.Uint32(in) - in = in[4:] - if uint32(len(in)) < length { - return - } - out = in[:length] - rest = in[length:] - ok = true - return -} - -var ( - comma = []byte{','} - emptyNameList = []string{} -) - -func parseNameList(in []byte) (out []string, rest []byte, ok bool) { - contents, rest, ok := parseString(in) - if !ok { - return - } - if len(contents) == 0 { - out = emptyNameList - return - } - parts := bytes.Split(contents, comma) - out = make([]string, len(parts)) - for i, part := range parts { - out[i] = string(part) - } - return -} - -func parseInt(in []byte) (out *big.Int, rest []byte, ok bool) { - contents, rest, ok := parseString(in) - if !ok { - return - } - out = new(big.Int) - - if len(contents) > 0 && contents[0]&0x80 == 0x80 { - // This is a negative number - notBytes := make([]byte, len(contents)) - for i := range notBytes { - notBytes[i] = ^contents[i] - } - out.SetBytes(notBytes) - out.Add(out, bigOne) - out.Neg(out) - } else { - // Positive number - out.SetBytes(contents) - } - ok = true - return -} - -func parseUint32(in []byte) (uint32, []byte, bool) { - if len(in) < 4 { - return 0, nil, false - } - return binary.BigEndian.Uint32(in), in[4:], true -} - -func parseUint64(in []byte) (uint64, []byte, bool) { - if len(in) < 8 { - return 0, nil, false - } - return binary.BigEndian.Uint64(in), in[8:], true -} - -func intLength(n *big.Int) int { - length := 4 /* length bytes */ - if n.Sign() < 0 { - nMinus1 := new(big.Int).Neg(n) - nMinus1.Sub(nMinus1, bigOne) - bitLen := nMinus1.BitLen() - if bitLen%8 == 0 { - // The number will need 0xff padding - length++ - } - length += (bitLen + 7) / 8 - } else if n.Sign() == 0 { - // A zero is the zero length string - } else { - bitLen := n.BitLen() - if bitLen%8 == 0 { - // The number will need 0x00 padding - length++ - } - length += (bitLen + 7) / 8 - } - - return length -} - -func marshalUint32(to []byte, n uint32) []byte { - binary.BigEndian.PutUint32(to, n) - return to[4:] -} - -func marshalUint64(to []byte, n uint64) []byte { - binary.BigEndian.PutUint64(to, n) - return to[8:] -} - -func marshalInt(to []byte, n *big.Int) []byte { - lengthBytes := to - to = to[4:] - length := 0 - - if n.Sign() < 0 { - // A negative number has to be converted to two's-complement - // form. So we'll subtract 1 and invert. If the - // most-significant-bit isn't set then we'll need to pad the - // beginning with 0xff in order to keep the number negative. - nMinus1 := new(big.Int).Neg(n) - nMinus1.Sub(nMinus1, bigOne) - bytes := nMinus1.Bytes() - for i := range bytes { - bytes[i] ^= 0xff - } - if len(bytes) == 0 || bytes[0]&0x80 == 0 { - to[0] = 0xff - to = to[1:] - length++ - } - nBytes := copy(to, bytes) - to = to[nBytes:] - length += nBytes - } else if n.Sign() == 0 { - // A zero is the zero length string - } else { - bytes := n.Bytes() - if len(bytes) > 0 && bytes[0]&0x80 != 0 { - // We'll have to pad this with a 0x00 in order to - // stop it looking like a negative number. - to[0] = 0 - to = to[1:] - length++ - } - nBytes := copy(to, bytes) - to = to[nBytes:] - length += nBytes - } - - lengthBytes[0] = byte(length >> 24) - lengthBytes[1] = byte(length >> 16) - lengthBytes[2] = byte(length >> 8) - lengthBytes[3] = byte(length) - return to -} - -func writeInt(w io.Writer, n *big.Int) { - length := intLength(n) - buf := make([]byte, length) - marshalInt(buf, n) - w.Write(buf) -} - -func writeString(w io.Writer, s []byte) { - var lengthBytes [4]byte - lengthBytes[0] = byte(len(s) >> 24) - lengthBytes[1] = byte(len(s) >> 16) - lengthBytes[2] = byte(len(s) >> 8) - lengthBytes[3] = byte(len(s)) - w.Write(lengthBytes[:]) - w.Write(s) -} - -func stringLength(n int) int { - return 4 + n -} - -func marshalString(to []byte, s []byte) []byte { - to[0] = byte(len(s) >> 24) - to[1] = byte(len(s) >> 16) - to[2] = byte(len(s) >> 8) - to[3] = byte(len(s)) - to = to[4:] - copy(to, s) - return to[len(s):] -} - -var bigIntType = reflect.TypeOf((*big.Int)(nil)) - -// Decode a packet into its corresponding message. -func decode(packet []byte) (interface{}, error) { - var msg interface{} - switch packet[0] { - case msgDisconnect: - msg = new(disconnectMsg) - case msgServiceRequest: - msg = new(serviceRequestMsg) - case msgServiceAccept: - msg = new(serviceAcceptMsg) - case msgKexInit: - msg = new(kexInitMsg) - case msgKexDHInit: - msg = new(kexDHInitMsg) - case msgKexDHReply: - msg = new(kexDHReplyMsg) - case msgUserAuthRequest: - msg = new(userAuthRequestMsg) - case msgUserAuthSuccess: - return new(userAuthSuccessMsg), nil - case msgUserAuthFailure: - msg = new(userAuthFailureMsg) - case msgUserAuthPubKeyOk: - msg = new(userAuthPubKeyOkMsg) - case msgGlobalRequest: - msg = new(globalRequestMsg) - case msgRequestSuccess: - msg = new(globalRequestSuccessMsg) - case msgRequestFailure: - msg = new(globalRequestFailureMsg) - case msgChannelOpen: - msg = new(channelOpenMsg) - case msgChannelData: - msg = new(channelDataMsg) - case msgChannelOpenConfirm: - msg = new(channelOpenConfirmMsg) - case msgChannelOpenFailure: - msg = new(channelOpenFailureMsg) - case msgChannelWindowAdjust: - msg = new(windowAdjustMsg) - case msgChannelEOF: - msg = new(channelEOFMsg) - case msgChannelClose: - msg = new(channelCloseMsg) - case msgChannelRequest: - msg = new(channelRequestMsg) - case msgChannelSuccess: - msg = new(channelRequestSuccessMsg) - case msgChannelFailure: - msg = new(channelRequestFailureMsg) - default: - return nil, unexpectedMessageError(0, packet[0]) - } - if err := Unmarshal(packet, msg); err != nil { - return nil, err - } - return msg, nil -} diff --git a/vendor/golang.org/x/crypto/ssh/messages_test.go b/vendor/golang.org/x/crypto/ssh/messages_test.go deleted file mode 100644 index e790764..0000000 --- a/vendor/golang.org/x/crypto/ssh/messages_test.go +++ /dev/null @@ -1,288 +0,0 @@ -// 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 ssh - -import ( - "bytes" - "math/big" - "math/rand" - "reflect" - "testing" - "testing/quick" -) - -var intLengthTests = []struct { - val, length int -}{ - {0, 4 + 0}, - {1, 4 + 1}, - {127, 4 + 1}, - {128, 4 + 2}, - {-1, 4 + 1}, -} - -func TestIntLength(t *testing.T) { - for _, test := range intLengthTests { - v := new(big.Int).SetInt64(int64(test.val)) - length := intLength(v) - if length != test.length { - t.Errorf("For %d, got length %d but expected %d", test.val, length, test.length) - } - } -} - -type msgAllTypes struct { - Bool bool `sshtype:"21"` - Array [16]byte - Uint64 uint64 - Uint32 uint32 - Uint8 uint8 - String string - Strings []string - Bytes []byte - Int *big.Int - Rest []byte `ssh:"rest"` -} - -func (t *msgAllTypes) Generate(rand *rand.Rand, size int) reflect.Value { - m := &msgAllTypes{} - m.Bool = rand.Intn(2) == 1 - randomBytes(m.Array[:], rand) - m.Uint64 = uint64(rand.Int63n(1<<63 - 1)) - m.Uint32 = uint32(rand.Intn((1 << 31) - 1)) - m.Uint8 = uint8(rand.Intn(1 << 8)) - m.String = string(m.Array[:]) - m.Strings = randomNameList(rand) - m.Bytes = m.Array[:] - m.Int = randomInt(rand) - m.Rest = m.Array[:] - return reflect.ValueOf(m) -} - -func TestMarshalUnmarshal(t *testing.T) { - rand := rand.New(rand.NewSource(0)) - iface := &msgAllTypes{} - ty := reflect.ValueOf(iface).Type() - - n := 100 - if testing.Short() { - n = 5 - } - for j := 0; j < n; j++ { - v, ok := quick.Value(ty, rand) - if !ok { - t.Errorf("failed to create value") - break - } - - m1 := v.Elem().Interface() - m2 := iface - - marshaled := Marshal(m1) - if err := Unmarshal(marshaled, m2); err != nil { - t.Errorf("Unmarshal %#v: %s", m1, err) - break - } - - if !reflect.DeepEqual(v.Interface(), m2) { - t.Errorf("got: %#v\nwant:%#v\n%x", m2, m1, marshaled) - break - } - } -} - -func TestUnmarshalEmptyPacket(t *testing.T) { - var b []byte - var m channelRequestSuccessMsg - if err := Unmarshal(b, &m); err == nil { - t.Fatalf("unmarshal of empty slice succeeded") - } -} - -func TestUnmarshalUnexpectedPacket(t *testing.T) { - type S struct { - I uint32 `sshtype:"43"` - S string - B bool - } - - s := S{11, "hello", true} - packet := Marshal(s) - packet[0] = 42 - roundtrip := S{} - err := Unmarshal(packet, &roundtrip) - if err == nil { - t.Fatal("expected error, not nil") - } -} - -func TestMarshalPtr(t *testing.T) { - s := struct { - S string - }{"hello"} - - m1 := Marshal(s) - m2 := Marshal(&s) - if !bytes.Equal(m1, m2) { - t.Errorf("got %q, want %q for marshaled pointer", m2, m1) - } -} - -func TestBareMarshalUnmarshal(t *testing.T) { - type S struct { - I uint32 - S string - B bool - } - - s := S{42, "hello", true} - packet := Marshal(s) - roundtrip := S{} - Unmarshal(packet, &roundtrip) - - if !reflect.DeepEqual(s, roundtrip) { - t.Errorf("got %#v, want %#v", roundtrip, s) - } -} - -func TestBareMarshal(t *testing.T) { - type S2 struct { - I uint32 - } - s := S2{42} - packet := Marshal(s) - i, rest, ok := parseUint32(packet) - if len(rest) > 0 || !ok { - t.Errorf("parseInt(%q): parse error", packet) - } - if i != s.I { - t.Errorf("got %d, want %d", i, s.I) - } -} - -func TestUnmarshalShortKexInitPacket(t *testing.T) { - // This used to panic. - // Issue 11348 - packet := []byte{0x14, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0xff, 0xff, 0xff, 0xff} - kim := &kexInitMsg{} - if err := Unmarshal(packet, kim); err == nil { - t.Error("truncated packet unmarshaled without error") - } -} - -func TestMarshalMultiTag(t *testing.T) { - var res struct { - A uint32 `sshtype:"1|2"` - } - - good1 := struct { - A uint32 `sshtype:"1"` - }{ - 1, - } - good2 := struct { - A uint32 `sshtype:"2"` - }{ - 1, - } - - if e := Unmarshal(Marshal(good1), &res); e != nil { - t.Errorf("error unmarshaling multipart tag: %v", e) - } - - if e := Unmarshal(Marshal(good2), &res); e != nil { - t.Errorf("error unmarshaling multipart tag: %v", e) - } - - bad1 := struct { - A uint32 `sshtype:"3"` - }{ - 1, - } - if e := Unmarshal(Marshal(bad1), &res); e == nil { - t.Errorf("bad struct unmarshaled without error") - } -} - -func randomBytes(out []byte, rand *rand.Rand) { - for i := 0; i < len(out); i++ { - out[i] = byte(rand.Int31()) - } -} - -func randomNameList(rand *rand.Rand) []string { - ret := make([]string, rand.Int31()&15) - for i := range ret { - s := make([]byte, 1+(rand.Int31()&15)) - for j := range s { - s[j] = 'a' + uint8(rand.Int31()&15) - } - ret[i] = string(s) - } - return ret -} - -func randomInt(rand *rand.Rand) *big.Int { - return new(big.Int).SetInt64(int64(int32(rand.Uint32()))) -} - -func (*kexInitMsg) Generate(rand *rand.Rand, size int) reflect.Value { - ki := &kexInitMsg{} - randomBytes(ki.Cookie[:], rand) - ki.KexAlgos = randomNameList(rand) - ki.ServerHostKeyAlgos = randomNameList(rand) - ki.CiphersClientServer = randomNameList(rand) - ki.CiphersServerClient = randomNameList(rand) - ki.MACsClientServer = randomNameList(rand) - ki.MACsServerClient = randomNameList(rand) - ki.CompressionClientServer = randomNameList(rand) - ki.CompressionServerClient = randomNameList(rand) - ki.LanguagesClientServer = randomNameList(rand) - ki.LanguagesServerClient = randomNameList(rand) - if rand.Int31()&1 == 1 { - ki.FirstKexFollows = true - } - return reflect.ValueOf(ki) -} - -func (*kexDHInitMsg) Generate(rand *rand.Rand, size int) reflect.Value { - dhi := &kexDHInitMsg{} - dhi.X = randomInt(rand) - return reflect.ValueOf(dhi) -} - -var ( - _kexInitMsg = new(kexInitMsg).Generate(rand.New(rand.NewSource(0)), 10).Elem().Interface() - _kexDHInitMsg = new(kexDHInitMsg).Generate(rand.New(rand.NewSource(0)), 10).Elem().Interface() - - _kexInit = Marshal(_kexInitMsg) - _kexDHInit = Marshal(_kexDHInitMsg) -) - -func BenchmarkMarshalKexInitMsg(b *testing.B) { - for i := 0; i < b.N; i++ { - Marshal(_kexInitMsg) - } -} - -func BenchmarkUnmarshalKexInitMsg(b *testing.B) { - m := new(kexInitMsg) - for i := 0; i < b.N; i++ { - Unmarshal(_kexInit, m) - } -} - -func BenchmarkMarshalKexDHInitMsg(b *testing.B) { - for i := 0; i < b.N; i++ { - Marshal(_kexDHInitMsg) - } -} - -func BenchmarkUnmarshalKexDHInitMsg(b *testing.B) { - m := new(kexDHInitMsg) - for i := 0; i < b.N; i++ { - Unmarshal(_kexDHInit, m) - } -} diff --git a/vendor/golang.org/x/crypto/ssh/mux.go b/vendor/golang.org/x/crypto/ssh/mux.go deleted file mode 100644 index f3a3ddd..0000000 --- a/vendor/golang.org/x/crypto/ssh/mux.go +++ /dev/null @@ -1,330 +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 ssh - -import ( - "encoding/binary" - "fmt" - "io" - "log" - "sync" - "sync/atomic" -) - -// debugMux, if set, causes messages in the connection protocol to be -// logged. -const debugMux = false - -// chanList is a thread safe channel list. -type chanList struct { - // protects concurrent access to chans - sync.Mutex - - // chans are indexed by the local id of the channel, which the - // other side should send in the PeersId field. - chans []*channel - - // This is a debugging aid: it offsets all IDs by this - // amount. This helps distinguish otherwise identical - // server/client muxes - offset uint32 -} - -// Assigns a channel ID to the given channel. -func (c *chanList) add(ch *channel) uint32 { - c.Lock() - defer c.Unlock() - for i := range c.chans { - if c.chans[i] == nil { - c.chans[i] = ch - return uint32(i) + c.offset - } - } - c.chans = append(c.chans, ch) - return uint32(len(c.chans)-1) + c.offset -} - -// getChan returns the channel for the given ID. -func (c *chanList) getChan(id uint32) *channel { - id -= c.offset - - c.Lock() - defer c.Unlock() - if id < uint32(len(c.chans)) { - return c.chans[id] - } - return nil -} - -func (c *chanList) remove(id uint32) { - id -= c.offset - c.Lock() - if id < uint32(len(c.chans)) { - c.chans[id] = nil - } - c.Unlock() -} - -// dropAll forgets all channels it knows, returning them in a slice. -func (c *chanList) dropAll() []*channel { - c.Lock() - defer c.Unlock() - var r []*channel - - for _, ch := range c.chans { - if ch == nil { - continue - } - r = append(r, ch) - } - c.chans = nil - return r -} - -// mux represents the state for the SSH connection protocol, which -// multiplexes many channels onto a single packet transport. -type mux struct { - conn packetConn - chanList chanList - - incomingChannels chan NewChannel - - globalSentMu sync.Mutex - globalResponses chan interface{} - incomingRequests chan *Request - - errCond *sync.Cond - err error -} - -// When debugging, each new chanList instantiation has a different -// offset. -var globalOff uint32 - -func (m *mux) Wait() error { - m.errCond.L.Lock() - defer m.errCond.L.Unlock() - for m.err == nil { - m.errCond.Wait() - } - return m.err -} - -// newMux returns a mux that runs over the given connection. -func newMux(p packetConn) *mux { - m := &mux{ - conn: p, - incomingChannels: make(chan NewChannel, 16), - globalResponses: make(chan interface{}, 1), - incomingRequests: make(chan *Request, 16), - errCond: newCond(), - } - if debugMux { - m.chanList.offset = atomic.AddUint32(&globalOff, 1) - } - - go m.loop() - return m -} - -func (m *mux) sendMessage(msg interface{}) error { - p := Marshal(msg) - if debugMux { - log.Printf("send global(%d): %#v", m.chanList.offset, msg) - } - return m.conn.writePacket(p) -} - -func (m *mux) SendRequest(name string, wantReply bool, payload []byte) (bool, []byte, error) { - if wantReply { - m.globalSentMu.Lock() - defer m.globalSentMu.Unlock() - } - - if err := m.sendMessage(globalRequestMsg{ - Type: name, - WantReply: wantReply, - Data: payload, - }); err != nil { - return false, nil, err - } - - if !wantReply { - return false, nil, nil - } - - msg, ok := <-m.globalResponses - if !ok { - return false, nil, io.EOF - } - switch msg := msg.(type) { - case *globalRequestFailureMsg: - return false, msg.Data, nil - case *globalRequestSuccessMsg: - return true, msg.Data, nil - default: - return false, nil, fmt.Errorf("ssh: unexpected response to request: %#v", msg) - } -} - -// ackRequest must be called after processing a global request that -// has WantReply set. -func (m *mux) ackRequest(ok bool, data []byte) error { - if ok { - return m.sendMessage(globalRequestSuccessMsg{Data: data}) - } - return m.sendMessage(globalRequestFailureMsg{Data: data}) -} - -func (m *mux) Close() error { - return m.conn.Close() -} - -// loop runs the connection machine. It will process packets until an -// error is encountered. To synchronize on loop exit, use mux.Wait. -func (m *mux) loop() { - var err error - for err == nil { - err = m.onePacket() - } - - for _, ch := range m.chanList.dropAll() { - ch.close() - } - - close(m.incomingChannels) - close(m.incomingRequests) - close(m.globalResponses) - - m.conn.Close() - - m.errCond.L.Lock() - m.err = err - m.errCond.Broadcast() - m.errCond.L.Unlock() - - if debugMux { - log.Println("loop exit", err) - } -} - -// onePacket reads and processes one packet. -func (m *mux) onePacket() error { - packet, err := m.conn.readPacket() - if err != nil { - return err - } - - if debugMux { - if packet[0] == msgChannelData || packet[0] == msgChannelExtendedData { - log.Printf("decoding(%d): data packet - %d bytes", m.chanList.offset, len(packet)) - } else { - p, _ := decode(packet) - log.Printf("decoding(%d): %d %#v - %d bytes", m.chanList.offset, packet[0], p, len(packet)) - } - } - - switch packet[0] { - case msgChannelOpen: - return m.handleChannelOpen(packet) - case msgGlobalRequest, msgRequestSuccess, msgRequestFailure: - return m.handleGlobalPacket(packet) - } - - // assume a channel packet. - if len(packet) < 5 { - return parseError(packet[0]) - } - id := binary.BigEndian.Uint32(packet[1:]) - ch := m.chanList.getChan(id) - if ch == nil { - return fmt.Errorf("ssh: invalid channel %d", id) - } - - return ch.handlePacket(packet) -} - -func (m *mux) handleGlobalPacket(packet []byte) error { - msg, err := decode(packet) - if err != nil { - return err - } - - switch msg := msg.(type) { - case *globalRequestMsg: - m.incomingRequests <- &Request{ - Type: msg.Type, - WantReply: msg.WantReply, - Payload: msg.Data, - mux: m, - } - case *globalRequestSuccessMsg, *globalRequestFailureMsg: - m.globalResponses <- msg - default: - panic(fmt.Sprintf("not a global message %#v", msg)) - } - - return nil -} - -// handleChannelOpen schedules a channel to be Accept()ed. -func (m *mux) handleChannelOpen(packet []byte) error { - var msg channelOpenMsg - if err := Unmarshal(packet, &msg); err != nil { - return err - } - - if msg.MaxPacketSize < minPacketLength || msg.MaxPacketSize > 1<<31 { - failMsg := channelOpenFailureMsg{ - PeersId: msg.PeersId, - Reason: ConnectionFailed, - Message: "invalid request", - Language: "en_US.UTF-8", - } - return m.sendMessage(failMsg) - } - - c := m.newChannel(msg.ChanType, channelInbound, msg.TypeSpecificData) - c.remoteId = msg.PeersId - c.maxRemotePayload = msg.MaxPacketSize - c.remoteWin.add(msg.PeersWindow) - m.incomingChannels <- c - return nil -} - -func (m *mux) OpenChannel(chanType string, extra []byte) (Channel, <-chan *Request, error) { - ch, err := m.openChannel(chanType, extra) - if err != nil { - return nil, nil, err - } - - return ch, ch.incomingRequests, nil -} - -func (m *mux) openChannel(chanType string, extra []byte) (*channel, error) { - ch := m.newChannel(chanType, channelOutbound, extra) - - ch.maxIncomingPayload = channelMaxPacket - - open := channelOpenMsg{ - ChanType: chanType, - PeersWindow: ch.myWindow, - MaxPacketSize: ch.maxIncomingPayload, - TypeSpecificData: extra, - PeersId: ch.localId, - } - if err := m.sendMessage(open); err != nil { - return nil, err - } - - switch msg := (<-ch.msg).(type) { - case *channelOpenConfirmMsg: - return ch, nil - case *channelOpenFailureMsg: - return nil, &OpenChannelError{msg.Reason, msg.Message} - default: - return nil, fmt.Errorf("ssh: unexpected packet in response to channel open: %T", msg) - } -} diff --git a/vendor/golang.org/x/crypto/ssh/mux_test.go b/vendor/golang.org/x/crypto/ssh/mux_test.go deleted file mode 100644 index 591aae8..0000000 --- a/vendor/golang.org/x/crypto/ssh/mux_test.go +++ /dev/null @@ -1,502 +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 ssh - -import ( - "io" - "io/ioutil" - "sync" - "testing" -) - -func muxPair() (*mux, *mux) { - a, b := memPipe() - - s := newMux(a) - c := newMux(b) - - return s, c -} - -// Returns both ends of a channel, and the mux for the the 2nd -// channel. -func channelPair(t *testing.T) (*channel, *channel, *mux) { - c, s := muxPair() - - res := make(chan *channel, 1) - go func() { - newCh, ok := <-s.incomingChannels - if !ok { - t.Fatalf("No incoming channel") - } - if newCh.ChannelType() != "chan" { - t.Fatalf("got type %q want chan", newCh.ChannelType()) - } - ch, _, err := newCh.Accept() - if err != nil { - t.Fatalf("Accept %v", err) - } - res <- ch.(*channel) - }() - - ch, err := c.openChannel("chan", nil) - if err != nil { - t.Fatalf("OpenChannel: %v", err) - } - - return <-res, ch, c -} - -// Test that stderr and stdout can be addressed from different -// goroutines. This is intended for use with the race detector. -func TestMuxChannelExtendedThreadSafety(t *testing.T) { - writer, reader, mux := channelPair(t) - defer writer.Close() - defer reader.Close() - defer mux.Close() - - var wr, rd sync.WaitGroup - magic := "hello world" - - wr.Add(2) - go func() { - io.WriteString(writer, magic) - wr.Done() - }() - go func() { - io.WriteString(writer.Stderr(), magic) - wr.Done() - }() - - rd.Add(2) - go func() { - c, err := ioutil.ReadAll(reader) - if string(c) != magic { - t.Fatalf("stdout read got %q, want %q (error %s)", c, magic, err) - } - rd.Done() - }() - go func() { - c, err := ioutil.ReadAll(reader.Stderr()) - if string(c) != magic { - t.Fatalf("stderr read got %q, want %q (error %s)", c, magic, err) - } - rd.Done() - }() - - wr.Wait() - writer.CloseWrite() - rd.Wait() -} - -func TestMuxReadWrite(t *testing.T) { - s, c, mux := channelPair(t) - defer s.Close() - defer c.Close() - defer mux.Close() - - magic := "hello world" - magicExt := "hello stderr" - go func() { - _, err := s.Write([]byte(magic)) - if err != nil { - t.Fatalf("Write: %v", err) - } - _, err = s.Extended(1).Write([]byte(magicExt)) - if err != nil { - t.Fatalf("Write: %v", err) - } - err = s.Close() - if err != nil { - t.Fatalf("Close: %v", err) - } - }() - - var buf [1024]byte - n, err := c.Read(buf[:]) - if err != nil { - t.Fatalf("server Read: %v", err) - } - got := string(buf[:n]) - if got != magic { - t.Fatalf("server: got %q want %q", got, magic) - } - - n, err = c.Extended(1).Read(buf[:]) - if err != nil { - t.Fatalf("server Read: %v", err) - } - - got = string(buf[:n]) - if got != magicExt { - t.Fatalf("server: got %q want %q", got, magic) - } -} - -func TestMuxChannelOverflow(t *testing.T) { - reader, writer, mux := channelPair(t) - defer reader.Close() - defer writer.Close() - defer mux.Close() - - wDone := make(chan int, 1) - go func() { - if _, err := writer.Write(make([]byte, channelWindowSize)); err != nil { - t.Errorf("could not fill window: %v", err) - } - writer.Write(make([]byte, 1)) - wDone <- 1 - }() - writer.remoteWin.waitWriterBlocked() - - // Send 1 byte. - packet := make([]byte, 1+4+4+1) - packet[0] = msgChannelData - marshalUint32(packet[1:], writer.remoteId) - marshalUint32(packet[5:], uint32(1)) - packet[9] = 42 - - if err := writer.mux.conn.writePacket(packet); err != nil { - t.Errorf("could not send packet") - } - if _, err := reader.SendRequest("hello", true, nil); err == nil { - t.Errorf("SendRequest succeeded.") - } - <-wDone -} - -func TestMuxChannelCloseWriteUnblock(t *testing.T) { - reader, writer, mux := channelPair(t) - defer reader.Close() - defer writer.Close() - defer mux.Close() - - wDone := make(chan int, 1) - go func() { - if _, err := writer.Write(make([]byte, channelWindowSize)); err != nil { - t.Errorf("could not fill window: %v", err) - } - if _, err := writer.Write(make([]byte, 1)); err != io.EOF { - t.Errorf("got %v, want EOF for unblock write", err) - } - wDone <- 1 - }() - - writer.remoteWin.waitWriterBlocked() - reader.Close() - <-wDone -} - -func TestMuxConnectionCloseWriteUnblock(t *testing.T) { - reader, writer, mux := channelPair(t) - defer reader.Close() - defer writer.Close() - defer mux.Close() - - wDone := make(chan int, 1) - go func() { - if _, err := writer.Write(make([]byte, channelWindowSize)); err != nil { - t.Errorf("could not fill window: %v", err) - } - if _, err := writer.Write(make([]byte, 1)); err != io.EOF { - t.Errorf("got %v, want EOF for unblock write", err) - } - wDone <- 1 - }() - - writer.remoteWin.waitWriterBlocked() - mux.Close() - <-wDone -} - -func TestMuxReject(t *testing.T) { - client, server := muxPair() - defer server.Close() - defer client.Close() - - go func() { - ch, ok := <-server.incomingChannels - if !ok { - t.Fatalf("Accept") - } - if ch.ChannelType() != "ch" || string(ch.ExtraData()) != "extra" { - t.Fatalf("unexpected channel: %q, %q", ch.ChannelType(), ch.ExtraData()) - } - ch.Reject(RejectionReason(42), "message") - }() - - ch, err := client.openChannel("ch", []byte("extra")) - if ch != nil { - t.Fatal("openChannel not rejected") - } - - ocf, ok := err.(*OpenChannelError) - if !ok { - t.Errorf("got %#v want *OpenChannelError", err) - } else if ocf.Reason != 42 || ocf.Message != "message" { - t.Errorf("got %#v, want {Reason: 42, Message: %q}", ocf, "message") - } - - want := "ssh: rejected: unknown reason 42 (message)" - if err.Error() != want { - t.Errorf("got %q, want %q", err.Error(), want) - } -} - -func TestMuxChannelRequest(t *testing.T) { - client, server, mux := channelPair(t) - defer server.Close() - defer client.Close() - defer mux.Close() - - var received int - var wg sync.WaitGroup - wg.Add(1) - go func() { - for r := range server.incomingRequests { - received++ - r.Reply(r.Type == "yes", nil) - } - wg.Done() - }() - _, err := client.SendRequest("yes", false, nil) - if err != nil { - t.Fatalf("SendRequest: %v", err) - } - ok, err := client.SendRequest("yes", true, nil) - if err != nil { - t.Fatalf("SendRequest: %v", err) - } - - if !ok { - t.Errorf("SendRequest(yes): %v", ok) - - } - - ok, err = client.SendRequest("no", true, nil) - if err != nil { - t.Fatalf("SendRequest: %v", err) - } - if ok { - t.Errorf("SendRequest(no): %v", ok) - - } - - client.Close() - wg.Wait() - - if received != 3 { - t.Errorf("got %d requests, want %d", received, 3) - } -} - -func TestMuxGlobalRequest(t *testing.T) { - clientMux, serverMux := muxPair() - defer serverMux.Close() - defer clientMux.Close() - - var seen bool - go func() { - for r := range serverMux.incomingRequests { - seen = seen || r.Type == "peek" - if r.WantReply { - err := r.Reply(r.Type == "yes", - append([]byte(r.Type), r.Payload...)) - if err != nil { - t.Errorf("AckRequest: %v", err) - } - } - } - }() - - _, _, err := clientMux.SendRequest("peek", false, nil) - if err != nil { - t.Errorf("SendRequest: %v", err) - } - - ok, data, err := clientMux.SendRequest("yes", true, []byte("a")) - if !ok || string(data) != "yesa" || err != nil { - t.Errorf("SendRequest(\"yes\", true, \"a\"): %v %v %v", - ok, data, err) - } - if ok, data, err := clientMux.SendRequest("yes", true, []byte("a")); !ok || string(data) != "yesa" || err != nil { - t.Errorf("SendRequest(\"yes\", true, \"a\"): %v %v %v", - ok, data, err) - } - - if ok, data, err := clientMux.SendRequest("no", true, []byte("a")); ok || string(data) != "noa" || err != nil { - t.Errorf("SendRequest(\"no\", true, \"a\"): %v %v %v", - ok, data, err) - } - - if !seen { - t.Errorf("never saw 'peek' request") - } -} - -func TestMuxGlobalRequestUnblock(t *testing.T) { - clientMux, serverMux := muxPair() - defer serverMux.Close() - defer clientMux.Close() - - result := make(chan error, 1) - go func() { - _, _, err := clientMux.SendRequest("hello", true, nil) - result <- err - }() - - <-serverMux.incomingRequests - serverMux.conn.Close() - err := <-result - - if err != io.EOF { - t.Errorf("want EOF, got %v", io.EOF) - } -} - -func TestMuxChannelRequestUnblock(t *testing.T) { - a, b, connB := channelPair(t) - defer a.Close() - defer b.Close() - defer connB.Close() - - result := make(chan error, 1) - go func() { - _, err := a.SendRequest("hello", true, nil) - result <- err - }() - - <-b.incomingRequests - connB.conn.Close() - err := <-result - - if err != io.EOF { - t.Errorf("want EOF, got %v", err) - } -} - -func TestMuxCloseChannel(t *testing.T) { - r, w, mux := channelPair(t) - defer mux.Close() - defer r.Close() - defer w.Close() - - result := make(chan error, 1) - go func() { - var b [1024]byte - _, err := r.Read(b[:]) - result <- err - }() - if err := w.Close(); err != nil { - t.Errorf("w.Close: %v", err) - } - - if _, err := w.Write([]byte("hello")); err != io.EOF { - t.Errorf("got err %v, want io.EOF after Close", err) - } - - if err := <-result; err != io.EOF { - t.Errorf("got %v (%T), want io.EOF", err, err) - } -} - -func TestMuxCloseWriteChannel(t *testing.T) { - r, w, mux := channelPair(t) - defer mux.Close() - - result := make(chan error, 1) - go func() { - var b [1024]byte - _, err := r.Read(b[:]) - result <- err - }() - if err := w.CloseWrite(); err != nil { - t.Errorf("w.CloseWrite: %v", err) - } - - if _, err := w.Write([]byte("hello")); err != io.EOF { - t.Errorf("got err %v, want io.EOF after CloseWrite", err) - } - - if err := <-result; err != io.EOF { - t.Errorf("got %v (%T), want io.EOF", err, err) - } -} - -func TestMuxInvalidRecord(t *testing.T) { - a, b := muxPair() - defer a.Close() - defer b.Close() - - packet := make([]byte, 1+4+4+1) - packet[0] = msgChannelData - marshalUint32(packet[1:], 29348723 /* invalid channel id */) - marshalUint32(packet[5:], 1) - packet[9] = 42 - - a.conn.writePacket(packet) - go a.SendRequest("hello", false, nil) - // 'a' wrote an invalid packet, so 'b' has exited. - req, ok := <-b.incomingRequests - if ok { - t.Errorf("got request %#v after receiving invalid packet", req) - } -} - -func TestZeroWindowAdjust(t *testing.T) { - a, b, mux := channelPair(t) - defer a.Close() - defer b.Close() - defer mux.Close() - - go func() { - io.WriteString(a, "hello") - // bogus adjust. - a.sendMessage(windowAdjustMsg{}) - io.WriteString(a, "world") - a.Close() - }() - - want := "helloworld" - c, _ := ioutil.ReadAll(b) - if string(c) != want { - t.Errorf("got %q want %q", c, want) - } -} - -func TestMuxMaxPacketSize(t *testing.T) { - a, b, mux := channelPair(t) - defer a.Close() - defer b.Close() - defer mux.Close() - - large := make([]byte, a.maxRemotePayload+1) - packet := make([]byte, 1+4+4+1+len(large)) - packet[0] = msgChannelData - marshalUint32(packet[1:], a.remoteId) - marshalUint32(packet[5:], uint32(len(large))) - packet[9] = 42 - - if err := a.mux.conn.writePacket(packet); err != nil { - t.Errorf("could not send packet") - } - - go a.SendRequest("hello", false, nil) - - _, ok := <-b.incomingRequests - if ok { - t.Errorf("connection still alive after receiving large packet.") - } -} - -// Don't ship code with debug=true. -func TestDebug(t *testing.T) { - if debugMux { - t.Error("mux debug switched on") - } - if debugHandshake { - t.Error("handshake debug switched on") - } -} diff --git a/vendor/golang.org/x/crypto/ssh/server.go b/vendor/golang.org/x/crypto/ssh/server.go deleted file mode 100644 index e73a1c1..0000000 --- a/vendor/golang.org/x/crypto/ssh/server.go +++ /dev/null @@ -1,489 +0,0 @@ -// 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 ssh - -import ( - "bytes" - "errors" - "fmt" - "io" - "net" -) - -// The Permissions type holds fine-grained permissions that are -// specific to a user or a specific authentication method for a -// user. Permissions, except for "source-address", must be enforced in -// the server application layer, after successful authentication. The -// Permissions are passed on in ServerConn so a server implementation -// can honor them. -type Permissions struct { - // Critical options restrict default permissions. Common - // restrictions are "source-address" and "force-command". If - // the server cannot enforce the restriction, or does not - // recognize it, the user should not authenticate. - CriticalOptions map[string]string - - // Extensions are extra functionality that the server may - // offer on authenticated connections. Common extensions are - // "permit-agent-forwarding", "permit-X11-forwarding". Lack of - // support for an extension does not preclude authenticating a - // user. - Extensions map[string]string -} - -// ServerConfig holds server specific configuration data. -type ServerConfig struct { - // Config contains configuration shared between client and server. - Config - - hostKeys []Signer - - // NoClientAuth is true if clients are allowed to connect without - // authenticating. - NoClientAuth bool - - // PasswordCallback, if non-nil, is called when a user - // attempts to authenticate using a password. - PasswordCallback func(conn ConnMetadata, password []byte) (*Permissions, error) - - // PublicKeyCallback, if non-nil, is called when a client attempts public - // key authentication. It must return true if the given public key is - // valid for the given user. For example, see CertChecker.Authenticate. - PublicKeyCallback func(conn ConnMetadata, key PublicKey) (*Permissions, error) - - // KeyboardInteractiveCallback, if non-nil, is called when - // keyboard-interactive authentication is selected (RFC - // 4256). The client object's Challenge function should be - // used to query the user. The callback may offer multiple - // Challenge rounds. To avoid information leaks, the client - // should be presented a challenge even if the user is - // unknown. - KeyboardInteractiveCallback func(conn ConnMetadata, client KeyboardInteractiveChallenge) (*Permissions, error) - - // AuthLogCallback, if non-nil, is called to log all authentication - // attempts. - AuthLogCallback func(conn ConnMetadata, method string, err error) - - // ServerVersion is the version identification string to announce in - // the public handshake. - // If empty, a reasonable default is used. - // Note that RFC 4253 section 4.2 requires that this string start with - // "SSH-2.0-". - ServerVersion string -} - -// AddHostKey adds a private key as a host key. If an existing host -// key exists with the same algorithm, it is overwritten. Each server -// config must have at least one host key. -func (s *ServerConfig) AddHostKey(key Signer) { - for i, k := range s.hostKeys { - if k.PublicKey().Type() == key.PublicKey().Type() { - s.hostKeys[i] = key - return - } - } - - s.hostKeys = append(s.hostKeys, key) -} - -// cachedPubKey contains the results of querying whether a public key is -// acceptable for a user. -type cachedPubKey struct { - user string - pubKeyData []byte - result error - perms *Permissions -} - -const maxCachedPubKeys = 16 - -// pubKeyCache caches tests for public keys. Since SSH clients -// will query whether a public key is acceptable before attempting to -// authenticate with it, we end up with duplicate queries for public -// key validity. The cache only applies to a single ServerConn. -type pubKeyCache struct { - keys []cachedPubKey -} - -// get returns the result for a given user/algo/key tuple. -func (c *pubKeyCache) get(user string, pubKeyData []byte) (cachedPubKey, bool) { - for _, k := range c.keys { - if k.user == user && bytes.Equal(k.pubKeyData, pubKeyData) { - return k, true - } - } - return cachedPubKey{}, false -} - -// add adds the given tuple to the cache. -func (c *pubKeyCache) add(candidate cachedPubKey) { - if len(c.keys) < maxCachedPubKeys { - c.keys = append(c.keys, candidate) - } -} - -// ServerConn is an authenticated SSH connection, as seen from the -// server -type ServerConn struct { - Conn - - // If the succeeding authentication callback returned a - // non-nil Permissions pointer, it is stored here. - Permissions *Permissions -} - -// NewServerConn starts a new SSH server with c as the underlying -// transport. It starts with a handshake and, if the handshake is -// unsuccessful, it closes the connection and returns an error. The -// Request and NewChannel channels must be serviced, or the connection -// will hang. -func NewServerConn(c net.Conn, config *ServerConfig) (*ServerConn, <-chan NewChannel, <-chan *Request, error) { - fullConf := *config - fullConf.SetDefaults() - s := &connection{ - sshConn: sshConn{conn: c}, - } - perms, err := s.serverHandshake(&fullConf) - if err != nil { - c.Close() - return nil, nil, nil, err - } - return &ServerConn{s, perms}, s.mux.incomingChannels, s.mux.incomingRequests, nil -} - -// 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) - if err != nil { - return nil, err - } - - return Marshal(sig), nil -} - -// handshake performs key exchange and user authentication. -func (s *connection) serverHandshake(config *ServerConfig) (*Permissions, error) { - if len(config.hostKeys) == 0 { - return nil, errors.New("ssh: server has no host keys") - } - - if !config.NoClientAuth && config.PasswordCallback == nil && config.PublicKeyCallback == nil && config.KeyboardInteractiveCallback == nil { - return nil, errors.New("ssh: no authentication methods configured but NoClientAuth is also false") - } - - if config.ServerVersion != "" { - s.serverVersion = []byte(config.ServerVersion) - } else { - s.serverVersion = []byte(packageVersion) - } - var err error - s.clientVersion, err = exchangeVersions(s.sshConn.conn, s.serverVersion) - if err != nil { - return nil, err - } - - tr := newTransport(s.sshConn.conn, config.Rand, false /* not client */) - s.transport = newServerTransport(tr, s.clientVersion, s.serverVersion, config) - - if err := s.transport.requestInitialKeyChange(); err != nil { - return nil, err - } - - // We just did the key change, so the session ID is established. - s.sessionID = s.transport.getSessionID() - - var packet []byte - if packet, err = s.transport.readPacket(); err != nil { - return nil, err - } - - var serviceRequest serviceRequestMsg - if err = Unmarshal(packet, &serviceRequest); err != nil { - return nil, err - } - if serviceRequest.Service != serviceUserAuth { - return nil, errors.New("ssh: requested service '" + serviceRequest.Service + "' before authenticating") - } - serviceAccept := serviceAcceptMsg{ - Service: serviceUserAuth, - } - if err := s.transport.writePacket(Marshal(&serviceAccept)); err != nil { - return nil, err - } - - perms, err := s.serverAuthenticate(config) - if err != nil { - return nil, err - } - s.mux = newMux(s.transport) - return perms, err -} - -func isAcceptableAlgo(algo string) bool { - switch algo { - case KeyAlgoRSA, KeyAlgoDSA, KeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoECDSA521, KeyAlgoED25519, - CertAlgoRSAv01, CertAlgoDSAv01, CertAlgoECDSA256v01, CertAlgoECDSA384v01, CertAlgoECDSA521v01: - return true - } - return false -} - -func checkSourceAddress(addr net.Addr, sourceAddr string) error { - if addr == nil { - return errors.New("ssh: no address known for client, but source-address match required") - } - - tcpAddr, ok := addr.(*net.TCPAddr) - if !ok { - return fmt.Errorf("ssh: remote address %v is not an TCP address when checking source-address match", addr) - } - - if allowedIP := net.ParseIP(sourceAddr); allowedIP != nil { - if bytes.Equal(allowedIP, tcpAddr.IP) { - return nil - } - } else { - _, ipNet, err := net.ParseCIDR(sourceAddr) - if err != nil { - return fmt.Errorf("ssh: error parsing source-address restriction %q: %v", sourceAddr, err) - } - - if ipNet.Contains(tcpAddr.IP) { - return nil - } - } - - return fmt.Errorf("ssh: remote address %v is not allowed because of source-address restriction", addr) -} - -func (s *connection) serverAuthenticate(config *ServerConfig) (*Permissions, error) { - var err error - var cache pubKeyCache - var perms *Permissions - -userAuthLoop: - for { - var userAuthReq userAuthRequestMsg - if packet, err := s.transport.readPacket(); err != nil { - return nil, err - } else if err = Unmarshal(packet, &userAuthReq); err != nil { - return nil, err - } - - if userAuthReq.Service != serviceSSH { - return nil, errors.New("ssh: client attempted to negotiate for unknown service: " + userAuthReq.Service) - } - - s.user = userAuthReq.User - perms = nil - authErr := errors.New("no auth passed yet") - - switch userAuthReq.Method { - case "none": - if config.NoClientAuth { - s.user = "" - authErr = nil - } - case "password": - if config.PasswordCallback == nil { - authErr = errors.New("ssh: password auth not configured") - break - } - payload := userAuthReq.Payload - if len(payload) < 1 || payload[0] != 0 { - return nil, parseError(msgUserAuthRequest) - } - payload = payload[1:] - password, payload, ok := parseString(payload) - if !ok || len(payload) > 0 { - return nil, parseError(msgUserAuthRequest) - } - - perms, authErr = config.PasswordCallback(s, password) - case "keyboard-interactive": - if config.KeyboardInteractiveCallback == nil { - authErr = errors.New("ssh: keyboard-interactive auth not configubred") - break - } - - prompter := &sshClientKeyboardInteractive{s} - perms, authErr = config.KeyboardInteractiveCallback(s, prompter.Challenge) - case "publickey": - if config.PublicKeyCallback == nil { - authErr = errors.New("ssh: publickey auth not configured") - break - } - payload := userAuthReq.Payload - if len(payload) < 1 { - return nil, parseError(msgUserAuthRequest) - } - isQuery := payload[0] == 0 - payload = payload[1:] - algoBytes, payload, ok := parseString(payload) - if !ok { - return nil, parseError(msgUserAuthRequest) - } - algo := string(algoBytes) - if !isAcceptableAlgo(algo) { - authErr = fmt.Errorf("ssh: algorithm %q not accepted", algo) - break - } - - pubKeyData, payload, ok := parseString(payload) - if !ok { - return nil, parseError(msgUserAuthRequest) - } - - pubKey, err := ParsePublicKey(pubKeyData) - if err != nil { - return nil, err - } - - candidate, ok := cache.get(s.user, pubKeyData) - if !ok { - candidate.user = s.user - candidate.pubKeyData = pubKeyData - candidate.perms, candidate.result = config.PublicKeyCallback(s, pubKey) - if candidate.result == nil && candidate.perms != nil && candidate.perms.CriticalOptions != nil && candidate.perms.CriticalOptions[sourceAddressCriticalOption] != "" { - candidate.result = checkSourceAddress( - s.RemoteAddr(), - candidate.perms.CriticalOptions[sourceAddressCriticalOption]) - } - cache.add(candidate) - } - - if isQuery { - // The client can query if the given public key - // would be okay. - if len(payload) > 0 { - return nil, parseError(msgUserAuthRequest) - } - - if candidate.result == nil { - okMsg := userAuthPubKeyOkMsg{ - Algo: algo, - PubKey: pubKeyData, - } - if err = s.transport.writePacket(Marshal(&okMsg)); err != nil { - return nil, err - } - continue userAuthLoop - } - authErr = candidate.result - } else { - sig, payload, ok := parseSignature(payload) - 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 - // sig.Format. This is usually the same, but - // for certs, the names differ. - if !isAcceptableAlgo(sig.Format) { - break - } - signedData := buildDataSignedForAuth(s.transport.getSessionID(), userAuthReq, algoBytes, pubKeyData) - - if err := pubKey.Verify(signedData, sig); err != nil { - return nil, err - } - - authErr = candidate.result - perms = candidate.perms - } - default: - authErr = fmt.Errorf("ssh: unknown method %q", userAuthReq.Method) - } - - if config.AuthLogCallback != nil { - config.AuthLogCallback(s, userAuthReq.Method, authErr) - } - - if authErr == nil { - break userAuthLoop - } - - var failureMsg userAuthFailureMsg - if config.PasswordCallback != nil { - failureMsg.Methods = append(failureMsg.Methods, "password") - } - if config.PublicKeyCallback != nil { - failureMsg.Methods = append(failureMsg.Methods, "publickey") - } - if config.KeyboardInteractiveCallback != nil { - failureMsg.Methods = append(failureMsg.Methods, "keyboard-interactive") - } - - if len(failureMsg.Methods) == 0 { - return nil, errors.New("ssh: no authentication methods configured but NoClientAuth is also false") - } - - if err = s.transport.writePacket(Marshal(&failureMsg)); err != nil { - return nil, err - } - } - - if err = s.transport.writePacket([]byte{msgUserAuthSuccess}); err != nil { - return nil, err - } - return perms, nil -} - -// sshClientKeyboardInteractive implements a ClientKeyboardInteractive by -// asking the client on the other side of a ServerConn. -type sshClientKeyboardInteractive struct { - *connection -} - -func (c *sshClientKeyboardInteractive) Challenge(user, 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") - } - - var prompts []byte - for i := range questions { - prompts = appendString(prompts, questions[i]) - prompts = appendBool(prompts, echos[i]) - } - - if err := c.transport.writePacket(Marshal(&userAuthInfoRequestMsg{ - Instruction: instruction, - NumPrompts: uint32(len(questions)), - Prompts: prompts, - })); err != nil { - return nil, err - } - - packet, err := c.transport.readPacket() - if err != nil { - return nil, err - } - if packet[0] != msgUserAuthInfoResponse { - return nil, unexpectedMessageError(msgUserAuthInfoResponse, packet[0]) - } - packet = packet[1:] - - n, packet, ok := parseUint32(packet) - if !ok || int(n) != len(questions) { - return nil, parseError(msgUserAuthInfoResponse) - } - - for i := uint32(0); i < n; i++ { - ans, rest, ok := parseString(packet) - if !ok { - return nil, parseError(msgUserAuthInfoResponse) - } - - answers = append(answers, string(ans)) - packet = rest - } - if len(packet) != 0 { - return nil, errors.New("ssh: junk at end of message") - } - - return answers, nil -} diff --git a/vendor/golang.org/x/crypto/ssh/session.go b/vendor/golang.org/x/crypto/ssh/session.go deleted file mode 100644 index 09eb009..0000000 --- a/vendor/golang.org/x/crypto/ssh/session.go +++ /dev/null @@ -1,612 +0,0 @@ -// 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 ssh - -// Session implements an interactive session described in -// "RFC 4254, section 6". - -import ( - "bytes" - "errors" - "fmt" - "io" - "io/ioutil" - "sync" -) - -type Signal string - -// POSIX signals as listed in RFC 4254 Section 6.10. -const ( - SIGABRT Signal = "ABRT" - SIGALRM Signal = "ALRM" - SIGFPE Signal = "FPE" - SIGHUP Signal = "HUP" - SIGILL Signal = "ILL" - SIGINT Signal = "INT" - SIGKILL Signal = "KILL" - SIGPIPE Signal = "PIPE" - SIGQUIT Signal = "QUIT" - SIGSEGV Signal = "SEGV" - SIGTERM Signal = "TERM" - SIGUSR1 Signal = "USR1" - SIGUSR2 Signal = "USR2" -) - -var signals = map[Signal]int{ - SIGABRT: 6, - SIGALRM: 14, - SIGFPE: 8, - SIGHUP: 1, - SIGILL: 4, - SIGINT: 2, - SIGKILL: 9, - SIGPIPE: 13, - SIGQUIT: 3, - SIGSEGV: 11, - SIGTERM: 15, -} - -type TerminalModes map[uint8]uint32 - -// POSIX terminal mode flags as listed in RFC 4254 Section 8. -const ( - tty_OP_END = 0 - VINTR = 1 - VQUIT = 2 - VERASE = 3 - VKILL = 4 - VEOF = 5 - VEOL = 6 - VEOL2 = 7 - VSTART = 8 - VSTOP = 9 - VSUSP = 10 - VDSUSP = 11 - VREPRINT = 12 - VWERASE = 13 - VLNEXT = 14 - VFLUSH = 15 - VSWTCH = 16 - VSTATUS = 17 - VDISCARD = 18 - IGNPAR = 30 - PARMRK = 31 - INPCK = 32 - ISTRIP = 33 - INLCR = 34 - IGNCR = 35 - ICRNL = 36 - IUCLC = 37 - IXON = 38 - IXANY = 39 - IXOFF = 40 - IMAXBEL = 41 - ISIG = 50 - ICANON = 51 - XCASE = 52 - ECHO = 53 - ECHOE = 54 - ECHOK = 55 - ECHONL = 56 - NOFLSH = 57 - TOSTOP = 58 - IEXTEN = 59 - ECHOCTL = 60 - ECHOKE = 61 - PENDIN = 62 - OPOST = 70 - OLCUC = 71 - ONLCR = 72 - OCRNL = 73 - ONOCR = 74 - ONLRET = 75 - CS7 = 90 - CS8 = 91 - PARENB = 92 - PARODD = 93 - TTY_OP_ISPEED = 128 - TTY_OP_OSPEED = 129 -) - -// A Session represents a connection to a remote command or shell. -type Session struct { - // Stdin specifies the remote process's standard input. - // If Stdin is nil, the remote process reads from an empty - // bytes.Buffer. - Stdin io.Reader - - // Stdout and Stderr specify the remote process's standard - // output and error. - // - // If either is nil, Run connects the corresponding file - // descriptor to an instance of ioutil.Discard. There is a - // fixed amount of buffering that is shared for the two streams. - // If either blocks it may eventually cause the remote - // command to block. - Stdout io.Writer - Stderr io.Writer - - ch Channel // the channel backing this session - started bool // true once Start, Run or Shell is invoked. - copyFuncs []func() error - errors chan error // one send per copyFunc - - // true if pipe method is active - stdinpipe, stdoutpipe, stderrpipe bool - - // stdinPipeWriter is non-nil if StdinPipe has not been called - // and Stdin was specified by the user; it is the write end of - // a pipe connecting Session.Stdin to the stdin channel. - stdinPipeWriter io.WriteCloser - - exitStatus chan error -} - -// SendRequest sends an out-of-band channel request on the SSH channel -// underlying the session. -func (s *Session) SendRequest(name string, wantReply bool, payload []byte) (bool, error) { - return s.ch.SendRequest(name, wantReply, payload) -} - -func (s *Session) Close() error { - return s.ch.Close() -} - -// RFC 4254 Section 6.4. -type setenvRequest struct { - Name string - Value string -} - -// Setenv sets an environment variable that will be applied to any -// command executed by Shell or Run. -func (s *Session) Setenv(name, value string) error { - msg := setenvRequest{ - Name: name, - Value: value, - } - ok, err := s.ch.SendRequest("env", true, Marshal(&msg)) - if err == nil && !ok { - err = errors.New("ssh: setenv failed") - } - return err -} - -// RFC 4254 Section 6.2. -type ptyRequestMsg struct { - Term string - Columns uint32 - Rows uint32 - Width uint32 - Height uint32 - Modelist string -} - -// RequestPty requests the association of a pty with the session on the remote host. -func (s *Session) RequestPty(term string, h, w int, termmodes TerminalModes) error { - var tm []byte - for k, v := range termmodes { - kv := struct { - Key byte - Val uint32 - }{k, v} - - tm = append(tm, Marshal(&kv)...) - } - tm = append(tm, tty_OP_END) - req := ptyRequestMsg{ - Term: term, - Columns: uint32(w), - Rows: uint32(h), - Width: uint32(w * 8), - Height: uint32(h * 8), - Modelist: string(tm), - } - ok, err := s.ch.SendRequest("pty-req", true, Marshal(&req)) - if err == nil && !ok { - err = errors.New("ssh: pty-req failed") - } - return err -} - -// RFC 4254 Section 6.5. -type subsystemRequestMsg struct { - Subsystem string -} - -// RequestSubsystem requests the association of a subsystem with the session on the remote host. -// A subsystem is a predefined command that runs in the background when the ssh session is initiated -func (s *Session) RequestSubsystem(subsystem string) error { - msg := subsystemRequestMsg{ - Subsystem: subsystem, - } - ok, err := s.ch.SendRequest("subsystem", true, Marshal(&msg)) - if err == nil && !ok { - err = errors.New("ssh: subsystem request failed") - } - return err -} - -// RFC 4254 Section 6.9. -type signalMsg struct { - Signal string -} - -// Signal sends the given signal to the remote process. -// sig is one of the SIG* constants. -func (s *Session) Signal(sig Signal) error { - msg := signalMsg{ - Signal: string(sig), - } - - _, err := s.ch.SendRequest("signal", false, Marshal(&msg)) - return err -} - -// RFC 4254 Section 6.5. -type execMsg struct { - Command string -} - -// Start runs cmd on the remote host. Typically, the remote -// server passes cmd to the shell for interpretation. -// A Session only accepts one call to Run, Start or Shell. -func (s *Session) Start(cmd string) error { - if s.started { - return errors.New("ssh: session already started") - } - req := execMsg{ - Command: cmd, - } - - ok, err := s.ch.SendRequest("exec", true, Marshal(&req)) - if err == nil && !ok { - err = fmt.Errorf("ssh: command %v failed", cmd) - } - if err != nil { - return err - } - return s.start() -} - -// Run runs cmd on the remote host. Typically, the remote -// server passes cmd to the shell for interpretation. -// A Session only accepts one call to Run, Start, Shell, Output, -// or CombinedOutput. -// -// The returned error is nil if the command runs, has no problems -// copying stdin, stdout, and stderr, and exits with a zero exit -// status. -// -// If the command fails to run or doesn't complete successfully, the -// error is of type *ExitError. Other error types may be -// returned for I/O problems. -func (s *Session) Run(cmd string) error { - err := s.Start(cmd) - if err != nil { - return err - } - return s.Wait() -} - -// Output runs cmd on the remote host and returns its standard output. -func (s *Session) Output(cmd string) ([]byte, error) { - if s.Stdout != nil { - return nil, errors.New("ssh: Stdout already set") - } - var b bytes.Buffer - s.Stdout = &b - err := s.Run(cmd) - return b.Bytes(), err -} - -type singleWriter struct { - b bytes.Buffer - mu sync.Mutex -} - -func (w *singleWriter) Write(p []byte) (int, error) { - w.mu.Lock() - defer w.mu.Unlock() - return w.b.Write(p) -} - -// CombinedOutput runs cmd on the remote host and returns its combined -// standard output and standard error. -func (s *Session) CombinedOutput(cmd string) ([]byte, error) { - if s.Stdout != nil { - return nil, errors.New("ssh: Stdout already set") - } - if s.Stderr != nil { - return nil, errors.New("ssh: Stderr already set") - } - var b singleWriter - s.Stdout = &b - s.Stderr = &b - err := s.Run(cmd) - return b.b.Bytes(), err -} - -// Shell starts a login shell on the remote host. A Session only -// accepts one call to Run, Start, Shell, Output, or CombinedOutput. -func (s *Session) Shell() error { - if s.started { - return errors.New("ssh: session already started") - } - - ok, err := s.ch.SendRequest("shell", true, nil) - if err == nil && !ok { - return errors.New("ssh: could not start shell") - } - if err != nil { - return err - } - return s.start() -} - -func (s *Session) start() error { - s.started = true - - type F func(*Session) - for _, setupFd := range []F{(*Session).stdin, (*Session).stdout, (*Session).stderr} { - setupFd(s) - } - - s.errors = make(chan error, len(s.copyFuncs)) - for _, fn := range s.copyFuncs { - go func(fn func() error) { - s.errors <- fn() - }(fn) - } - return nil -} - -// Wait waits for the remote command to exit. -// -// The returned error is nil if the command runs, has no problems -// copying stdin, stdout, and stderr, and exits with a zero exit -// status. -// -// If the command fails to run or doesn't complete successfully, the -// error is of type *ExitError. Other error types may be -// returned for I/O problems. -func (s *Session) Wait() error { - if !s.started { - return errors.New("ssh: session not started") - } - waitErr := <-s.exitStatus - - if s.stdinPipeWriter != nil { - s.stdinPipeWriter.Close() - } - var copyError error - for _ = range s.copyFuncs { - if err := <-s.errors; err != nil && copyError == nil { - copyError = err - } - } - if waitErr != nil { - return waitErr - } - return copyError -} - -func (s *Session) wait(reqs <-chan *Request) error { - wm := Waitmsg{status: -1} - // Wait for msg channel to be closed before returning. - for msg := range reqs { - switch msg.Type { - case "exit-status": - d := msg.Payload - wm.status = int(d[0])<<24 | int(d[1])<<16 | int(d[2])<<8 | int(d[3]) - case "exit-signal": - var sigval struct { - Signal string - CoreDumped bool - Error string - Lang string - } - if err := Unmarshal(msg.Payload, &sigval); err != nil { - return err - } - - // Must sanitize strings? - wm.signal = sigval.Signal - wm.msg = sigval.Error - wm.lang = sigval.Lang - default: - // This handles keepalives and matches - // OpenSSH's behaviour. - if msg.WantReply { - msg.Reply(false, nil) - } - } - } - if wm.status == 0 { - return nil - } - if wm.status == -1 { - // exit-status was never sent from server - if wm.signal == "" { - return errors.New("wait: remote command exited without exit status or exit signal") - } - wm.status = 128 - if _, ok := signals[Signal(wm.signal)]; ok { - wm.status += signals[Signal(wm.signal)] - } - } - return &ExitError{wm} -} - -func (s *Session) stdin() { - if s.stdinpipe { - return - } - var stdin io.Reader - if s.Stdin == nil { - stdin = new(bytes.Buffer) - } else { - r, w := io.Pipe() - go func() { - _, err := io.Copy(w, s.Stdin) - w.CloseWithError(err) - }() - stdin, s.stdinPipeWriter = r, w - } - s.copyFuncs = append(s.copyFuncs, func() error { - _, err := io.Copy(s.ch, stdin) - if err1 := s.ch.CloseWrite(); err == nil && err1 != io.EOF { - err = err1 - } - return err - }) -} - -func (s *Session) stdout() { - if s.stdoutpipe { - return - } - if s.Stdout == nil { - s.Stdout = ioutil.Discard - } - s.copyFuncs = append(s.copyFuncs, func() error { - _, err := io.Copy(s.Stdout, s.ch) - return err - }) -} - -func (s *Session) stderr() { - if s.stderrpipe { - return - } - if s.Stderr == nil { - s.Stderr = ioutil.Discard - } - s.copyFuncs = append(s.copyFuncs, func() error { - _, err := io.Copy(s.Stderr, s.ch.Stderr()) - return err - }) -} - -// sessionStdin reroutes Close to CloseWrite. -type sessionStdin struct { - io.Writer - ch Channel -} - -func (s *sessionStdin) Close() error { - return s.ch.CloseWrite() -} - -// StdinPipe returns a pipe that will be connected to the -// remote command's standard input when the command starts. -func (s *Session) StdinPipe() (io.WriteCloser, error) { - if s.Stdin != nil { - return nil, errors.New("ssh: Stdin already set") - } - if s.started { - return nil, errors.New("ssh: StdinPipe after process started") - } - s.stdinpipe = true - return &sessionStdin{s.ch, s.ch}, nil -} - -// StdoutPipe returns a pipe that will be connected to the -// remote command's standard output when the command starts. -// There is a fixed amount of buffering that is shared between -// stdout and stderr streams. If the StdoutPipe reader is -// not serviced fast enough it may eventually cause the -// remote command to block. -func (s *Session) StdoutPipe() (io.Reader, error) { - if s.Stdout != nil { - return nil, errors.New("ssh: Stdout already set") - } - if s.started { - return nil, errors.New("ssh: StdoutPipe after process started") - } - s.stdoutpipe = true - return s.ch, nil -} - -// StderrPipe returns a pipe that will be connected to the -// remote command's standard error when the command starts. -// There is a fixed amount of buffering that is shared between -// stdout and stderr streams. If the StderrPipe reader is -// not serviced fast enough it may eventually cause the -// remote command to block. -func (s *Session) StderrPipe() (io.Reader, error) { - if s.Stderr != nil { - return nil, errors.New("ssh: Stderr already set") - } - if s.started { - return nil, errors.New("ssh: StderrPipe after process started") - } - s.stderrpipe = true - return s.ch.Stderr(), nil -} - -// newSession returns a new interactive session on the remote host. -func newSession(ch Channel, reqs <-chan *Request) (*Session, error) { - s := &Session{ - ch: ch, - } - s.exitStatus = make(chan error, 1) - go func() { - s.exitStatus <- s.wait(reqs) - }() - - return s, nil -} - -// An ExitError reports unsuccessful completion of a remote command. -type ExitError struct { - Waitmsg -} - -func (e *ExitError) Error() string { - return e.Waitmsg.String() -} - -// Waitmsg stores the information about an exited remote command -// as reported by Wait. -type Waitmsg struct { - status int - signal string - msg string - lang string -} - -// ExitStatus returns the exit status of the remote command. -func (w Waitmsg) ExitStatus() int { - return w.status -} - -// Signal returns the exit signal of the remote command if -// it was terminated violently. -func (w Waitmsg) Signal() string { - return w.signal -} - -// Msg returns the exit message given by the remote command -func (w Waitmsg) Msg() string { - return w.msg -} - -// Lang returns the language tag. See RFC 3066 -func (w Waitmsg) Lang() string { - return w.lang -} - -func (w Waitmsg) String() string { - str := fmt.Sprintf("Process exited with status %v", w.status) - if w.signal != "" { - str += fmt.Sprintf(" from signal %v", w.signal) - } - if w.msg != "" { - str += fmt.Sprintf(". Reason was: %v", w.msg) - } - return str -} diff --git a/vendor/golang.org/x/crypto/ssh/session_test.go b/vendor/golang.org/x/crypto/ssh/session_test.go deleted file mode 100644 index f7f0f76..0000000 --- a/vendor/golang.org/x/crypto/ssh/session_test.go +++ /dev/null @@ -1,774 +0,0 @@ -// 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 ssh - -// Session tests. - -import ( - "bytes" - crypto_rand "crypto/rand" - "errors" - "io" - "io/ioutil" - "math/rand" - "net" - "testing" - - "golang.org/x/crypto/ssh/terminal" -) - -type serverType func(Channel, <-chan *Request, *testing.T) - -// dial constructs a new test server and returns a *ClientConn. -func dial(handler serverType, t *testing.T) *Client { - c1, c2, err := netPipe() - if err != nil { - t.Fatalf("netPipe: %v", err) - } - - go func() { - defer c1.Close() - conf := ServerConfig{ - NoClientAuth: true, - } - conf.AddHostKey(testSigners["rsa"]) - - _, chans, reqs, err := NewServerConn(c1, &conf) - if err != nil { - t.Fatalf("Unable to handshake: %v", err) - } - go DiscardRequests(reqs) - - for newCh := range chans { - if newCh.ChannelType() != "session" { - newCh.Reject(UnknownChannelType, "unknown channel type") - continue - } - - ch, inReqs, err := newCh.Accept() - if err != nil { - t.Errorf("Accept: %v", err) - continue - } - go func() { - handler(ch, inReqs, t) - }() - } - }() - - config := &ClientConfig{ - User: "testuser", - } - - conn, chans, reqs, err := NewClientConn(c2, "", config) - if err != nil { - t.Fatalf("unable to dial remote side: %v", err) - } - - return NewClient(conn, chans, reqs) -} - -// Test a simple string is returned to session.Stdout. -func TestSessionShell(t *testing.T) { - conn := dial(shellHandler, t) - defer conn.Close() - session, err := conn.NewSession() - if err != nil { - t.Fatalf("Unable to request new session: %v", err) - } - defer session.Close() - stdout := new(bytes.Buffer) - session.Stdout = stdout - if err := session.Shell(); err != nil { - t.Fatalf("Unable to execute command: %s", err) - } - if err := session.Wait(); err != nil { - t.Fatalf("Remote command did not exit cleanly: %v", err) - } - actual := stdout.String() - if actual != "golang" { - t.Fatalf("Remote shell did not return expected string: expected=golang, actual=%s", actual) - } -} - -// TODO(dfc) add support for Std{in,err}Pipe when the Server supports it. - -// Test a simple string is returned via StdoutPipe. -func TestSessionStdoutPipe(t *testing.T) { - conn := dial(shellHandler, t) - defer conn.Close() - session, err := conn.NewSession() - if err != nil { - t.Fatalf("Unable to request new session: %v", err) - } - defer session.Close() - stdout, err := session.StdoutPipe() - if err != nil { - t.Fatalf("Unable to request StdoutPipe(): %v", err) - } - var buf bytes.Buffer - if err := session.Shell(); err != nil { - t.Fatalf("Unable to execute command: %v", err) - } - done := make(chan bool, 1) - go func() { - if _, err := io.Copy(&buf, stdout); err != nil { - t.Errorf("Copy of stdout failed: %v", err) - } - done <- true - }() - if err := session.Wait(); err != nil { - t.Fatalf("Remote command did not exit cleanly: %v", err) - } - <-done - actual := buf.String() - if actual != "golang" { - t.Fatalf("Remote shell did not return expected string: expected=golang, actual=%s", actual) - } -} - -// Test that a simple string is returned via the Output helper, -// and that stderr is discarded. -func TestSessionOutput(t *testing.T) { - conn := dial(fixedOutputHandler, t) - defer conn.Close() - session, err := conn.NewSession() - if err != nil { - t.Fatalf("Unable to request new session: %v", err) - } - defer session.Close() - - buf, err := session.Output("") // cmd is ignored by fixedOutputHandler - if err != nil { - t.Error("Remote command did not exit cleanly:", err) - } - w := "this-is-stdout." - g := string(buf) - if g != w { - t.Error("Remote command did not return expected string:") - t.Logf("want %q", w) - t.Logf("got %q", g) - } -} - -// Test that both stdout and stderr are returned -// via the CombinedOutput helper. -func TestSessionCombinedOutput(t *testing.T) { - conn := dial(fixedOutputHandler, t) - defer conn.Close() - session, err := conn.NewSession() - if err != nil { - t.Fatalf("Unable to request new session: %v", err) - } - defer session.Close() - - buf, err := session.CombinedOutput("") // cmd is ignored by fixedOutputHandler - if err != nil { - t.Error("Remote command did not exit cleanly:", err) - } - const stdout = "this-is-stdout." - const stderr = "this-is-stderr." - g := string(buf) - if g != stdout+stderr && g != stderr+stdout { - t.Error("Remote command did not return expected string:") - t.Logf("want %q, or %q", stdout+stderr, stderr+stdout) - t.Logf("got %q", g) - } -} - -// Test non-0 exit status is returned correctly. -func TestExitStatusNonZero(t *testing.T) { - conn := dial(exitStatusNonZeroHandler, t) - defer conn.Close() - session, err := conn.NewSession() - if err != nil { - t.Fatalf("Unable to request new session: %v", err) - } - defer session.Close() - if err := session.Shell(); err != nil { - t.Fatalf("Unable to execute command: %v", err) - } - err = session.Wait() - if err == nil { - t.Fatalf("expected command to fail but it didn't") - } - e, ok := err.(*ExitError) - if !ok { - t.Fatalf("expected *ExitError but got %T", err) - } - if e.ExitStatus() != 15 { - t.Fatalf("expected command to exit with 15 but got %v", e.ExitStatus()) - } -} - -// Test 0 exit status is returned correctly. -func TestExitStatusZero(t *testing.T) { - conn := dial(exitStatusZeroHandler, t) - defer conn.Close() - session, err := conn.NewSession() - if err != nil { - t.Fatalf("Unable to request new session: %v", err) - } - defer session.Close() - - if err := session.Shell(); err != nil { - t.Fatalf("Unable to execute command: %v", err) - } - err = session.Wait() - if err != nil { - t.Fatalf("expected nil but got %v", err) - } -} - -// Test exit signal and status are both returned correctly. -func TestExitSignalAndStatus(t *testing.T) { - conn := dial(exitSignalAndStatusHandler, t) - defer conn.Close() - session, err := conn.NewSession() - if err != nil { - t.Fatalf("Unable to request new session: %v", err) - } - defer session.Close() - if err := session.Shell(); err != nil { - t.Fatalf("Unable to execute command: %v", err) - } - err = session.Wait() - if err == nil { - t.Fatalf("expected command to fail but it didn't") - } - e, ok := err.(*ExitError) - if !ok { - t.Fatalf("expected *ExitError but got %T", err) - } - if e.Signal() != "TERM" || e.ExitStatus() != 15 { - t.Fatalf("expected command to exit with signal TERM and status 15 but got signal %s and status %v", e.Signal(), e.ExitStatus()) - } -} - -// Test exit signal and status are both returned correctly. -func TestKnownExitSignalOnly(t *testing.T) { - conn := dial(exitSignalHandler, t) - defer conn.Close() - session, err := conn.NewSession() - if err != nil { - t.Fatalf("Unable to request new session: %v", err) - } - defer session.Close() - if err := session.Shell(); err != nil { - t.Fatalf("Unable to execute command: %v", err) - } - err = session.Wait() - if err == nil { - t.Fatalf("expected command to fail but it didn't") - } - e, ok := err.(*ExitError) - if !ok { - t.Fatalf("expected *ExitError but got %T", err) - } - if e.Signal() != "TERM" || e.ExitStatus() != 143 { - t.Fatalf("expected command to exit with signal TERM and status 143 but got signal %s and status %v", e.Signal(), e.ExitStatus()) - } -} - -// Test exit signal and status are both returned correctly. -func TestUnknownExitSignal(t *testing.T) { - conn := dial(exitSignalUnknownHandler, t) - defer conn.Close() - session, err := conn.NewSession() - if err != nil { - t.Fatalf("Unable to request new session: %v", err) - } - defer session.Close() - if err := session.Shell(); err != nil { - t.Fatalf("Unable to execute command: %v", err) - } - err = session.Wait() - if err == nil { - t.Fatalf("expected command to fail but it didn't") - } - e, ok := err.(*ExitError) - if !ok { - t.Fatalf("expected *ExitError but got %T", err) - } - if e.Signal() != "SYS" || e.ExitStatus() != 128 { - t.Fatalf("expected command to exit with signal SYS and status 128 but got signal %s and status %v", e.Signal(), e.ExitStatus()) - } -} - -// Test WaitMsg is not returned if the channel closes abruptly. -func TestExitWithoutStatusOrSignal(t *testing.T) { - conn := dial(exitWithoutSignalOrStatus, t) - defer conn.Close() - session, err := conn.NewSession() - if err != nil { - t.Fatalf("Unable to request new session: %v", err) - } - defer session.Close() - if err := session.Shell(); err != nil { - t.Fatalf("Unable to execute command: %v", err) - } - err = session.Wait() - if err == nil { - t.Fatalf("expected command to fail but it didn't") - } - _, ok := err.(*ExitError) - if ok { - // you can't actually test for errors.errorString - // because it's not exported. - t.Fatalf("expected *errorString but got %T", err) - } -} - -// windowTestBytes is the number of bytes that we'll send to the SSH server. -const windowTestBytes = 16000 * 200 - -// TestServerWindow writes random data to the server. The server is expected to echo -// the same data back, which is compared against the original. -func TestServerWindow(t *testing.T) { - origBuf := bytes.NewBuffer(make([]byte, 0, windowTestBytes)) - io.CopyN(origBuf, crypto_rand.Reader, windowTestBytes) - origBytes := origBuf.Bytes() - - conn := dial(echoHandler, t) - defer conn.Close() - session, err := conn.NewSession() - if err != nil { - t.Fatal(err) - } - defer session.Close() - result := make(chan []byte) - - go func() { - defer close(result) - echoedBuf := bytes.NewBuffer(make([]byte, 0, windowTestBytes)) - serverStdout, err := session.StdoutPipe() - if err != nil { - t.Errorf("StdoutPipe failed: %v", err) - return - } - n, err := copyNRandomly("stdout", echoedBuf, serverStdout, windowTestBytes) - if err != nil && err != io.EOF { - t.Errorf("Read only %d bytes from server, expected %d: %v", n, windowTestBytes, err) - } - result <- echoedBuf.Bytes() - }() - - serverStdin, err := session.StdinPipe() - if err != nil { - t.Fatalf("StdinPipe failed: %v", err) - } - written, err := copyNRandomly("stdin", serverStdin, origBuf, windowTestBytes) - if err != nil { - t.Fatalf("failed to copy origBuf to serverStdin: %v", err) - } - if written != windowTestBytes { - t.Fatalf("Wrote only %d of %d bytes to server", written, windowTestBytes) - } - - echoedBytes := <-result - - if !bytes.Equal(origBytes, echoedBytes) { - t.Fatalf("Echoed buffer differed from original, orig %d, echoed %d", len(origBytes), len(echoedBytes)) - } -} - -// Verify the client can handle a keepalive packet from the server. -func TestClientHandlesKeepalives(t *testing.T) { - conn := dial(channelKeepaliveSender, t) - defer conn.Close() - session, err := conn.NewSession() - if err != nil { - t.Fatal(err) - } - defer session.Close() - if err := session.Shell(); err != nil { - t.Fatalf("Unable to execute command: %v", err) - } - err = session.Wait() - if err != nil { - t.Fatalf("expected nil but got: %v", err) - } -} - -type exitStatusMsg struct { - Status uint32 -} - -type exitSignalMsg struct { - Signal string - CoreDumped bool - Errmsg string - Lang string -} - -func handleTerminalRequests(in <-chan *Request) { - for req := range in { - ok := false - switch req.Type { - case "shell": - ok = true - if len(req.Payload) > 0 { - // We don't accept any commands, only the default shell. - ok = false - } - case "env": - ok = true - } - req.Reply(ok, nil) - } -} - -func newServerShell(ch Channel, in <-chan *Request, prompt string) *terminal.Terminal { - term := terminal.NewTerminal(ch, prompt) - go handleTerminalRequests(in) - return term -} - -func exitStatusZeroHandler(ch Channel, in <-chan *Request, t *testing.T) { - defer ch.Close() - // this string is returned to stdout - shell := newServerShell(ch, in, "> ") - readLine(shell, t) - sendStatus(0, ch, t) -} - -func exitStatusNonZeroHandler(ch Channel, in <-chan *Request, t *testing.T) { - defer ch.Close() - shell := newServerShell(ch, in, "> ") - readLine(shell, t) - sendStatus(15, ch, t) -} - -func exitSignalAndStatusHandler(ch Channel, in <-chan *Request, t *testing.T) { - defer ch.Close() - shell := newServerShell(ch, in, "> ") - readLine(shell, t) - sendStatus(15, ch, t) - sendSignal("TERM", ch, t) -} - -func exitSignalHandler(ch Channel, in <-chan *Request, t *testing.T) { - defer ch.Close() - shell := newServerShell(ch, in, "> ") - readLine(shell, t) - sendSignal("TERM", ch, t) -} - -func exitSignalUnknownHandler(ch Channel, in <-chan *Request, t *testing.T) { - defer ch.Close() - shell := newServerShell(ch, in, "> ") - readLine(shell, t) - sendSignal("SYS", ch, t) -} - -func exitWithoutSignalOrStatus(ch Channel, in <-chan *Request, t *testing.T) { - defer ch.Close() - shell := newServerShell(ch, in, "> ") - readLine(shell, t) -} - -func shellHandler(ch Channel, in <-chan *Request, t *testing.T) { - defer ch.Close() - // this string is returned to stdout - shell := newServerShell(ch, in, "golang") - readLine(shell, t) - sendStatus(0, ch, t) -} - -// Ignores the command, writes fixed strings to stderr and stdout. -// Strings are "this-is-stdout." and "this-is-stderr.". -func fixedOutputHandler(ch Channel, in <-chan *Request, t *testing.T) { - defer ch.Close() - _, err := ch.Read(nil) - - req, ok := <-in - if !ok { - t.Fatalf("error: expected channel request, got: %#v", err) - return - } - - // ignore request, always send some text - req.Reply(true, nil) - - _, err = io.WriteString(ch, "this-is-stdout.") - if err != nil { - t.Fatalf("error writing on server: %v", err) - } - _, err = io.WriteString(ch.Stderr(), "this-is-stderr.") - if err != nil { - t.Fatalf("error writing on server: %v", err) - } - sendStatus(0, ch, t) -} - -func readLine(shell *terminal.Terminal, t *testing.T) { - if _, err := shell.ReadLine(); err != nil && err != io.EOF { - t.Errorf("unable to read line: %v", err) - } -} - -func sendStatus(status uint32, ch Channel, t *testing.T) { - msg := exitStatusMsg{ - Status: status, - } - if _, err := ch.SendRequest("exit-status", false, Marshal(&msg)); err != nil { - t.Errorf("unable to send status: %v", err) - } -} - -func sendSignal(signal string, ch Channel, t *testing.T) { - sig := exitSignalMsg{ - Signal: signal, - CoreDumped: false, - Errmsg: "Process terminated", - Lang: "en-GB-oed", - } - if _, err := ch.SendRequest("exit-signal", false, Marshal(&sig)); err != nil { - t.Errorf("unable to send signal: %v", err) - } -} - -func discardHandler(ch Channel, t *testing.T) { - defer ch.Close() - io.Copy(ioutil.Discard, ch) -} - -func echoHandler(ch Channel, in <-chan *Request, t *testing.T) { - defer ch.Close() - if n, err := copyNRandomly("echohandler", ch, ch, windowTestBytes); err != nil { - t.Errorf("short write, wrote %d, expected %d: %v ", n, windowTestBytes, err) - } -} - -// copyNRandomly copies n bytes from src to dst. It uses a variable, and random, -// buffer size to exercise more code paths. -func copyNRandomly(title string, dst io.Writer, src io.Reader, n int) (int, error) { - var ( - buf = make([]byte, 32*1024) - written int - remaining = n - ) - for remaining > 0 { - l := rand.Intn(1 << 15) - if remaining < l { - l = remaining - } - nr, er := src.Read(buf[:l]) - nw, ew := dst.Write(buf[:nr]) - remaining -= nw - written += nw - if ew != nil { - return written, ew - } - if nr != nw { - return written, io.ErrShortWrite - } - if er != nil && er != io.EOF { - return written, er - } - } - return written, nil -} - -func channelKeepaliveSender(ch Channel, in <-chan *Request, t *testing.T) { - defer ch.Close() - shell := newServerShell(ch, in, "> ") - readLine(shell, t) - if _, err := ch.SendRequest("keepalive@openssh.com", true, nil); err != nil { - t.Errorf("unable to send channel keepalive request: %v", err) - } - sendStatus(0, ch, t) -} - -func TestClientWriteEOF(t *testing.T) { - conn := dial(simpleEchoHandler, t) - defer conn.Close() - - session, err := conn.NewSession() - if err != nil { - t.Fatal(err) - } - defer session.Close() - stdin, err := session.StdinPipe() - if err != nil { - t.Fatalf("StdinPipe failed: %v", err) - } - stdout, err := session.StdoutPipe() - if err != nil { - t.Fatalf("StdoutPipe failed: %v", err) - } - - data := []byte(`0000`) - _, err = stdin.Write(data) - if err != nil { - t.Fatalf("Write failed: %v", err) - } - stdin.Close() - - res, err := ioutil.ReadAll(stdout) - if err != nil { - t.Fatalf("Read failed: %v", err) - } - - if !bytes.Equal(data, res) { - t.Fatalf("Read differed from write, wrote: %v, read: %v", data, res) - } -} - -func simpleEchoHandler(ch Channel, in <-chan *Request, t *testing.T) { - defer ch.Close() - data, err := ioutil.ReadAll(ch) - if err != nil { - t.Errorf("handler read error: %v", err) - } - _, err = ch.Write(data) - if err != nil { - t.Errorf("handler write error: %v", err) - } -} - -func TestSessionID(t *testing.T) { - c1, c2, err := netPipe() - if err != nil { - t.Fatalf("netPipe: %v", err) - } - defer c1.Close() - defer c2.Close() - - serverID := make(chan []byte, 1) - clientID := make(chan []byte, 1) - - serverConf := &ServerConfig{ - NoClientAuth: true, - } - serverConf.AddHostKey(testSigners["ecdsa"]) - clientConf := &ClientConfig{ - User: "user", - } - - go func() { - conn, chans, reqs, err := NewServerConn(c1, serverConf) - if err != nil { - t.Fatalf("server handshake: %v", err) - } - serverID <- conn.SessionID() - go DiscardRequests(reqs) - for ch := range chans { - ch.Reject(Prohibited, "") - } - }() - - go func() { - conn, chans, reqs, err := NewClientConn(c2, "", clientConf) - if err != nil { - t.Fatalf("client handshake: %v", err) - } - clientID <- conn.SessionID() - go DiscardRequests(reqs) - for ch := range chans { - ch.Reject(Prohibited, "") - } - }() - - s := <-serverID - c := <-clientID - if bytes.Compare(s, c) != 0 { - t.Errorf("server session ID (%x) != client session ID (%x)", s, c) - } else if len(s) == 0 { - t.Errorf("client and server SessionID were empty.") - } -} - -type noReadConn struct { - readSeen bool - net.Conn -} - -func (c *noReadConn) Close() error { - return nil -} - -func (c *noReadConn) Read(b []byte) (int, error) { - c.readSeen = true - return 0, errors.New("noReadConn error") -} - -func TestInvalidServerConfiguration(t *testing.T) { - c1, c2, err := netPipe() - if err != nil { - t.Fatalf("netPipe: %v", err) - } - defer c1.Close() - defer c2.Close() - - serveConn := noReadConn{Conn: c1} - serverConf := &ServerConfig{} - - NewServerConn(&serveConn, serverConf) - if serveConn.readSeen { - t.Fatalf("NewServerConn attempted to Read() from Conn while configuration is missing host key") - } - - serverConf.AddHostKey(testSigners["ecdsa"]) - - NewServerConn(&serveConn, serverConf) - if serveConn.readSeen { - t.Fatalf("NewServerConn attempted to Read() from Conn while configuration is missing authentication method") - } -} - -func TestHostKeyAlgorithms(t *testing.T) { - serverConf := &ServerConfig{ - NoClientAuth: true, - } - serverConf.AddHostKey(testSigners["rsa"]) - serverConf.AddHostKey(testSigners["ecdsa"]) - - connect := func(clientConf *ClientConfig, want string) { - var alg string - clientConf.HostKeyCallback = func(h string, a net.Addr, key PublicKey) error { - alg = key.Type() - return nil - } - c1, c2, err := netPipe() - if err != nil { - t.Fatalf("netPipe: %v", err) - } - defer c1.Close() - defer c2.Close() - - go NewServerConn(c1, serverConf) - _, _, _, err = NewClientConn(c2, "", clientConf) - if err != nil { - t.Fatalf("NewClientConn: %v", err) - } - if alg != want { - t.Errorf("selected key algorithm %s, want %s", alg, want) - } - } - - // By default, we get the preferred algorithm, which is ECDSA 256. - - clientConf := &ClientConfig{} - connect(clientConf, KeyAlgoECDSA256) - - // Client asks for RSA explicitly. - clientConf.HostKeyAlgorithms = []string{KeyAlgoRSA} - connect(clientConf, KeyAlgoRSA) - - c1, c2, err := netPipe() - if err != nil { - t.Fatalf("netPipe: %v", err) - } - defer c1.Close() - defer c2.Close() - - go NewServerConn(c1, serverConf) - clientConf.HostKeyAlgorithms = []string{"nonexistent-hostkey-algo"} - _, _, _, err = NewClientConn(c2, "", clientConf) - if err == nil { - t.Fatal("succeeded connecting with unknown hostkey algorithm") - } -} diff --git a/vendor/golang.org/x/crypto/ssh/tcpip.go b/vendor/golang.org/x/crypto/ssh/tcpip.go deleted file mode 100644 index 6151241..0000000 --- a/vendor/golang.org/x/crypto/ssh/tcpip.go +++ /dev/null @@ -1,407 +0,0 @@ -// 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 ssh - -import ( - "errors" - "fmt" - "io" - "math/rand" - "net" - "strconv" - "strings" - "sync" - "time" -) - -// Listen requests the remote peer open a listening socket on -// addr. Incoming connections will be available by calling Accept on -// the returned net.Listener. The listener must be serviced, or the -// SSH connection may hang. -func (c *Client) Listen(n, addr string) (net.Listener, error) { - laddr, err := net.ResolveTCPAddr(n, addr) - if err != nil { - return nil, err - } - return c.ListenTCP(laddr) -} - -// Automatic port allocation is broken with OpenSSH before 6.0. See -// also https://bugzilla.mindrot.org/show_bug.cgi?id=2017. In -// particular, OpenSSH 5.9 sends a channelOpenMsg with port number 0, -// rather than the actual port number. This means you can never open -// two different listeners with auto allocated ports. We work around -// this by trying explicit ports until we succeed. - -const openSSHPrefix = "OpenSSH_" - -var portRandomizer = rand.New(rand.NewSource(time.Now().UnixNano())) - -// isBrokenOpenSSHVersion returns true if the given version string -// specifies a version of OpenSSH that is known to have a bug in port -// forwarding. -func isBrokenOpenSSHVersion(versionStr string) bool { - i := strings.Index(versionStr, openSSHPrefix) - if i < 0 { - return false - } - i += len(openSSHPrefix) - j := i - for ; j < len(versionStr); j++ { - if versionStr[j] < '0' || versionStr[j] > '9' { - break - } - } - version, _ := strconv.Atoi(versionStr[i:j]) - return version < 6 -} - -// autoPortListenWorkaround simulates automatic port allocation by -// trying random ports repeatedly. -func (c *Client) autoPortListenWorkaround(laddr *net.TCPAddr) (net.Listener, error) { - var sshListener net.Listener - var err error - const tries = 10 - for i := 0; i < tries; i++ { - addr := *laddr - addr.Port = 1024 + portRandomizer.Intn(60000) - sshListener, err = c.ListenTCP(&addr) - if err == nil { - laddr.Port = addr.Port - return sshListener, err - } - } - return nil, fmt.Errorf("ssh: listen on random port failed after %d tries: %v", tries, err) -} - -// RFC 4254 7.1 -type channelForwardMsg struct { - addr string - rport uint32 -} - -// ListenTCP requests the remote peer open a listening socket -// on laddr. Incoming connections will be available by calling -// Accept on the returned net.Listener. -func (c *Client) ListenTCP(laddr *net.TCPAddr) (net.Listener, error) { - if laddr.Port == 0 && isBrokenOpenSSHVersion(string(c.ServerVersion())) { - return c.autoPortListenWorkaround(laddr) - } - - m := channelForwardMsg{ - laddr.IP.String(), - uint32(laddr.Port), - } - // send message - ok, resp, err := c.SendRequest("tcpip-forward", true, Marshal(&m)) - if err != nil { - return nil, err - } - if !ok { - return nil, errors.New("ssh: tcpip-forward request denied by peer") - } - - // If the original port was 0, then the remote side will - // supply a real port number in the response. - if laddr.Port == 0 { - var p struct { - Port uint32 - } - if err := Unmarshal(resp, &p); err != nil { - return nil, err - } - laddr.Port = int(p.Port) - } - - // Register this forward, using the port number we obtained. - ch := c.forwards.add(*laddr) - - return &tcpListener{laddr, c, ch}, nil -} - -// forwardList stores a mapping between remote -// forward requests and the tcpListeners. -type forwardList struct { - sync.Mutex - entries []forwardEntry -} - -// forwardEntry represents an established mapping of a laddr on a -// remote ssh server to a channel connected to a tcpListener. -type forwardEntry struct { - laddr net.TCPAddr - c chan forward -} - -// forward represents an incoming forwarded tcpip connection. The -// arguments to add/remove/lookup should be address as specified in -// the original forward-request. -type forward struct { - newCh NewChannel // the ssh client channel underlying this forward - raddr *net.TCPAddr // the raddr of the incoming connection -} - -func (l *forwardList) add(addr net.TCPAddr) chan forward { - l.Lock() - defer l.Unlock() - f := forwardEntry{ - addr, - make(chan forward, 1), - } - l.entries = append(l.entries, f) - return f.c -} - -// See RFC 4254, section 7.2 -type forwardedTCPPayload struct { - Addr string - Port uint32 - OriginAddr string - OriginPort uint32 -} - -// parseTCPAddr parses the originating address from the remote into a *net.TCPAddr. -func parseTCPAddr(addr string, port uint32) (*net.TCPAddr, error) { - if port == 0 || port > 65535 { - return nil, fmt.Errorf("ssh: port number out of range: %d", port) - } - ip := net.ParseIP(string(addr)) - if ip == nil { - return nil, fmt.Errorf("ssh: cannot parse IP address %q", addr) - } - return &net.TCPAddr{IP: ip, Port: int(port)}, nil -} - -func (l *forwardList) handleChannels(in <-chan NewChannel) { - for ch := range in { - var payload forwardedTCPPayload - if err := Unmarshal(ch.ExtraData(), &payload); err != nil { - ch.Reject(ConnectionFailed, "could not parse forwarded-tcpip payload: "+err.Error()) - continue - } - - // RFC 4254 section 7.2 specifies that incoming - // addresses should list the address, in string - // format. It is implied that this should be an IP - // address, as it would be impossible to connect to it - // otherwise. - laddr, err := parseTCPAddr(payload.Addr, payload.Port) - if err != nil { - ch.Reject(ConnectionFailed, err.Error()) - continue - } - raddr, err := parseTCPAddr(payload.OriginAddr, payload.OriginPort) - if err != nil { - ch.Reject(ConnectionFailed, err.Error()) - continue - } - - if ok := l.forward(*laddr, *raddr, ch); !ok { - // Section 7.2, implementations MUST reject spurious incoming - // connections. - ch.Reject(Prohibited, "no forward for address") - continue - } - } -} - -// remove removes the forward entry, and the channel feeding its -// listener. -func (l *forwardList) remove(addr net.TCPAddr) { - l.Lock() - defer l.Unlock() - for i, f := range l.entries { - if addr.IP.Equal(f.laddr.IP) && addr.Port == f.laddr.Port { - l.entries = append(l.entries[:i], l.entries[i+1:]...) - close(f.c) - return - } - } -} - -// closeAll closes and clears all forwards. -func (l *forwardList) closeAll() { - l.Lock() - defer l.Unlock() - for _, f := range l.entries { - close(f.c) - } - l.entries = nil -} - -func (l *forwardList) forward(laddr, raddr net.TCPAddr, ch NewChannel) bool { - l.Lock() - defer l.Unlock() - for _, f := range l.entries { - if laddr.IP.Equal(f.laddr.IP) && laddr.Port == f.laddr.Port { - f.c <- forward{ch, &raddr} - return true - } - } - return false -} - -type tcpListener struct { - laddr *net.TCPAddr - - conn *Client - in <-chan forward -} - -// Accept waits for and returns the next connection to the listener. -func (l *tcpListener) Accept() (net.Conn, error) { - s, ok := <-l.in - if !ok { - return nil, io.EOF - } - ch, incoming, err := s.newCh.Accept() - if err != nil { - return nil, err - } - go DiscardRequests(incoming) - - return &tcpChanConn{ - Channel: ch, - laddr: l.laddr, - raddr: s.raddr, - }, nil -} - -// Close closes the listener. -func (l *tcpListener) Close() error { - m := channelForwardMsg{ - l.laddr.IP.String(), - uint32(l.laddr.Port), - } - - // this also closes the listener. - l.conn.forwards.remove(*l.laddr) - ok, _, err := l.conn.SendRequest("cancel-tcpip-forward", true, Marshal(&m)) - if err == nil && !ok { - err = errors.New("ssh: cancel-tcpip-forward failed") - } - return err -} - -// Addr returns the listener's network address. -func (l *tcpListener) Addr() net.Addr { - return l.laddr -} - -// Dial initiates a connection to the addr from the remote host. -// The resulting connection has a zero LocalAddr() and RemoteAddr(). -func (c *Client) Dial(n, addr string) (net.Conn, error) { - // Parse the address into host and numeric port. - host, portString, err := net.SplitHostPort(addr) - if err != nil { - return nil, err - } - port, err := strconv.ParseUint(portString, 10, 16) - if err != nil { - return nil, err - } - // Use a zero address for local and remote address. - zeroAddr := &net.TCPAddr{ - IP: net.IPv4zero, - Port: 0, - } - ch, err := c.dial(net.IPv4zero.String(), 0, host, int(port)) - if err != nil { - return nil, err - } - return &tcpChanConn{ - Channel: ch, - laddr: zeroAddr, - raddr: zeroAddr, - }, nil -} - -// DialTCP connects to the remote address raddr on the network net, -// which must be "tcp", "tcp4", or "tcp6". If laddr is not nil, it is used -// as the local address for the connection. -func (c *Client) DialTCP(n string, laddr, raddr *net.TCPAddr) (net.Conn, error) { - if laddr == nil { - laddr = &net.TCPAddr{ - IP: net.IPv4zero, - Port: 0, - } - } - ch, err := c.dial(laddr.IP.String(), laddr.Port, raddr.IP.String(), raddr.Port) - if err != nil { - return nil, err - } - return &tcpChanConn{ - Channel: ch, - laddr: laddr, - raddr: raddr, - }, nil -} - -// RFC 4254 7.2 -type channelOpenDirectMsg struct { - raddr string - rport uint32 - laddr string - lport uint32 -} - -func (c *Client) dial(laddr string, lport int, raddr string, rport int) (Channel, error) { - msg := channelOpenDirectMsg{ - raddr: raddr, - rport: uint32(rport), - laddr: laddr, - lport: uint32(lport), - } - ch, in, err := c.OpenChannel("direct-tcpip", Marshal(&msg)) - if err != nil { - return nil, err - } - go DiscardRequests(in) - return ch, err -} - -type tcpChan struct { - Channel // the backing channel -} - -// tcpChanConn fulfills the net.Conn interface without -// the tcpChan having to hold laddr or raddr directly. -type tcpChanConn struct { - Channel - laddr, raddr net.Addr -} - -// LocalAddr returns the local network address. -func (t *tcpChanConn) LocalAddr() net.Addr { - return t.laddr -} - -// RemoteAddr returns the remote network address. -func (t *tcpChanConn) RemoteAddr() net.Addr { - return t.raddr -} - -// SetDeadline sets the read and write deadlines associated -// with the connection. -func (t *tcpChanConn) SetDeadline(deadline time.Time) error { - if err := t.SetReadDeadline(deadline); err != nil { - return err - } - return t.SetWriteDeadline(deadline) -} - -// SetReadDeadline sets the read deadline. -// A zero value for t means Read will not time out. -// After the deadline, the error from Read will implement net.Error -// with Timeout() == true. -func (t *tcpChanConn) SetReadDeadline(deadline time.Time) error { - return errors.New("ssh: tcpChan: deadline not supported") -} - -// SetWriteDeadline exists to satisfy the net.Conn interface -// but is not implemented by this type. It always returns an error. -func (t *tcpChanConn) SetWriteDeadline(deadline time.Time) error { - return errors.New("ssh: tcpChan: deadline not supported") -} diff --git a/vendor/golang.org/x/crypto/ssh/tcpip_test.go b/vendor/golang.org/x/crypto/ssh/tcpip_test.go deleted file mode 100644 index f1265cb..0000000 --- a/vendor/golang.org/x/crypto/ssh/tcpip_test.go +++ /dev/null @@ -1,20 +0,0 @@ -// 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 ssh - -import ( - "testing" -) - -func TestAutoPortListenBroken(t *testing.T) { - broken := "SSH-2.0-OpenSSH_5.9hh11" - works := "SSH-2.0-OpenSSH_6.1" - if !isBrokenOpenSSHVersion(broken) { - t.Errorf("version %q not marked as broken", broken) - } - if isBrokenOpenSSHVersion(works) { - t.Errorf("version %q marked as broken", works) - } -} diff --git a/vendor/golang.org/x/crypto/ssh/terminal/terminal.go b/vendor/golang.org/x/crypto/ssh/terminal/terminal.go deleted file mode 100644 index 741eeb1..0000000 --- a/vendor/golang.org/x/crypto/ssh/terminal/terminal.go +++ /dev/null @@ -1,892 +0,0 @@ -// 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 - -import ( - "bytes" - "io" - "sync" - "unicode/utf8" -) - -// EscapeCodes contains escape sequences that can be written to the terminal in -// order to achieve different styles of text. -type EscapeCodes struct { - // Foreground colors - Black, Red, Green, Yellow, Blue, Magenta, Cyan, White []byte - - // Reset all attributes - Reset []byte -} - -var vt100EscapeCodes = EscapeCodes{ - Black: []byte{keyEscape, '[', '3', '0', 'm'}, - Red: []byte{keyEscape, '[', '3', '1', 'm'}, - Green: []byte{keyEscape, '[', '3', '2', 'm'}, - Yellow: []byte{keyEscape, '[', '3', '3', 'm'}, - Blue: []byte{keyEscape, '[', '3', '4', 'm'}, - Magenta: []byte{keyEscape, '[', '3', '5', 'm'}, - Cyan: []byte{keyEscape, '[', '3', '6', 'm'}, - White: []byte{keyEscape, '[', '3', '7', 'm'}, - - Reset: []byte{keyEscape, '[', '0', 'm'}, -} - -// Terminal contains the state for running a VT100 terminal that is capable of -// reading lines of input. -type Terminal struct { - // AutoCompleteCallback, if non-null, is called for each keypress with - // the full input line and the current position of the cursor (in - // bytes, as an index into |line|). If it returns ok=false, the key - // press is processed normally. Otherwise it returns a replacement line - // and the new cursor position. - AutoCompleteCallback func(line string, pos int, key rune) (newLine string, newPos int, ok bool) - - // Escape contains a pointer to the escape codes for this terminal. - // It's always a valid pointer, although the escape codes themselves - // may be empty if the terminal doesn't support them. - Escape *EscapeCodes - - // lock protects the terminal and the state in this object from - // concurrent processing of a key press and a Write() call. - lock sync.Mutex - - c io.ReadWriter - prompt []rune - - // line is the current line being entered. - line []rune - // pos is the logical position of the cursor in line - pos int - // echo is true if local echo is enabled - echo bool - // pasteActive is true iff there is a bracketed paste operation in - // progress. - pasteActive bool - - // cursorX contains the current X value of the cursor where the left - // edge is 0. cursorY contains the row number where the first row of - // the current line is 0. - cursorX, cursorY int - // maxLine is the greatest value of cursorY so far. - maxLine int - - termWidth, termHeight int - - // outBuf contains the terminal data to be sent. - outBuf []byte - // remainder contains the remainder of any partial key sequences after - // a read. It aliases into inBuf. - remainder []byte - inBuf [256]byte - - // history contains previously entered commands so that they can be - // accessed with the up and down keys. - history stRingBuffer - // historyIndex stores the currently accessed history entry, where zero - // means the immediately previous entry. - historyIndex int - // When navigating up and down the history it's possible to return to - // the incomplete, initial line. That value is stored in - // historyPending. - historyPending string -} - -// 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 &Terminal{ - Escape: &vt100EscapeCodes, - c: c, - prompt: []rune(prompt), - termWidth: 80, - termHeight: 24, - echo: true, - historyIndex: -1, - } -} - -const ( - keyCtrlD = 4 - keyCtrlU = 21 - keyEnter = '\r' - keyEscape = 27 - keyBackspace = 127 - keyUnknown = 0xd800 /* UTF-16 surrogate area */ + iota - keyUp - keyDown - keyLeft - keyRight - keyAltLeft - keyAltRight - keyHome - keyEnd - keyDeleteWord - keyDeleteLine - keyClearScreen - keyPasteStart - keyPasteEnd -) - -var pasteStart = []byte{keyEscape, '[', '2', '0', '0', '~'} -var pasteEnd = []byte{keyEscape, '[', '2', '0', '1', '~'} - -// bytesToKey tries to parse a key sequence from b. If successful, it returns -// the key and the remainder of the input. Otherwise it returns utf8.RuneError. -func bytesToKey(b []byte, pasteActive bool) (rune, []byte) { - if len(b) == 0 { - return utf8.RuneError, nil - } - - if !pasteActive { - switch b[0] { - case 1: // ^A - return keyHome, b[1:] - case 5: // ^E - return keyEnd, b[1:] - case 8: // ^H - return keyBackspace, b[1:] - case 11: // ^K - return keyDeleteLine, b[1:] - case 12: // ^L - return keyClearScreen, b[1:] - case 23: // ^W - return keyDeleteWord, b[1:] - } - } - - if b[0] != keyEscape { - if !utf8.FullRune(b) { - return utf8.RuneError, b - } - r, l := utf8.DecodeRune(b) - return r, b[l:] - } - - if !pasteActive && len(b) >= 3 && b[0] == keyEscape && b[1] == '[' { - switch b[2] { - case 'A': - return keyUp, b[3:] - case 'B': - return keyDown, b[3:] - case 'C': - return keyRight, b[3:] - case 'D': - return keyLeft, b[3:] - case 'H': - return keyHome, b[3:] - case 'F': - return keyEnd, b[3:] - } - } - - if !pasteActive && len(b) >= 6 && b[0] == keyEscape && b[1] == '[' && b[2] == '1' && b[3] == ';' && b[4] == '3' { - switch b[5] { - case 'C': - return keyAltRight, b[6:] - case 'D': - return keyAltLeft, b[6:] - } - } - - if !pasteActive && len(b) >= 6 && bytes.Equal(b[:6], pasteStart) { - return keyPasteStart, b[6:] - } - - if pasteActive && len(b) >= 6 && bytes.Equal(b[:6], pasteEnd) { - return keyPasteEnd, b[6:] - } - - // If we get here then we have a key that we don't recognise, or a - // partial sequence. It's not clear how one should find the end of a - // sequence without knowing them all, but it seems that [a-zA-Z~] only - // appears at the end of a sequence. - for i, c := range b[0:] { - if c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c == '~' { - return keyUnknown, b[i+1:] - } - } - - return utf8.RuneError, b -} - -// queue appends data to the end of t.outBuf -func (t *Terminal) queue(data []rune) { - t.outBuf = append(t.outBuf, []byte(string(data))...) -} - -var eraseUnderCursor = []rune{' ', keyEscape, '[', 'D'} -var space = []rune{' '} - -func isPrintable(key rune) bool { - isInSurrogateArea := key >= 0xd800 && key <= 0xdbff - return key >= 32 && !isInSurrogateArea -} - -// moveCursorToPos appends data to t.outBuf which will move the cursor to the -// given, logical position in the text. -func (t *Terminal) moveCursorToPos(pos int) { - if !t.echo { - return - } - - x := visualLength(t.prompt) + pos - y := x / t.termWidth - x = x % t.termWidth - - up := 0 - if y < t.cursorY { - up = t.cursorY - y - } - - down := 0 - if y > t.cursorY { - down = y - t.cursorY - } - - left := 0 - if x < t.cursorX { - left = t.cursorX - x - } - - right := 0 - if x > t.cursorX { - right = x - t.cursorX - } - - t.cursorX = x - t.cursorY = y - t.move(up, down, left, right) -} - -func (t *Terminal) move(up, down, left, right int) { - movement := make([]rune, 3*(up+down+left+right)) - m := movement - for i := 0; i < up; i++ { - m[0] = keyEscape - m[1] = '[' - m[2] = 'A' - m = m[3:] - } - for i := 0; i < down; i++ { - m[0] = keyEscape - m[1] = '[' - m[2] = 'B' - m = m[3:] - } - for i := 0; i < left; i++ { - m[0] = keyEscape - m[1] = '[' - m[2] = 'D' - m = m[3:] - } - for i := 0; i < right; i++ { - m[0] = keyEscape - m[1] = '[' - m[2] = 'C' - m = m[3:] - } - - t.queue(movement) -} - -func (t *Terminal) clearLineToRight() { - op := []rune{keyEscape, '[', 'K'} - t.queue(op) -} - -const maxLineLength = 4096 - -func (t *Terminal) setLine(newLine []rune, newPos int) { - if t.echo { - t.moveCursorToPos(0) - t.writeLine(newLine) - for i := len(newLine); i < len(t.line); i++ { - t.writeLine(space) - } - t.moveCursorToPos(newPos) - } - t.line = newLine - t.pos = newPos -} - -func (t *Terminal) advanceCursor(places int) { - t.cursorX += places - t.cursorY += t.cursorX / t.termWidth - if t.cursorY > t.maxLine { - t.maxLine = t.cursorY - } - t.cursorX = t.cursorX % t.termWidth - - if places > 0 && t.cursorX == 0 { - // Normally terminals will advance the current position - // when writing a character. But that doesn't happen - // for the last character in a line. However, when - // writing a character (except a new line) that causes - // a line wrap, the position will be advanced two - // places. - // - // So, if we are stopping at the end of a line, we - // need to write a newline so that our cursor can be - // advanced to the next line. - t.outBuf = append(t.outBuf, '\n') - } -} - -func (t *Terminal) eraseNPreviousChars(n int) { - if n == 0 { - return - } - - if t.pos < n { - n = t.pos - } - t.pos -= n - t.moveCursorToPos(t.pos) - - copy(t.line[t.pos:], t.line[n+t.pos:]) - t.line = t.line[:len(t.line)-n] - if t.echo { - t.writeLine(t.line[t.pos:]) - for i := 0; i < n; i++ { - t.queue(space) - } - t.advanceCursor(n) - t.moveCursorToPos(t.pos) - } -} - -// countToLeftWord returns then number of characters from the cursor to the -// start of the previous word. -func (t *Terminal) countToLeftWord() int { - if t.pos == 0 { - return 0 - } - - pos := t.pos - 1 - for pos > 0 { - if t.line[pos] != ' ' { - break - } - pos-- - } - for pos > 0 { - if t.line[pos] == ' ' { - pos++ - break - } - pos-- - } - - return t.pos - pos -} - -// countToRightWord returns then number of characters from the cursor to the -// start of the next word. -func (t *Terminal) countToRightWord() int { - pos := t.pos - for pos < len(t.line) { - if t.line[pos] == ' ' { - break - } - pos++ - } - for pos < len(t.line) { - if t.line[pos] != ' ' { - break - } - pos++ - } - return pos - t.pos -} - -// visualLength returns the number of visible glyphs in s. -func visualLength(runes []rune) int { - inEscapeSeq := false - length := 0 - - for _, r := range runes { - switch { - case inEscapeSeq: - if (r >= 'a' && r <= 'z') || (r >= 'A' && r <= 'Z') { - inEscapeSeq = false - } - case r == '\x1b': - inEscapeSeq = true - default: - length++ - } - } - - return length -} - -// handleKey processes the given key and, optionally, returns a line of text -// that the user has entered. -func (t *Terminal) handleKey(key rune) (line string, ok bool) { - if t.pasteActive && key != keyEnter { - t.addKeyToLine(key) - return - } - - switch key { - case keyBackspace: - if t.pos == 0 { - return - } - t.eraseNPreviousChars(1) - case keyAltLeft: - // move left by a word. - t.pos -= t.countToLeftWord() - t.moveCursorToPos(t.pos) - case keyAltRight: - // move right by a word. - t.pos += t.countToRightWord() - t.moveCursorToPos(t.pos) - case keyLeft: - if t.pos == 0 { - return - } - t.pos-- - t.moveCursorToPos(t.pos) - case keyRight: - if t.pos == len(t.line) { - return - } - t.pos++ - t.moveCursorToPos(t.pos) - case keyHome: - if t.pos == 0 { - return - } - t.pos = 0 - t.moveCursorToPos(t.pos) - case keyEnd: - if t.pos == len(t.line) { - return - } - t.pos = len(t.line) - t.moveCursorToPos(t.pos) - case keyUp: - entry, ok := t.history.NthPreviousEntry(t.historyIndex + 1) - if !ok { - return "", false - } - if t.historyIndex == -1 { - t.historyPending = string(t.line) - } - t.historyIndex++ - runes := []rune(entry) - t.setLine(runes, len(runes)) - case keyDown: - switch t.historyIndex { - case -1: - return - case 0: - runes := []rune(t.historyPending) - t.setLine(runes, len(runes)) - t.historyIndex-- - default: - entry, ok := t.history.NthPreviousEntry(t.historyIndex - 1) - if ok { - t.historyIndex-- - runes := []rune(entry) - t.setLine(runes, len(runes)) - } - } - case keyEnter: - t.moveCursorToPos(len(t.line)) - t.queue([]rune("\r\n")) - line = string(t.line) - ok = true - t.line = t.line[:0] - t.pos = 0 - t.cursorX = 0 - t.cursorY = 0 - t.maxLine = 0 - case keyDeleteWord: - // Delete zero or more spaces and then one or more characters. - t.eraseNPreviousChars(t.countToLeftWord()) - case keyDeleteLine: - // Delete everything from the current cursor position to the - // end of line. - for i := t.pos; i < len(t.line); i++ { - t.queue(space) - t.advanceCursor(1) - } - t.line = t.line[:t.pos] - t.moveCursorToPos(t.pos) - case keyCtrlD: - // Erase the character under the current position. - // The EOF case when the line is empty is handled in - // readLine(). - if t.pos < len(t.line) { - t.pos++ - t.eraseNPreviousChars(1) - } - case keyCtrlU: - t.eraseNPreviousChars(t.pos) - case keyClearScreen: - // Erases the screen and moves the cursor to the home position. - t.queue([]rune("\x1b[2J\x1b[H")) - t.queue(t.prompt) - t.cursorX, t.cursorY = 0, 0 - t.advanceCursor(visualLength(t.prompt)) - t.setLine(t.line, t.pos) - default: - if t.AutoCompleteCallback != nil { - prefix := string(t.line[:t.pos]) - suffix := string(t.line[t.pos:]) - - t.lock.Unlock() - newLine, newPos, completeOk := t.AutoCompleteCallback(prefix+suffix, len(prefix), key) - t.lock.Lock() - - if completeOk { - t.setLine([]rune(newLine), utf8.RuneCount([]byte(newLine)[:newPos])) - return - } - } - if !isPrintable(key) { - return - } - if len(t.line) == maxLineLength { - return - } - t.addKeyToLine(key) - } - return -} - -// addKeyToLine inserts the given key at the current position in the current -// line. -func (t *Terminal) addKeyToLine(key rune) { - if len(t.line) == cap(t.line) { - newLine := make([]rune, len(t.line), 2*(1+len(t.line))) - copy(newLine, t.line) - t.line = newLine - } - t.line = t.line[:len(t.line)+1] - copy(t.line[t.pos+1:], t.line[t.pos:]) - t.line[t.pos] = key - if t.echo { - t.writeLine(t.line[t.pos:]) - } - t.pos++ - t.moveCursorToPos(t.pos) -} - -func (t *Terminal) writeLine(line []rune) { - for len(line) != 0 { - remainingOnLine := t.termWidth - t.cursorX - todo := len(line) - if todo > remainingOnLine { - todo = remainingOnLine - } - t.queue(line[:todo]) - t.advanceCursor(visualLength(line[:todo])) - line = line[todo:] - } -} - -func (t *Terminal) Write(buf []byte) (n int, err error) { - t.lock.Lock() - defer t.lock.Unlock() - - if t.cursorX == 0 && t.cursorY == 0 { - // This is the easy case: there's nothing on the screen that we - // have to move out of the way. - return t.c.Write(buf) - } - - // We have a prompt and possibly user input on the screen. We - // have to clear it first. - t.move(0 /* up */, 0 /* down */, t.cursorX /* left */, 0 /* right */) - t.cursorX = 0 - t.clearLineToRight() - - for t.cursorY > 0 { - t.move(1 /* up */, 0, 0, 0) - t.cursorY-- - t.clearLineToRight() - } - - if _, err = t.c.Write(t.outBuf); err != nil { - return - } - t.outBuf = t.outBuf[:0] - - if n, err = t.c.Write(buf); err != nil { - return - } - - t.writeLine(t.prompt) - if t.echo { - t.writeLine(t.line) - } - - t.moveCursorToPos(t.pos) - - if _, err = t.c.Write(t.outBuf); err != nil { - return - } - t.outBuf = t.outBuf[:0] - return -} - -// ReadPassword temporarily changes the prompt and reads a password, without -// echo, from the terminal. -func (t *Terminal) ReadPassword(prompt string) (line string, err error) { - t.lock.Lock() - defer t.lock.Unlock() - - oldPrompt := t.prompt - t.prompt = []rune(prompt) - t.echo = false - - line, err = t.readLine() - - t.prompt = oldPrompt - t.echo = true - - return -} - -// ReadLine returns a line of input from the terminal. -func (t *Terminal) ReadLine() (line string, err error) { - t.lock.Lock() - defer t.lock.Unlock() - - return t.readLine() -} - -func (t *Terminal) readLine() (line string, err error) { - // t.lock must be held at this point - - if t.cursorX == 0 && t.cursorY == 0 { - t.writeLine(t.prompt) - t.c.Write(t.outBuf) - t.outBuf = t.outBuf[:0] - } - - lineIsPasted := t.pasteActive - - for { - rest := t.remainder - lineOk := false - for !lineOk { - var key rune - key, rest = bytesToKey(rest, t.pasteActive) - if key == utf8.RuneError { - break - } - if !t.pasteActive { - if key == keyCtrlD { - if len(t.line) == 0 { - return "", io.EOF - } - } - if key == keyPasteStart { - t.pasteActive = true - if len(t.line) == 0 { - lineIsPasted = true - } - continue - } - } else if key == keyPasteEnd { - t.pasteActive = false - continue - } - if !t.pasteActive { - lineIsPasted = false - } - line, lineOk = t.handleKey(key) - } - if len(rest) > 0 { - n := copy(t.inBuf[:], rest) - t.remainder = t.inBuf[:n] - } else { - t.remainder = nil - } - t.c.Write(t.outBuf) - t.outBuf = t.outBuf[:0] - if lineOk { - if t.echo { - t.historyIndex = -1 - t.history.Add(line) - } - if lineIsPasted { - err = ErrPasteIndicator - } - return - } - - // t.remainder is a slice at the beginning of t.inBuf - // containing a partial key sequence - readBuf := t.inBuf[len(t.remainder):] - var n int - - t.lock.Unlock() - n, err = t.c.Read(readBuf) - t.lock.Lock() - - if err != nil { - return - } - - t.remainder = t.inBuf[:n+len(t.remainder)] - } - - panic("unreachable") // for Go 1.0. -} - -// SetPrompt sets the prompt to be used when reading subsequent lines. -func (t *Terminal) SetPrompt(prompt string) { - t.lock.Lock() - defer t.lock.Unlock() - - t.prompt = []rune(prompt) -} - -func (t *Terminal) clearAndRepaintLinePlusNPrevious(numPrevLines int) { - // Move cursor to column zero at the start of the line. - t.move(t.cursorY, 0, t.cursorX, 0) - t.cursorX, t.cursorY = 0, 0 - t.clearLineToRight() - for t.cursorY < numPrevLines { - // Move down a line - t.move(0, 1, 0, 0) - t.cursorY++ - t.clearLineToRight() - } - // Move back to beginning. - t.move(t.cursorY, 0, 0, 0) - t.cursorX, t.cursorY = 0, 0 - - t.queue(t.prompt) - t.advanceCursor(visualLength(t.prompt)) - t.writeLine(t.line) - t.moveCursorToPos(t.pos) -} - -func (t *Terminal) SetSize(width, height int) error { - t.lock.Lock() - defer t.lock.Unlock() - - if width == 0 { - width = 1 - } - - oldWidth := t.termWidth - t.termWidth, t.termHeight = width, height - - switch { - case width == oldWidth: - // If the width didn't change then nothing else needs to be - // done. - return nil - case len(t.line) == 0 && t.cursorX == 0 && t.cursorY == 0: - // If there is nothing on current line and no prompt printed, - // just do nothing - return nil - case width < oldWidth: - // Some terminals (e.g. xterm) will truncate lines that were - // too long when shinking. Others, (e.g. gnome-terminal) will - // attempt to wrap them. For the former, repainting t.maxLine - // works great, but that behaviour goes badly wrong in the case - // of the latter because they have doubled every full line. - - // We assume that we are working on a terminal that wraps lines - // and adjust the cursor position based on every previous line - // wrapping and turning into two. This causes the prompt on - // xterms to move upwards, which isn't great, but it avoids a - // huge mess with gnome-terminal. - if t.cursorX >= t.termWidth { - t.cursorX = t.termWidth - 1 - } - t.cursorY *= 2 - t.clearAndRepaintLinePlusNPrevious(t.maxLine * 2) - case width > oldWidth: - // If the terminal expands then our position calculations will - // be wrong in the future because we think the cursor is - // |t.pos| chars into the string, but there will be a gap at - // the end of any wrapped line. - // - // But the position will actually be correct until we move, so - // we can move back to the beginning and repaint everything. - t.clearAndRepaintLinePlusNPrevious(t.maxLine) - } - - _, err := t.c.Write(t.outBuf) - t.outBuf = t.outBuf[:0] - return err -} - -type pasteIndicatorError struct{} - -func (pasteIndicatorError) Error() string { - return "terminal: ErrPasteIndicator not correctly handled" -} - -// 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 = pasteIndicatorError{} - -// SetBracketedPasteMode requests that the terminal bracket paste operations -// with markers. Not all terminals support this but, if it is supported, then -// enabling this mode will stop any autocomplete callback from running due to -// pastes. Additionally, any lines that are completely pasted will be returned -// from ReadLine with the error set to ErrPasteIndicator. -func (t *Terminal) SetBracketedPasteMode(on bool) { - if on { - io.WriteString(t.c, "\x1b[?2004h") - } else { - io.WriteString(t.c, "\x1b[?2004l") - } -} - -// stRingBuffer is a ring buffer of strings. -type stRingBuffer struct { - // entries contains max elements. - entries []string - max int - // head contains the index of the element most recently added to the ring. - head int - // size contains the number of elements in the ring. - size int -} - -func (s *stRingBuffer) Add(a string) { - if s.entries == nil { - const defaultNumEntries = 100 - s.entries = make([]string, defaultNumEntries) - s.max = defaultNumEntries - } - - s.head = (s.head + 1) % s.max - s.entries[s.head] = a - if s.size < s.max { - s.size++ - } -} - -// NthPreviousEntry returns the value passed to the nth previous call to Add. -// If n is zero then the immediately prior value is returned, if one, then the -// next most recent, and so on. If such an element doesn't exist then ok is -// false. -func (s *stRingBuffer) NthPreviousEntry(n int) (value string, ok bool) { - if n >= s.size { - return "", false - } - index := s.head - n - if index < 0 { - index += s.max - } - return s.entries[index], true -} diff --git a/vendor/golang.org/x/crypto/ssh/terminal/terminal_test.go b/vendor/golang.org/x/crypto/ssh/terminal/terminal_test.go deleted file mode 100644 index 6bdefb4..0000000 --- a/vendor/golang.org/x/crypto/ssh/terminal/terminal_test.go +++ /dev/null @@ -1,291 +0,0 @@ -// 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 - -import ( - "io" - "os" - "testing" -) - -type MockTerminal struct { - toSend []byte - bytesPerRead int - received []byte -} - -func (c *MockTerminal) Read(data []byte) (n int, err error) { - n = len(data) - if n == 0 { - return - } - if n > len(c.toSend) { - n = len(c.toSend) - } - if n == 0 { - return 0, io.EOF - } - if c.bytesPerRead > 0 && n > c.bytesPerRead { - n = c.bytesPerRead - } - copy(data, c.toSend[:n]) - c.toSend = c.toSend[n:] - return -} - -func (c *MockTerminal) Write(data []byte) (n int, err error) { - c.received = append(c.received, data...) - return len(data), nil -} - -func TestClose(t *testing.T) { - c := &MockTerminal{} - ss := NewTerminal(c, "> ") - line, err := ss.ReadLine() - if line != "" { - t.Errorf("Expected empty line but got: %s", line) - } - if err != io.EOF { - t.Errorf("Error should have been EOF but got: %s", err) - } -} - -var keyPressTests = []struct { - in string - line string - err error - throwAwayLines int -}{ - { - err: io.EOF, - }, - { - in: "\r", - line: "", - }, - { - in: "foo\r", - line: "foo", - }, - { - in: "a\x1b[Cb\r", // right - line: "ab", - }, - { - in: "a\x1b[Db\r", // left - line: "ba", - }, - { - in: "a\177b\r", // backspace - line: "b", - }, - { - in: "\x1b[A\r", // up - }, - { - in: "\x1b[B\r", // down - }, - { - in: "line\x1b[A\x1b[B\r", // up then down - line: "line", - }, - { - in: "line1\rline2\x1b[A\r", // recall previous line. - line: "line1", - throwAwayLines: 1, - }, - { - // recall two previous lines and append. - in: "line1\rline2\rline3\x1b[A\x1b[Axxx\r", - line: "line1xxx", - throwAwayLines: 2, - }, - { - // Ctrl-A to move to beginning of line followed by ^K to kill - // line. - in: "a b \001\013\r", - line: "", - }, - { - // Ctrl-A to move to beginning of line, Ctrl-E to move to end, - // finally ^K to kill nothing. - in: "a b \001\005\013\r", - line: "a b ", - }, - { - in: "\027\r", - line: "", - }, - { - in: "a\027\r", - line: "", - }, - { - in: "a \027\r", - line: "", - }, - { - in: "a b\027\r", - line: "a ", - }, - { - in: "a b \027\r", - line: "a ", - }, - { - in: "one two thr\x1b[D\027\r", - line: "one two r", - }, - { - in: "\013\r", - line: "", - }, - { - in: "a\013\r", - line: "a", - }, - { - in: "ab\x1b[D\013\r", - line: "a", - }, - { - in: "Ξεσκεπάζω\r", - line: "Ξεσκεπάζω", - }, - { - in: "£\r\x1b[A\177\r", // non-ASCII char, enter, up, backspace. - line: "", - throwAwayLines: 1, - }, - { - in: "£\r££\x1b[A\x1b[B\177\r", // non-ASCII char, enter, 2x non-ASCII, up, down, backspace, enter. - line: "£", - throwAwayLines: 1, - }, - { - // Ctrl-D at the end of the line should be ignored. - in: "a\004\r", - line: "a", - }, - { - // a, b, left, Ctrl-D should erase the b. - in: "ab\x1b[D\004\r", - line: "a", - }, - { - // a, b, c, d, left, left, ^U should erase to the beginning of - // the line. - in: "abcd\x1b[D\x1b[D\025\r", - line: "cd", - }, - { - // Bracketed paste mode: control sequences should be returned - // verbatim in paste mode. - in: "abc\x1b[200~de\177f\x1b[201~\177\r", - line: "abcde\177", - }, - { - // Enter in bracketed paste mode should still work. - in: "abc\x1b[200~d\refg\x1b[201~h\r", - line: "efgh", - throwAwayLines: 1, - }, - { - // Lines consisting entirely of pasted data should be indicated as such. - in: "\x1b[200~a\r", - line: "a", - err: ErrPasteIndicator, - }, -} - -func TestKeyPresses(t *testing.T) { - for i, test := range keyPressTests { - for j := 1; j < len(test.in); j++ { - c := &MockTerminal{ - toSend: []byte(test.in), - bytesPerRead: j, - } - ss := NewTerminal(c, "> ") - for k := 0; k < test.throwAwayLines; k++ { - _, err := ss.ReadLine() - if err != nil { - t.Errorf("Throwaway line %d from test %d resulted in error: %s", k, i, err) - } - } - line, err := ss.ReadLine() - if line != test.line { - t.Errorf("Line resulting from test %d (%d bytes per read) was '%s', expected '%s'", i, j, line, test.line) - break - } - if err != test.err { - t.Errorf("Error resulting from test %d (%d bytes per read) was '%v', expected '%v'", i, j, err, test.err) - break - } - } - } -} - -func TestPasswordNotSaved(t *testing.T) { - c := &MockTerminal{ - toSend: []byte("password\r\x1b[A\r"), - bytesPerRead: 1, - } - ss := NewTerminal(c, "> ") - pw, _ := ss.ReadPassword("> ") - if pw != "password" { - t.Fatalf("failed to read password, got %s", pw) - } - line, _ := ss.ReadLine() - if len(line) > 0 { - t.Fatalf("password was saved in history") - } -} - -var setSizeTests = []struct { - width, height int -}{ - {40, 13}, - {80, 24}, - {132, 43}, -} - -func TestTerminalSetSize(t *testing.T) { - for _, setSize := range setSizeTests { - c := &MockTerminal{ - toSend: []byte("password\r\x1b[A\r"), - bytesPerRead: 1, - } - ss := NewTerminal(c, "> ") - ss.SetSize(setSize.width, setSize.height) - pw, _ := ss.ReadPassword("Password: ") - if pw != "password" { - t.Fatalf("failed to read password, got %s", pw) - } - if string(c.received) != "Password: \r\n" { - t.Errorf("failed to set the temporary prompt expected %q, got %q", "Password: ", c.received) - } - } -} - -func TestMakeRawState(t *testing.T) { - fd := int(os.Stdout.Fd()) - if !IsTerminal(fd) { - t.Skip("stdout is not a terminal; skipping test") - } - - st, err := GetState(fd) - if err != nil { - t.Fatalf("failed to get terminal state from GetState: %s", err) - } - defer Restore(fd, st) - raw, err := MakeRaw(fd) - if err != nil { - t.Fatalf("failed to get terminal state from MakeRaw: %s", err) - } - - if *st != *raw { - t.Errorf("states do not match; was %v, expected %v", raw, st) - } -} diff --git a/vendor/golang.org/x/crypto/ssh/terminal/util.go b/vendor/golang.org/x/crypto/ssh/terminal/util.go deleted file mode 100644 index 598e3df..0000000 --- a/vendor/golang.org/x/crypto/ssh/terminal/util.go +++ /dev/null @@ -1,128 +0,0 @@ -// 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. - -// +build darwin dragonfly freebsd linux,!appengine netbsd openbsd - -// Package terminal provides support functions for dealing with terminals, as -// commonly found on UNIX systems. -// -// Putting a terminal into raw mode is the most common requirement: -// -// oldState, err := terminal.MakeRaw(0) -// if err != nil { -// panic(err) -// } -// defer terminal.Restore(0, oldState) -package terminal // import "golang.org/x/crypto/ssh/terminal" - -import ( - "io" - "syscall" - "unsafe" -) - -// State contains the state of a terminal. -type State struct { - termios syscall.Termios -} - -// IsTerminal returns true if the given file descriptor is a terminal. -func IsTerminal(fd int) bool { - var termios syscall.Termios - _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0) - return err == 0 -} - -// MakeRaw put 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) { - var oldState State - if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlReadTermios, uintptr(unsafe.Pointer(&oldState.termios)), 0, 0, 0); err != 0 { - return nil, err - } - - newState := oldState.termios - newState.Iflag &^= syscall.ISTRIP | syscall.INLCR | syscall.ICRNL | syscall.IGNCR | syscall.IXON | syscall.IXOFF - newState.Lflag &^= syscall.ECHO | syscall.ICANON | syscall.ISIG - if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlWriteTermios, uintptr(unsafe.Pointer(&newState)), 0, 0, 0); err != 0 { - return nil, err - } - - return &oldState, nil -} - -// 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) { - var oldState State - if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlReadTermios, uintptr(unsafe.Pointer(&oldState.termios)), 0, 0, 0); err != 0 { - return nil, err - } - - return &oldState, nil -} - -// Restore restores the terminal connected to the given file descriptor to a -// previous state. -func Restore(fd int, state *State) error { - _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlWriteTermios, uintptr(unsafe.Pointer(&state.termios)), 0, 0, 0) - return err -} - -// GetSize returns the dimensions of the given terminal. -func GetSize(fd int) (width, height int, err error) { - var dimensions [4]uint16 - - if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(syscall.TIOCGWINSZ), uintptr(unsafe.Pointer(&dimensions)), 0, 0, 0); err != 0 { - return -1, -1, err - } - return int(dimensions[1]), int(dimensions[0]), nil -} - -// 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) { - var oldState syscall.Termios - if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlReadTermios, uintptr(unsafe.Pointer(&oldState)), 0, 0, 0); err != 0 { - return nil, err - } - - newState := oldState - newState.Lflag &^= syscall.ECHO - newState.Lflag |= syscall.ICANON | syscall.ISIG - newState.Iflag |= syscall.ICRNL - if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlWriteTermios, uintptr(unsafe.Pointer(&newState)), 0, 0, 0); err != 0 { - return nil, err - } - - defer func() { - syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlWriteTermios, uintptr(unsafe.Pointer(&oldState)), 0, 0, 0) - }() - - var buf [16]byte - var ret []byte - for { - n, err := syscall.Read(fd, buf[:]) - if err != nil { - return nil, err - } - if n == 0 { - if len(ret) == 0 { - return nil, io.EOF - } - break - } - if buf[n-1] == '\n' { - n-- - } - ret = append(ret, buf[:n]...) - if n < len(buf) { - break - } - } - - return ret, nil -} diff --git a/vendor/golang.org/x/crypto/ssh/terminal/util_bsd.go b/vendor/golang.org/x/crypto/ssh/terminal/util_bsd.go deleted file mode 100644 index 9c1ffd1..0000000 --- a/vendor/golang.org/x/crypto/ssh/terminal/util_bsd.go +++ /dev/null @@ -1,12 +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. - -// +build darwin dragonfly freebsd netbsd openbsd - -package terminal - -import "syscall" - -const ioctlReadTermios = syscall.TIOCGETA -const ioctlWriteTermios = syscall.TIOCSETA diff --git a/vendor/golang.org/x/crypto/ssh/terminal/util_linux.go b/vendor/golang.org/x/crypto/ssh/terminal/util_linux.go deleted file mode 100644 index 5883b22..0000000 --- a/vendor/golang.org/x/crypto/ssh/terminal/util_linux.go +++ /dev/null @@ -1,11 +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 terminal - -// These constants are declared here, rather than importing -// them from the syscall package as some syscall packages, even -// on linux, for example gccgo, do not declare them. -const ioctlReadTermios = 0x5401 // syscall.TCGETS -const ioctlWriteTermios = 0x5402 // syscall.TCSETS diff --git a/vendor/golang.org/x/crypto/ssh/terminal/util_plan9.go b/vendor/golang.org/x/crypto/ssh/terminal/util_plan9.go deleted file mode 100644 index 799f049..0000000 --- a/vendor/golang.org/x/crypto/ssh/terminal/util_plan9.go +++ /dev/null @@ -1,58 +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 terminal provides support functions for dealing with terminals, as -// commonly found on UNIX systems. -// -// Putting a terminal into raw mode is the most common requirement: -// -// oldState, err := terminal.MakeRaw(0) -// if err != nil { -// panic(err) -// } -// defer terminal.Restore(0, oldState) -package terminal - -import ( - "fmt" - "runtime" -) - -type State struct{} - -// IsTerminal returns true if the given file descriptor is a terminal. -func IsTerminal(fd int) bool { - return false -} - -// MakeRaw put 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 nil, fmt.Errorf("terminal: MakeRaw not implemented on %s/%s", runtime.GOOS, runtime.GOARCH) -} - -// 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 nil, fmt.Errorf("terminal: GetState not implemented on %s/%s", runtime.GOOS, runtime.GOARCH) -} - -// Restore restores the terminal connected to the given file descriptor to a -// previous state. -func Restore(fd int, state *State) error { - return fmt.Errorf("terminal: Restore not implemented on %s/%s", runtime.GOOS, runtime.GOARCH) -} - -// GetSize returns the dimensions of the given terminal. -func GetSize(fd int) (width, height int, err error) { - return 0, 0, fmt.Errorf("terminal: GetSize not implemented on %s/%s", runtime.GOOS, runtime.GOARCH) -} - -// 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 nil, fmt.Errorf("terminal: ReadPassword not implemented on %s/%s", runtime.GOOS, runtime.GOARCH) -} diff --git a/vendor/golang.org/x/crypto/ssh/terminal/util_windows.go b/vendor/golang.org/x/crypto/ssh/terminal/util_windows.go deleted file mode 100644 index ae9fa9e..0000000 --- a/vendor/golang.org/x/crypto/ssh/terminal/util_windows.go +++ /dev/null @@ -1,174 +0,0 @@ -// 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. - -// +build windows - -// Package terminal provides support functions for dealing with terminals, as -// commonly found on UNIX systems. -// -// Putting a terminal into raw mode is the most common requirement: -// -// oldState, err := terminal.MakeRaw(0) -// if err != nil { -// panic(err) -// } -// defer terminal.Restore(0, oldState) -package terminal - -import ( - "io" - "syscall" - "unsafe" -) - -const ( - enableLineInput = 2 - enableEchoInput = 4 - enableProcessedInput = 1 - enableWindowInput = 8 - enableMouseInput = 16 - enableInsertMode = 32 - enableQuickEditMode = 64 - enableExtendedFlags = 128 - enableAutoPosition = 256 - enableProcessedOutput = 1 - enableWrapAtEolOutput = 2 -) - -var kernel32 = syscall.NewLazyDLL("kernel32.dll") - -var ( - procGetConsoleMode = kernel32.NewProc("GetConsoleMode") - procSetConsoleMode = kernel32.NewProc("SetConsoleMode") - procGetConsoleScreenBufferInfo = kernel32.NewProc("GetConsoleScreenBufferInfo") -) - -type ( - short int16 - word uint16 - - coord struct { - x short - y short - } - smallRect struct { - left short - top short - right short - bottom short - } - consoleScreenBufferInfo struct { - size coord - cursorPosition coord - attributes word - window smallRect - maximumWindowSize coord - } -) - -type State struct { - mode uint32 -} - -// IsTerminal returns true if the given file descriptor is a terminal. -func IsTerminal(fd int) bool { - var st uint32 - r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(fd), uintptr(unsafe.Pointer(&st)), 0) - return r != 0 && e == 0 -} - -// MakeRaw put 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) { - var st uint32 - _, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(fd), uintptr(unsafe.Pointer(&st)), 0) - if e != 0 { - return nil, error(e) - } - raw := st &^ (enableEchoInput | enableProcessedInput | enableLineInput | enableProcessedOutput) - _, _, e = syscall.Syscall(procSetConsoleMode.Addr(), 2, uintptr(fd), uintptr(raw), 0) - if e != 0 { - return nil, error(e) - } - return &State{st}, nil -} - -// 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) { - var st uint32 - _, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(fd), uintptr(unsafe.Pointer(&st)), 0) - if e != 0 { - return nil, error(e) - } - return &State{st}, nil -} - -// Restore restores the terminal connected to the given file descriptor to a -// previous state. -func Restore(fd int, state *State) error { - _, _, err := syscall.Syscall(procSetConsoleMode.Addr(), 2, uintptr(fd), uintptr(state.mode), 0) - return err -} - -// GetSize returns the dimensions of the given terminal. -func GetSize(fd int) (width, height int, err error) { - var info consoleScreenBufferInfo - _, _, e := syscall.Syscall(procGetConsoleScreenBufferInfo.Addr(), 2, uintptr(fd), uintptr(unsafe.Pointer(&info)), 0) - if e != 0 { - return 0, 0, error(e) - } - return int(info.size.x), int(info.size.y), nil -} - -// 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) { - var st uint32 - _, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(fd), uintptr(unsafe.Pointer(&st)), 0) - if e != 0 { - return nil, error(e) - } - old := st - - st &^= (enableEchoInput) - st |= (enableProcessedInput | enableLineInput | enableProcessedOutput) - _, _, e = syscall.Syscall(procSetConsoleMode.Addr(), 2, uintptr(fd), uintptr(st), 0) - if e != 0 { - return nil, error(e) - } - - defer func() { - syscall.Syscall(procSetConsoleMode.Addr(), 2, uintptr(fd), uintptr(old), 0) - }() - - var buf [16]byte - var ret []byte - for { - n, err := syscall.Read(syscall.Handle(fd), buf[:]) - if err != nil { - return nil, err - } - if n == 0 { - if len(ret) == 0 { - return nil, io.EOF - } - break - } - if buf[n-1] == '\n' { - n-- - } - if n > 0 && buf[n-1] == '\r' { - n-- - } - ret = append(ret, buf[:n]...) - if n < len(buf) { - break - } - } - - return ret, nil -} diff --git a/vendor/golang.org/x/crypto/ssh/test/agent_unix_test.go b/vendor/golang.org/x/crypto/ssh/test/agent_unix_test.go deleted file mode 100644 index f481253..0000000 --- a/vendor/golang.org/x/crypto/ssh/test/agent_unix_test.go +++ /dev/null @@ -1,59 +0,0 @@ -// 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. - -// +build darwin dragonfly freebsd linux netbsd openbsd - -package test - -import ( - "bytes" - "testing" - - "golang.org/x/crypto/ssh" - "golang.org/x/crypto/ssh/agent" -) - -func TestAgentForward(t *testing.T) { - server := newServer(t) - defer server.Shutdown() - conn := server.Dial(clientConfig()) - defer conn.Close() - - keyring := agent.NewKeyring() - if err := keyring.Add(agent.AddedKey{PrivateKey: testPrivateKeys["dsa"]}); err != nil { - t.Fatalf("Error adding key: %s", err) - } - if err := keyring.Add(agent.AddedKey{ - PrivateKey: testPrivateKeys["dsa"], - ConfirmBeforeUse: true, - LifetimeSecs: 3600, - }); err != nil { - t.Fatalf("Error adding key with constraints: %s", err) - } - pub := testPublicKeys["dsa"] - - sess, err := conn.NewSession() - if err != nil { - t.Fatalf("NewSession: %v", err) - } - if err := agent.RequestAgentForwarding(sess); err != nil { - t.Fatalf("RequestAgentForwarding: %v", err) - } - - if err := agent.ForwardToAgent(conn, keyring); err != nil { - t.Fatalf("SetupForwardKeyring: %v", err) - } - out, err := sess.CombinedOutput("ssh-add -L") - if err != nil { - t.Fatalf("running ssh-add: %v, out %s", err, out) - } - key, _, _, _, err := ssh.ParseAuthorizedKey(out) - if err != nil { - t.Fatalf("ParseAuthorizedKey(%q): %v", out, err) - } - - if !bytes.Equal(key.Marshal(), pub.Marshal()) { - t.Fatalf("got key %s, want %s", ssh.MarshalAuthorizedKey(key), ssh.MarshalAuthorizedKey(pub)) - } -} diff --git a/vendor/golang.org/x/crypto/ssh/test/cert_test.go b/vendor/golang.org/x/crypto/ssh/test/cert_test.go deleted file mode 100644 index 364790f..0000000 --- a/vendor/golang.org/x/crypto/ssh/test/cert_test.go +++ /dev/null @@ -1,47 +0,0 @@ -// 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. - -// +build darwin dragonfly freebsd linux netbsd openbsd - -package test - -import ( - "crypto/rand" - "testing" - - "golang.org/x/crypto/ssh" -) - -func TestCertLogin(t *testing.T) { - s := newServer(t) - defer s.Shutdown() - - // Use a key different from the default. - clientKey := testSigners["dsa"] - caAuthKey := testSigners["ecdsa"] - cert := &ssh.Certificate{ - Key: clientKey.PublicKey(), - ValidPrincipals: []string{username()}, - CertType: ssh.UserCert, - ValidBefore: ssh.CertTimeInfinity, - } - if err := cert.SignCert(rand.Reader, caAuthKey); err != nil { - t.Fatalf("SetSignature: %v", err) - } - - certSigner, err := ssh.NewCertSigner(cert, clientKey) - if err != nil { - t.Fatalf("NewCertSigner: %v", err) - } - - conf := &ssh.ClientConfig{ - User: username(), - } - conf.Auth = append(conf.Auth, ssh.PublicKeys(certSigner)) - client, err := s.TryDial(conf) - if err != nil { - t.Fatalf("TryDial: %v", err) - } - client.Close() -} diff --git a/vendor/golang.org/x/crypto/ssh/test/doc.go b/vendor/golang.org/x/crypto/ssh/test/doc.go deleted file mode 100644 index 3f9b334..0000000 --- a/vendor/golang.org/x/crypto/ssh/test/doc.go +++ /dev/null @@ -1,7 +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 package contains integration tests for the -// golang.org/x/crypto/ssh package. -package test // import "golang.org/x/crypto/ssh/test" diff --git a/vendor/golang.org/x/crypto/ssh/test/forward_unix_test.go b/vendor/golang.org/x/crypto/ssh/test/forward_unix_test.go deleted file mode 100644 index 877a88c..0000000 --- a/vendor/golang.org/x/crypto/ssh/test/forward_unix_test.go +++ /dev/null @@ -1,160 +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 darwin dragonfly freebsd linux netbsd openbsd - -package test - -import ( - "bytes" - "io" - "io/ioutil" - "math/rand" - "net" - "testing" - "time" -) - -func TestPortForward(t *testing.T) { - server := newServer(t) - defer server.Shutdown() - conn := server.Dial(clientConfig()) - defer conn.Close() - - sshListener, err := conn.Listen("tcp", "localhost:0") - if err != nil { - t.Fatal(err) - } - - go func() { - sshConn, err := sshListener.Accept() - if err != nil { - t.Fatalf("listen.Accept failed: %v", err) - } - - _, err = io.Copy(sshConn, sshConn) - if err != nil && err != io.EOF { - t.Fatalf("ssh client copy: %v", err) - } - sshConn.Close() - }() - - forwardedAddr := sshListener.Addr().String() - tcpConn, err := net.Dial("tcp", forwardedAddr) - if err != nil { - t.Fatalf("TCP dial failed: %v", err) - } - - readChan := make(chan []byte) - go func() { - data, _ := ioutil.ReadAll(tcpConn) - readChan <- data - }() - - // Invent some data. - data := make([]byte, 100*1000) - for i := range data { - data[i] = byte(i % 255) - } - - var sent []byte - for len(sent) < 1000*1000 { - // Send random sized chunks - m := rand.Intn(len(data)) - n, err := tcpConn.Write(data[:m]) - if err != nil { - break - } - sent = append(sent, data[:n]...) - } - if err := tcpConn.(*net.TCPConn).CloseWrite(); err != nil { - t.Errorf("tcpConn.CloseWrite: %v", err) - } - - read := <-readChan - - if len(sent) != len(read) { - t.Fatalf("got %d bytes, want %d", len(read), len(sent)) - } - if bytes.Compare(sent, read) != 0 { - t.Fatalf("read back data does not match") - } - - if err := sshListener.Close(); err != nil { - t.Fatalf("sshListener.Close: %v", err) - } - - // Check that the forward disappeared. - tcpConn, err = net.Dial("tcp", forwardedAddr) - if err == nil { - tcpConn.Close() - t.Errorf("still listening to %s after closing", forwardedAddr) - } -} - -func TestAcceptClose(t *testing.T) { - server := newServer(t) - defer server.Shutdown() - conn := server.Dial(clientConfig()) - - sshListener, err := conn.Listen("tcp", "localhost:0") - if err != nil { - t.Fatal(err) - } - - quit := make(chan error, 1) - go func() { - for { - c, err := sshListener.Accept() - if err != nil { - quit <- err - break - } - c.Close() - } - }() - sshListener.Close() - - select { - case <-time.After(1 * time.Second): - t.Errorf("timeout: listener did not close.") - case err := <-quit: - t.Logf("quit as expected (error %v)", err) - } -} - -// Check that listeners exit if the underlying client transport dies. -func TestPortForwardConnectionClose(t *testing.T) { - server := newServer(t) - defer server.Shutdown() - conn := server.Dial(clientConfig()) - - sshListener, err := conn.Listen("tcp", "localhost:0") - if err != nil { - t.Fatal(err) - } - - quit := make(chan error, 1) - go func() { - for { - c, err := sshListener.Accept() - if err != nil { - quit <- err - break - } - c.Close() - } - }() - - // It would be even nicer if we closed the server side, but it - // is more involved as the fd for that side is dup()ed. - server.clientConn.Close() - - select { - case <-time.After(1 * time.Second): - t.Errorf("timeout: listener did not close.") - case err := <-quit: - t.Logf("quit as expected (error %v)", err) - } -} diff --git a/vendor/golang.org/x/crypto/ssh/test/session_test.go b/vendor/golang.org/x/crypto/ssh/test/session_test.go deleted file mode 100644 index faf2d2b..0000000 --- a/vendor/golang.org/x/crypto/ssh/test/session_test.go +++ /dev/null @@ -1,365 +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 !windows - -package test - -// Session functional tests. - -import ( - "bytes" - "errors" - "io" - "strings" - "testing" - - "golang.org/x/crypto/ssh" -) - -func TestRunCommandSuccess(t *testing.T) { - server := newServer(t) - defer server.Shutdown() - conn := server.Dial(clientConfig()) - defer conn.Close() - - session, err := conn.NewSession() - if err != nil { - t.Fatalf("session failed: %v", err) - } - defer session.Close() - err = session.Run("true") - if err != nil { - t.Fatalf("session failed: %v", err) - } -} - -func TestHostKeyCheck(t *testing.T) { - server := newServer(t) - defer server.Shutdown() - - conf := clientConfig() - hostDB := hostKeyDB() - conf.HostKeyCallback = hostDB.Check - - // change the keys. - hostDB.keys[ssh.KeyAlgoRSA][25]++ - hostDB.keys[ssh.KeyAlgoDSA][25]++ - hostDB.keys[ssh.KeyAlgoECDSA256][25]++ - - conn, err := server.TryDial(conf) - if err == nil { - conn.Close() - t.Fatalf("dial should have failed.") - } else if !strings.Contains(err.Error(), "host key mismatch") { - t.Fatalf("'host key mismatch' not found in %v", err) - } -} - -func TestRunCommandStdin(t *testing.T) { - server := newServer(t) - defer server.Shutdown() - conn := server.Dial(clientConfig()) - defer conn.Close() - - session, err := conn.NewSession() - if err != nil { - t.Fatalf("session failed: %v", err) - } - defer session.Close() - - r, w := io.Pipe() - defer r.Close() - defer w.Close() - session.Stdin = r - - err = session.Run("true") - if err != nil { - t.Fatalf("session failed: %v", err) - } -} - -func TestRunCommandStdinError(t *testing.T) { - server := newServer(t) - defer server.Shutdown() - conn := server.Dial(clientConfig()) - defer conn.Close() - - session, err := conn.NewSession() - if err != nil { - t.Fatalf("session failed: %v", err) - } - defer session.Close() - - r, w := io.Pipe() - defer r.Close() - session.Stdin = r - pipeErr := errors.New("closing write end of pipe") - w.CloseWithError(pipeErr) - - err = session.Run("true") - if err != pipeErr { - t.Fatalf("expected %v, found %v", pipeErr, err) - } -} - -func TestRunCommandFailed(t *testing.T) { - server := newServer(t) - defer server.Shutdown() - conn := server.Dial(clientConfig()) - defer conn.Close() - - session, err := conn.NewSession() - if err != nil { - t.Fatalf("session failed: %v", err) - } - defer session.Close() - err = session.Run(`bash -c "kill -9 $$"`) - if err == nil { - t.Fatalf("session succeeded: %v", err) - } -} - -func TestRunCommandWeClosed(t *testing.T) { - server := newServer(t) - defer server.Shutdown() - conn := server.Dial(clientConfig()) - defer conn.Close() - - session, err := conn.NewSession() - if err != nil { - t.Fatalf("session failed: %v", err) - } - err = session.Shell() - if err != nil { - t.Fatalf("shell failed: %v", err) - } - err = session.Close() - if err != nil { - t.Fatalf("shell failed: %v", err) - } -} - -func TestFuncLargeRead(t *testing.T) { - server := newServer(t) - defer server.Shutdown() - conn := server.Dial(clientConfig()) - defer conn.Close() - - session, err := conn.NewSession() - if err != nil { - t.Fatalf("unable to create new session: %s", err) - } - - stdout, err := session.StdoutPipe() - if err != nil { - t.Fatalf("unable to acquire stdout pipe: %s", err) - } - - err = session.Start("dd if=/dev/urandom bs=2048 count=1024") - if err != nil { - t.Fatalf("unable to execute remote command: %s", err) - } - - buf := new(bytes.Buffer) - n, err := io.Copy(buf, stdout) - if err != nil { - t.Fatalf("error reading from remote stdout: %s", err) - } - - if n != 2048*1024 { - t.Fatalf("Expected %d bytes but read only %d from remote command", 2048, n) - } -} - -func TestKeyChange(t *testing.T) { - server := newServer(t) - defer server.Shutdown() - conf := clientConfig() - hostDB := hostKeyDB() - conf.HostKeyCallback = hostDB.Check - conf.RekeyThreshold = 1024 - conn := server.Dial(conf) - defer conn.Close() - - for i := 0; i < 4; i++ { - session, err := conn.NewSession() - if err != nil { - t.Fatalf("unable to create new session: %s", err) - } - - stdout, err := session.StdoutPipe() - if err != nil { - t.Fatalf("unable to acquire stdout pipe: %s", err) - } - - err = session.Start("dd if=/dev/urandom bs=1024 count=1") - if err != nil { - t.Fatalf("unable to execute remote command: %s", err) - } - buf := new(bytes.Buffer) - n, err := io.Copy(buf, stdout) - if err != nil { - t.Fatalf("error reading from remote stdout: %s", err) - } - - want := int64(1024) - if n != want { - t.Fatalf("Expected %d bytes but read only %d from remote command", want, n) - } - } - - if changes := hostDB.checkCount; changes < 4 { - t.Errorf("got %d key changes, want 4", changes) - } -} - -func TestInvalidTerminalMode(t *testing.T) { - server := newServer(t) - defer server.Shutdown() - conn := server.Dial(clientConfig()) - defer conn.Close() - - session, err := conn.NewSession() - if err != nil { - t.Fatalf("session failed: %v", err) - } - defer session.Close() - - if err = session.RequestPty("vt100", 80, 40, ssh.TerminalModes{255: 1984}); err == nil { - t.Fatalf("req-pty failed: successful request with invalid mode") - } -} - -func TestValidTerminalMode(t *testing.T) { - server := newServer(t) - defer server.Shutdown() - conn := server.Dial(clientConfig()) - defer conn.Close() - - session, err := conn.NewSession() - if err != nil { - t.Fatalf("session failed: %v", err) - } - defer session.Close() - - stdout, err := session.StdoutPipe() - if err != nil { - t.Fatalf("unable to acquire stdout pipe: %s", err) - } - - stdin, err := session.StdinPipe() - if err != nil { - t.Fatalf("unable to acquire stdin pipe: %s", err) - } - - tm := ssh.TerminalModes{ssh.ECHO: 0} - if err = session.RequestPty("xterm", 80, 40, tm); err != nil { - t.Fatalf("req-pty failed: %s", err) - } - - err = session.Shell() - if err != nil { - t.Fatalf("session failed: %s", err) - } - - stdin.Write([]byte("stty -a && exit\n")) - - var buf bytes.Buffer - if _, err := io.Copy(&buf, stdout); err != nil { - t.Fatalf("reading failed: %s", err) - } - - if sttyOutput := buf.String(); !strings.Contains(sttyOutput, "-echo ") { - t.Fatalf("terminal mode failure: expected -echo in stty output, got %s", sttyOutput) - } -} - -func TestCiphers(t *testing.T) { - var config ssh.Config - config.SetDefaults() - cipherOrder := config.Ciphers - // These ciphers will not be tested when commented out in cipher.go it will - // fallback to the next available as per line 292. - cipherOrder = append(cipherOrder, "aes128-cbc", "3des-cbc") - - for _, ciph := range cipherOrder { - server := newServer(t) - defer server.Shutdown() - conf := clientConfig() - conf.Ciphers = []string{ciph} - // Don't fail if sshd doesnt have the cipher. - conf.Ciphers = append(conf.Ciphers, cipherOrder...) - conn, err := server.TryDial(conf) - if err == nil { - conn.Close() - } else { - t.Fatalf("failed for cipher %q", ciph) - } - } -} - -func TestMACs(t *testing.T) { - var config ssh.Config - config.SetDefaults() - macOrder := config.MACs - - for _, mac := range macOrder { - server := newServer(t) - defer server.Shutdown() - conf := clientConfig() - conf.MACs = []string{mac} - // Don't fail if sshd doesnt have the MAC. - conf.MACs = append(conf.MACs, macOrder...) - if conn, err := server.TryDial(conf); err == nil { - conn.Close() - } else { - t.Fatalf("failed for MAC %q", mac) - } - } -} - -func TestKeyExchanges(t *testing.T) { - var config ssh.Config - config.SetDefaults() - kexOrder := config.KeyExchanges - for _, kex := range kexOrder { - server := newServer(t) - defer server.Shutdown() - conf := clientConfig() - // Don't fail if sshd doesnt have the kex. - conf.KeyExchanges = append([]string{kex}, kexOrder...) - conn, err := server.TryDial(conf) - if err == nil { - conn.Close() - } else { - t.Errorf("failed for kex %q", kex) - } - } -} - -func TestClientAuthAlgorithms(t *testing.T) { - for _, key := range []string{ - "rsa", - "dsa", - "ecdsa", - "ed25519", - } { - server := newServer(t) - conf := clientConfig() - conf.SetDefaults() - conf.Auth = []ssh.AuthMethod{ - ssh.PublicKeys(testSigners[key]), - } - - conn, err := server.TryDial(conf) - if err == nil { - conn.Close() - } else { - t.Errorf("failed for key %q", key) - } - - server.Shutdown() - } -} diff --git a/vendor/golang.org/x/crypto/ssh/test/tcpip_test.go b/vendor/golang.org/x/crypto/ssh/test/tcpip_test.go deleted file mode 100644 index a2eb935..0000000 --- a/vendor/golang.org/x/crypto/ssh/test/tcpip_test.go +++ /dev/null @@ -1,46 +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 !windows - -package test - -// direct-tcpip functional tests - -import ( - "io" - "net" - "testing" -) - -func TestDial(t *testing.T) { - server := newServer(t) - defer server.Shutdown() - sshConn := server.Dial(clientConfig()) - defer sshConn.Close() - - l, err := net.Listen("tcp", "127.0.0.1:0") - if err != nil { - t.Fatalf("Listen: %v", err) - } - defer l.Close() - - go func() { - for { - c, err := l.Accept() - if err != nil { - break - } - - io.WriteString(c, c.RemoteAddr().String()) - c.Close() - } - }() - - conn, err := sshConn.Dial("tcp", l.Addr().String()) - if err != nil { - t.Fatalf("Dial: %v", err) - } - defer conn.Close() -} diff --git a/vendor/golang.org/x/crypto/ssh/test/test_unix_test.go b/vendor/golang.org/x/crypto/ssh/test/test_unix_test.go deleted file mode 100644 index 3bfd881..0000000 --- a/vendor/golang.org/x/crypto/ssh/test/test_unix_test.go +++ /dev/null @@ -1,268 +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 darwin dragonfly freebsd linux netbsd openbsd plan9 - -package test - -// functional test harness for unix. - -import ( - "bytes" - "fmt" - "io/ioutil" - "log" - "net" - "os" - "os/exec" - "os/user" - "path/filepath" - "testing" - "text/template" - - "golang.org/x/crypto/ssh" - "golang.org/x/crypto/ssh/testdata" -) - -const sshd_config = ` -Protocol 2 -HostKey {{.Dir}}/id_rsa -HostKey {{.Dir}}/id_dsa -HostKey {{.Dir}}/id_ecdsa -Pidfile {{.Dir}}/sshd.pid -#UsePrivilegeSeparation no -KeyRegenerationInterval 3600 -ServerKeyBits 768 -SyslogFacility AUTH -LogLevel DEBUG2 -LoginGraceTime 120 -PermitRootLogin no -StrictModes no -RSAAuthentication yes -PubkeyAuthentication yes -AuthorizedKeysFile {{.Dir}}/authorized_keys -TrustedUserCAKeys {{.Dir}}/id_ecdsa.pub -IgnoreRhosts yes -RhostsRSAAuthentication no -HostbasedAuthentication no -PubkeyAcceptedKeyTypes=* -` - -var configTmpl = template.Must(template.New("").Parse(sshd_config)) - -type server struct { - t *testing.T - cleanup func() // executed during Shutdown - configfile string - cmd *exec.Cmd - output bytes.Buffer // holds stderr from sshd process - - // Client half of the network connection. - clientConn net.Conn -} - -func username() string { - var username string - if user, err := user.Current(); err == nil { - username = user.Username - } else { - // user.Current() currently requires cgo. If an error is - // returned attempt to get the username from the environment. - log.Printf("user.Current: %v; falling back on $USER", err) - username = os.Getenv("USER") - } - if username == "" { - panic("Unable to get username") - } - return username -} - -type storedHostKey struct { - // keys map from an algorithm string to binary key data. - keys map[string][]byte - - // checkCount counts the Check calls. Used for testing - // rekeying. - checkCount int -} - -func (k *storedHostKey) Add(key ssh.PublicKey) { - if k.keys == nil { - k.keys = map[string][]byte{} - } - k.keys[key.Type()] = key.Marshal() -} - -func (k *storedHostKey) Check(addr string, remote net.Addr, key ssh.PublicKey) error { - k.checkCount++ - algo := key.Type() - - if k.keys == nil || bytes.Compare(key.Marshal(), k.keys[algo]) != 0 { - return fmt.Errorf("host key mismatch. Got %q, want %q", key, k.keys[algo]) - } - return nil -} - -func hostKeyDB() *storedHostKey { - keyChecker := &storedHostKey{} - keyChecker.Add(testPublicKeys["ecdsa"]) - keyChecker.Add(testPublicKeys["rsa"]) - keyChecker.Add(testPublicKeys["dsa"]) - return keyChecker -} - -func clientConfig() *ssh.ClientConfig { - config := &ssh.ClientConfig{ - User: username(), - Auth: []ssh.AuthMethod{ - ssh.PublicKeys(testSigners["user"]), - }, - HostKeyCallback: hostKeyDB().Check, - } - return config -} - -// unixConnection creates two halves of a connected net.UnixConn. It -// is used for connecting the Go SSH client with sshd without opening -// ports. -func unixConnection() (*net.UnixConn, *net.UnixConn, error) { - dir, err := ioutil.TempDir("", "unixConnection") - if err != nil { - return nil, nil, err - } - defer os.Remove(dir) - - addr := filepath.Join(dir, "ssh") - listener, err := net.Listen("unix", addr) - if err != nil { - return nil, nil, err - } - defer listener.Close() - c1, err := net.Dial("unix", addr) - if err != nil { - return nil, nil, err - } - - c2, err := listener.Accept() - if err != nil { - c1.Close() - return nil, nil, err - } - - return c1.(*net.UnixConn), c2.(*net.UnixConn), nil -} - -func (s *server) TryDial(config *ssh.ClientConfig) (*ssh.Client, error) { - sshd, err := exec.LookPath("sshd") - if err != nil { - s.t.Skipf("skipping test: %v", err) - } - - c1, c2, err := unixConnection() - if err != nil { - s.t.Fatalf("unixConnection: %v", err) - } - - s.cmd = exec.Command(sshd, "-f", s.configfile, "-i", "-e") - f, err := c2.File() - if err != nil { - s.t.Fatalf("UnixConn.File: %v", err) - } - defer f.Close() - s.cmd.Stdin = f - s.cmd.Stdout = f - s.cmd.Stderr = &s.output - if err := s.cmd.Start(); err != nil { - s.t.Fail() - s.Shutdown() - s.t.Fatalf("s.cmd.Start: %v", err) - } - s.clientConn = c1 - conn, chans, reqs, err := ssh.NewClientConn(c1, "", config) - if err != nil { - return nil, err - } - return ssh.NewClient(conn, chans, reqs), nil -} - -func (s *server) Dial(config *ssh.ClientConfig) *ssh.Client { - conn, err := s.TryDial(config) - if err != nil { - s.t.Fail() - s.Shutdown() - s.t.Fatalf("ssh.Client: %v", err) - } - return conn -} - -func (s *server) Shutdown() { - if s.cmd != nil && s.cmd.Process != nil { - // Don't check for errors; if it fails it's most - // likely "os: process already finished", and we don't - // care about that. Use os.Interrupt, so child - // processes are killed too. - s.cmd.Process.Signal(os.Interrupt) - s.cmd.Wait() - } - if s.t.Failed() { - // log any output from sshd process - s.t.Logf("sshd: %s", s.output.String()) - } - s.cleanup() -} - -func writeFile(path string, contents []byte) { - f, err := os.OpenFile(path, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0600) - if err != nil { - panic(err) - } - defer f.Close() - if _, err := f.Write(contents); err != nil { - panic(err) - } -} - -// newServer returns a new mock ssh server. -func newServer(t *testing.T) *server { - if testing.Short() { - t.Skip("skipping test due to -short") - } - dir, err := ioutil.TempDir("", "sshtest") - if err != nil { - t.Fatal(err) - } - f, err := os.Create(filepath.Join(dir, "sshd_config")) - if err != nil { - t.Fatal(err) - } - err = configTmpl.Execute(f, map[string]string{ - "Dir": dir, - }) - if err != nil { - t.Fatal(err) - } - f.Close() - - for k, v := range testdata.PEMBytes { - filename := "id_" + k - writeFile(filepath.Join(dir, filename), v) - writeFile(filepath.Join(dir, filename+".pub"), ssh.MarshalAuthorizedKey(testPublicKeys[k])) - } - - var authkeys bytes.Buffer - for k, _ := range testdata.PEMBytes { - authkeys.Write(ssh.MarshalAuthorizedKey(testPublicKeys[k])) - } - writeFile(filepath.Join(dir, "authorized_keys"), authkeys.Bytes()) - - return &server{ - t: t, - configfile: f.Name(), - cleanup: func() { - if err := os.RemoveAll(dir); err != nil { - t.Error(err) - } - }, - } -} diff --git a/vendor/golang.org/x/crypto/ssh/test/testdata_test.go b/vendor/golang.org/x/crypto/ssh/test/testdata_test.go deleted file mode 100644 index ae48c75..0000000 --- a/vendor/golang.org/x/crypto/ssh/test/testdata_test.go +++ /dev/null @@ -1,64 +0,0 @@ -// 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. - -// IMPLEMENTOR NOTE: To avoid a package loop, this file is in three places: -// ssh/, ssh/agent, and ssh/test/. It should be kept in sync across all three -// instances. - -package test - -import ( - "crypto/rand" - "fmt" - - "golang.org/x/crypto/ssh" - "golang.org/x/crypto/ssh/testdata" -) - -var ( - testPrivateKeys map[string]interface{} - testSigners map[string]ssh.Signer - testPublicKeys map[string]ssh.PublicKey -) - -func init() { - var err error - - n := len(testdata.PEMBytes) - testPrivateKeys = make(map[string]interface{}, n) - testSigners = make(map[string]ssh.Signer, n) - testPublicKeys = make(map[string]ssh.PublicKey, n) - for t, k := range testdata.PEMBytes { - testPrivateKeys[t], err = ssh.ParseRawPrivateKey(k) - if err != nil { - panic(fmt.Sprintf("Unable to parse test key %s: %v", t, err)) - } - testSigners[t], err = ssh.NewSignerFromKey(testPrivateKeys[t]) - if err != nil { - panic(fmt.Sprintf("Unable to create signer for test key %s: %v", t, err)) - } - testPublicKeys[t] = testSigners[t].PublicKey() - } - - // Create a cert and sign it for use in tests. - testCert := &ssh.Certificate{ - Nonce: []byte{}, // To pass reflect.DeepEqual after marshal & parse, this must be non-nil - ValidPrincipals: []string{"gopher1", "gopher2"}, // increases test coverage - ValidAfter: 0, // unix epoch - ValidBefore: ssh.CertTimeInfinity, // The end of currently representable time. - Reserved: []byte{}, // To pass reflect.DeepEqual after marshal & parse, this must be non-nil - Key: testPublicKeys["ecdsa"], - SignatureKey: testPublicKeys["rsa"], - Permissions: ssh.Permissions{ - CriticalOptions: map[string]string{}, - Extensions: map[string]string{}, - }, - } - testCert.SignCert(rand.Reader, testSigners["rsa"]) - testPrivateKeys["cert"] = testPrivateKeys["ecdsa"] - testSigners["cert"], err = ssh.NewCertSigner(testCert, testSigners["ecdsa"]) - if err != nil { - panic(fmt.Sprintf("Unable to create certificate signer: %v", err)) - } -} diff --git a/vendor/golang.org/x/crypto/ssh/testdata/doc.go b/vendor/golang.org/x/crypto/ssh/testdata/doc.go deleted file mode 100644 index fcae47c..0000000 --- a/vendor/golang.org/x/crypto/ssh/testdata/doc.go +++ /dev/null @@ -1,8 +0,0 @@ -// 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. - -// This package contains test data shared between the various subpackages of -// the golang.org/x/crypto/ssh package. Under no circumstance should -// this data be used for production code. -package testdata // import "golang.org/x/crypto/ssh/testdata" diff --git a/vendor/golang.org/x/crypto/ssh/testdata/keys.go b/vendor/golang.org/x/crypto/ssh/testdata/keys.go deleted file mode 100644 index 9b76905..0000000 --- a/vendor/golang.org/x/crypto/ssh/testdata/keys.go +++ /dev/null @@ -1,57 +0,0 @@ -// 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 testdata - -var PEMBytes = map[string][]byte{ - "dsa": []byte(`-----BEGIN DSA PRIVATE KEY----- -MIIBuwIBAAKBgQD6PDSEyXiI9jfNs97WuM46MSDCYlOqWw80ajN16AohtBncs1YB -lHk//dQOvCYOsYaE+gNix2jtoRjwXhDsc25/IqQbU1ahb7mB8/rsaILRGIbA5WH3 -EgFtJmXFovDz3if6F6TzvhFpHgJRmLYVR8cqsezL3hEZOvvs2iH7MorkxwIVAJHD -nD82+lxh2fb4PMsIiaXudAsBAoGAQRf7Q/iaPRn43ZquUhd6WwvirqUj+tkIu6eV -2nZWYmXLlqFQKEy4Tejl7Wkyzr2OSYvbXLzo7TNxLKoWor6ips0phYPPMyXld14r -juhT24CrhOzuLMhDduMDi032wDIZG4Y+K7ElU8Oufn8Sj5Wge8r6ANmmVgmFfynr -FhdYCngCgYEA3ucGJ93/Mx4q4eKRDxcWD3QzWyqpbRVRRV1Vmih9Ha/qC994nJFz -DQIdjxDIT2Rk2AGzMqFEB68Zc3O+Wcsmz5eWWzEwFxaTwOGWTyDqsDRLm3fD+QYj -nOwuxb0Kce+gWI8voWcqC9cyRm09jGzu2Ab3Bhtpg8JJ8L7gS3MRZK4CFEx4UAfY -Fmsr0W6fHB9nhS4/UXM8 ------END DSA PRIVATE KEY----- -`), - "ecdsa": []byte(`-----BEGIN EC PRIVATE KEY----- -MHcCAQEEINGWx0zo6fhJ/0EAfrPzVFyFC9s18lBt3cRoEDhS3ARooAoGCCqGSM49 -AwEHoUQDQgAEi9Hdw6KvZcWxfg2IDhA7UkpDtzzt6ZqJXSsFdLd+Kx4S3Sx4cVO+ -6/ZOXRnPmNAlLUqjShUsUBBngG0u2fqEqA== ------END EC PRIVATE KEY----- -`), - "rsa": []byte(`-----BEGIN RSA PRIVATE KEY----- -MIICXAIBAAKBgQC8A6FGHDiWCSREAXCq6yBfNVr0xCVG2CzvktFNRpue+RXrGs/2 -a6ySEJQb3IYquw7HlJgu6fg3WIWhOmHCjfpG0PrL4CRwbqQ2LaPPXhJErWYejcD8 -Di00cF3677+G10KMZk9RXbmHtuBFZT98wxg8j+ZsBMqGM1+7yrWUvynswQIDAQAB -AoGAJMCk5vqfSRzyXOTXLGIYCuR4Kj6pdsbNSeuuRGfYBeR1F2c/XdFAg7D/8s5R -38p/Ih52/Ty5S8BfJtwtvgVY9ecf/JlU/rl/QzhG8/8KC0NG7KsyXklbQ7gJT8UT -Ojmw5QpMk+rKv17ipDVkQQmPaj+gJXYNAHqImke5mm/K/h0CQQDciPmviQ+DOhOq -2ZBqUfH8oXHgFmp7/6pXw80DpMIxgV3CwkxxIVx6a8lVH9bT/AFySJ6vXq4zTuV9 -6QmZcZzDAkEA2j/UXJPIs1fQ8z/6sONOkU/BjtoePFIWJlRxdN35cZjXnBraX5UR -fFHkePv4YwqmXNqrBOvSu+w2WdSDci+IKwJAcsPRc/jWmsrJW1q3Ha0hSf/WG/Bu -X7MPuXaKpP/DkzGoUmb8ks7yqj6XWnYkPNLjCc8izU5vRwIiyWBRf4mxMwJBAILa -NDvRS0rjwt6lJGv7zPZoqDc65VfrK2aNyHx2PgFyzwrEOtuF57bu7pnvEIxpLTeM -z26i6XVMeYXAWZMTloMCQBbpGgEERQpeUknLBqUHhg/wXF6+lFA+vEGnkY+Dwab2 -KCXFGd+SQ5GdUcEMe9isUH6DYj/6/yCDoFrXXmpQb+M= ------END RSA PRIVATE KEY----- -`), - "ed25519": []byte(`-----BEGIN OPENSSH PRIVATE KEY----- -b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW -QyNTUxOQAAACA+3f7hS7g5UWwXOGVTrMfhmxyrjqz7Sxxbx7I1j8DvvwAAAJhAFfkOQBX5 -DgAAAAtzc2gtZWQyNTUxOQAAACA+3f7hS7g5UWwXOGVTrMfhmxyrjqz7Sxxbx7I1j8Dvvw -AAAEAaYmXltfW6nhRo3iWGglRB48lYq0z0Q3I3KyrdutEr6j7d/uFLuDlRbBc4ZVOsx+Gb -HKuOrPtLHFvHsjWPwO+/AAAAE2dhcnRvbm1AZ2FydG9ubS14cHMBAg== ------END OPENSSH PRIVATE KEY----- -`), - "user": []byte(`-----BEGIN EC PRIVATE KEY----- -MHcCAQEEILYCAeq8f7V4vSSypRw7pxy8yz3V5W4qg8kSC3zJhqpQoAoGCCqGSM49 -AwEHoUQDQgAEYcO2xNKiRUYOLEHM7VYAp57HNyKbOdYtHD83Z4hzNPVC4tM5mdGD -PLL8IEwvYu2wq+lpXfGQnNMbzYf9gspG0w== ------END EC PRIVATE KEY----- -`), -} diff --git a/vendor/golang.org/x/crypto/ssh/testdata_test.go b/vendor/golang.org/x/crypto/ssh/testdata_test.go deleted file mode 100644 index f2828c1..0000000 --- a/vendor/golang.org/x/crypto/ssh/testdata_test.go +++ /dev/null @@ -1,63 +0,0 @@ -// 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. - -// IMPLEMENTOR NOTE: To avoid a package loop, this file is in three places: -// ssh/, ssh/agent, and ssh/test/. It should be kept in sync across all three -// instances. - -package ssh - -import ( - "crypto/rand" - "fmt" - - "golang.org/x/crypto/ssh/testdata" -) - -var ( - testPrivateKeys map[string]interface{} - testSigners map[string]Signer - testPublicKeys map[string]PublicKey -) - -func init() { - var err error - - n := len(testdata.PEMBytes) - testPrivateKeys = make(map[string]interface{}, n) - testSigners = make(map[string]Signer, n) - testPublicKeys = make(map[string]PublicKey, n) - for t, k := range testdata.PEMBytes { - testPrivateKeys[t], err = ParseRawPrivateKey(k) - if err != nil { - panic(fmt.Sprintf("Unable to parse test key %s: %v", t, err)) - } - testSigners[t], err = NewSignerFromKey(testPrivateKeys[t]) - if err != nil { - panic(fmt.Sprintf("Unable to create signer for test key %s: %v", t, err)) - } - testPublicKeys[t] = testSigners[t].PublicKey() - } - - // Create a cert and sign it for use in tests. - testCert := &Certificate{ - Nonce: []byte{}, // To pass reflect.DeepEqual after marshal & parse, this must be non-nil - ValidPrincipals: []string{"gopher1", "gopher2"}, // increases test coverage - ValidAfter: 0, // unix epoch - ValidBefore: CertTimeInfinity, // The end of currently representable time. - Reserved: []byte{}, // To pass reflect.DeepEqual after marshal & parse, this must be non-nil - Key: testPublicKeys["ecdsa"], - SignatureKey: testPublicKeys["rsa"], - Permissions: Permissions{ - CriticalOptions: map[string]string{}, - Extensions: map[string]string{}, - }, - } - testCert.SignCert(rand.Reader, testSigners["rsa"]) - testPrivateKeys["cert"] = testPrivateKeys["ecdsa"] - testSigners["cert"], err = NewCertSigner(testCert, testSigners["ecdsa"]) - if err != nil { - panic(fmt.Sprintf("Unable to create certificate signer: %v", err)) - } -} diff --git a/vendor/golang.org/x/crypto/ssh/transport.go b/vendor/golang.org/x/crypto/ssh/transport.go deleted file mode 100644 index 62fba62..0000000 --- a/vendor/golang.org/x/crypto/ssh/transport.go +++ /dev/null @@ -1,333 +0,0 @@ -// 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 ssh - -import ( - "bufio" - "errors" - "io" -) - -const ( - gcmCipherID = "aes128-gcm@openssh.com" - aes128cbcID = "aes128-cbc" - tripledescbcID = "3des-cbc" -) - -// packetConn represents a transport that implements packet based -// operations. -type packetConn interface { - // Encrypt and send a packet of data to the remote peer. - writePacket(packet []byte) error - - // Read a packet from the connection - readPacket() ([]byte, error) - - // Close closes the write-side of the connection. - Close() error -} - -// transport is the keyingTransport that implements the SSH packet -// protocol. -type transport struct { - reader connectionState - writer connectionState - - bufReader *bufio.Reader - bufWriter *bufio.Writer - rand io.Reader - - io.Closer -} - -// packetCipher represents a combination of SSH encryption/MAC -// protocol. A single instance should be used for one direction only. -type packetCipher interface { - // writePacket encrypts the packet and writes it to w. The - // contents of the packet are generally scrambled. - writePacket(seqnum uint32, w io.Writer, rand io.Reader, packet []byte) error - - // readPacket reads and decrypts a packet of data. The - // returned packet may be overwritten by future calls of - // readPacket. - readPacket(seqnum uint32, r io.Reader) ([]byte, error) -} - -// connectionState represents one side (read or write) of the -// connection. This is necessary because each direction has its own -// keys, and can even have its own algorithms -type connectionState struct { - packetCipher - seqNum uint32 - dir direction - pendingKeyChange chan packetCipher -} - -// prepareKeyChange sets up key material for a keychange. The key changes in -// both directions are triggered by reading and writing a msgNewKey packet -// respectively. -func (t *transport) prepareKeyChange(algs *algorithms, kexResult *kexResult) error { - if ciph, err := newPacketCipher(t.reader.dir, algs.r, kexResult); err != nil { - return err - } else { - t.reader.pendingKeyChange <- ciph - } - - if ciph, err := newPacketCipher(t.writer.dir, algs.w, kexResult); err != nil { - return err - } else { - t.writer.pendingKeyChange <- ciph - } - - return nil -} - -// Read and decrypt next packet. -func (t *transport) readPacket() ([]byte, error) { - return t.reader.readPacket(t.bufReader) -} - -func (s *connectionState) readPacket(r *bufio.Reader) ([]byte, error) { - packet, err := s.packetCipher.readPacket(s.seqNum, r) - s.seqNum++ - if err == nil && len(packet) == 0 { - err = errors.New("ssh: zero length packet") - } - - if len(packet) > 0 { - switch packet[0] { - case msgNewKeys: - select { - case cipher := <-s.pendingKeyChange: - s.packetCipher = cipher - default: - return nil, errors.New("ssh: got bogus newkeys message.") - } - - case msgDisconnect: - // Transform a disconnect message into an - // error. Since this is lowest level at which - // we interpret message types, doing it here - // ensures that we don't have to handle it - // elsewhere. - var msg disconnectMsg - if err := Unmarshal(packet, &msg); err != nil { - return nil, err - } - return nil, &msg - } - } - - // The packet may point to an internal buffer, so copy the - // packet out here. - fresh := make([]byte, len(packet)) - copy(fresh, packet) - - return fresh, err -} - -func (t *transport) writePacket(packet []byte) error { - return t.writer.writePacket(t.bufWriter, t.rand, packet) -} - -func (s *connectionState) writePacket(w *bufio.Writer, rand io.Reader, packet []byte) error { - changeKeys := len(packet) > 0 && packet[0] == msgNewKeys - - err := s.packetCipher.writePacket(s.seqNum, w, rand, packet) - if err != nil { - return err - } - if err = w.Flush(); err != nil { - return err - } - s.seqNum++ - if changeKeys { - select { - case cipher := <-s.pendingKeyChange: - s.packetCipher = cipher - default: - panic("ssh: no key material for msgNewKeys") - } - } - return err -} - -func newTransport(rwc io.ReadWriteCloser, rand io.Reader, isClient bool) *transport { - t := &transport{ - bufReader: bufio.NewReader(rwc), - bufWriter: bufio.NewWriter(rwc), - rand: rand, - reader: connectionState{ - packetCipher: &streamPacketCipher{cipher: noneCipher{}}, - pendingKeyChange: make(chan packetCipher, 1), - }, - writer: connectionState{ - packetCipher: &streamPacketCipher{cipher: noneCipher{}}, - pendingKeyChange: make(chan packetCipher, 1), - }, - Closer: rwc, - } - if isClient { - t.reader.dir = serverKeys - t.writer.dir = clientKeys - } else { - t.reader.dir = clientKeys - t.writer.dir = serverKeys - } - - return t -} - -type direction struct { - ivTag []byte - keyTag []byte - macKeyTag []byte -} - -var ( - serverKeys = direction{[]byte{'B'}, []byte{'D'}, []byte{'F'}} - clientKeys = direction{[]byte{'A'}, []byte{'C'}, []byte{'E'}} -) - -// generateKeys generates key material for IV, MAC and encryption. -func generateKeys(d direction, algs directionAlgorithms, kex *kexResult) (iv, key, macKey []byte) { - 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) - return -} - -// setupKeys sets the cipher and MAC keys from kex.K, kex.H and sessionId, as -// described in RFC 4253, section 6.4. direction should either be serverKeys -// (to setup server->client keys) or clientKeys (for client->server keys). -func newPacketCipher(d direction, algs directionAlgorithms, kex *kexResult) (packetCipher, error) { - iv, key, macKey := generateKeys(d, algs, kex) - - if algs.Cipher == gcmCipherID { - return newGCMCipher(iv, key, macKey) - } - - if algs.Cipher == aes128cbcID { - return newAESCBCCipher(iv, key, macKey, algs) - } - - if algs.Cipher == tripledescbcID { - return newTripleDESCBCCipher(iv, key, macKey, algs) - } - - c := &streamPacketCipher{ - mac: macModes[algs.MAC].new(macKey), - } - c.macResult = make([]byte, c.mac.Size()) - - var err error - c.cipher, err = cipherModes[algs.Cipher].createStream(key, iv) - if err != nil { - return nil, err - } - - return c, nil -} - -// generateKeyMaterial fills out with key material generated from tag, K, H -// and sessionId, as specified in RFC 4253, section 7.2. -func generateKeyMaterial(out, tag []byte, r *kexResult) { - var digestsSoFar []byte - - h := r.Hash.New() - for len(out) > 0 { - h.Reset() - h.Write(r.K) - h.Write(r.H) - - if len(digestsSoFar) == 0 { - h.Write(tag) - h.Write(r.SessionID) - } else { - h.Write(digestsSoFar) - } - - digest := h.Sum(nil) - n := copy(out, digest) - out = out[n:] - if len(out) > 0 { - digestsSoFar = append(digestsSoFar, digest...) - } - } -} - -const packageVersion = "SSH-2.0-Go" - -// Sends and receives a version line. The versionLine string should -// be US ASCII, start with "SSH-2.0-", and should not include a -// newline. exchangeVersions returns the other side's version line. -func exchangeVersions(rw io.ReadWriter, versionLine []byte) (them []byte, err error) { - // Contrary to the RFC, we do not ignore lines that don't - // start with "SSH-2.0-" to make the library usable with - // nonconforming servers. - for _, c := range versionLine { - // The spec disallows non US-ASCII chars, and - // specifically forbids null chars. - if c < 32 { - return nil, errors.New("ssh: junk character in version line") - } - } - if _, err = rw.Write(append(versionLine, '\r', '\n')); err != nil { - return - } - - them, err = readVersion(rw) - return them, err -} - -// maxVersionStringBytes is the maximum number of bytes that we'll -// accept as a version string. RFC 4253 section 4.2 limits this at 255 -// chars -const maxVersionStringBytes = 255 - -// Read version string as specified by RFC 4253, section 4.2. -func readVersion(r io.Reader) ([]byte, error) { - versionString := make([]byte, 0, 64) - var ok bool - var buf [1]byte - - for len(versionString) < maxVersionStringBytes { - _, err := io.ReadFull(r, buf[:]) - if err != nil { - return nil, err - } - // The RFC says that the version should be terminated with \r\n - // but several SSH servers actually only send a \n. - if buf[0] == '\n' { - ok = true - break - } - - // non ASCII chars are disallowed, but we are lenient, - // since Go doesn't use null-terminated strings. - - // The RFC allows a comment after a space, however, - // all of it (version and comments) goes into the - // session hash. - versionString = append(versionString, buf[0]) - } - - if !ok { - return nil, errors.New("ssh: overflow reading version string") - } - - // There might be a '\r' on the end which we should remove. - if len(versionString) > 0 && versionString[len(versionString)-1] == '\r' { - versionString = versionString[:len(versionString)-1] - } - return versionString, nil -} diff --git a/vendor/golang.org/x/crypto/ssh/transport_test.go b/vendor/golang.org/x/crypto/ssh/transport_test.go deleted file mode 100644 index 92d83ab..0000000 --- a/vendor/golang.org/x/crypto/ssh/transport_test.go +++ /dev/null @@ -1,109 +0,0 @@ -// 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 ssh - -import ( - "bytes" - "crypto/rand" - "encoding/binary" - "strings" - "testing" -) - -func TestReadVersion(t *testing.T) { - longversion := strings.Repeat("SSH-2.0-bla", 50)[:253] - cases := map[string]string{ - "SSH-2.0-bla\r\n": "SSH-2.0-bla", - "SSH-2.0-bla\n": "SSH-2.0-bla", - longversion + "\r\n": longversion, - } - - for in, want := range cases { - result, err := readVersion(bytes.NewBufferString(in)) - if err != nil { - t.Errorf("readVersion(%q): %s", in, err) - } - got := string(result) - if got != want { - t.Errorf("got %q, want %q", got, want) - } - } -} - -func TestReadVersionError(t *testing.T) { - longversion := strings.Repeat("SSH-2.0-bla", 50)[:253] - cases := []string{ - longversion + "too-long\r\n", - } - for _, in := range cases { - if _, err := readVersion(bytes.NewBufferString(in)); err == nil { - t.Errorf("readVersion(%q) should have failed", in) - } - } -} - -func TestExchangeVersionsBasic(t *testing.T) { - v := "SSH-2.0-bla" - buf := bytes.NewBufferString(v + "\r\n") - them, err := exchangeVersions(buf, []byte("xyz")) - if err != nil { - t.Errorf("exchangeVersions: %v", err) - } - - if want := "SSH-2.0-bla"; string(them) != want { - t.Errorf("got %q want %q for our version", them, want) - } -} - -func TestExchangeVersions(t *testing.T) { - cases := []string{ - "not\x000allowed", - "not allowed\n", - } - for _, c := range cases { - buf := bytes.NewBufferString("SSH-2.0-bla\r\n") - if _, err := exchangeVersions(buf, []byte(c)); err == nil { - t.Errorf("exchangeVersions(%q): should have failed", c) - } - } -} - -type closerBuffer struct { - bytes.Buffer -} - -func (b *closerBuffer) Close() error { - return nil -} - -func TestTransportMaxPacketWrite(t *testing.T) { - buf := &closerBuffer{} - tr := newTransport(buf, rand.Reader, true) - huge := make([]byte, maxPacket+1) - err := tr.writePacket(huge) - if err == nil { - t.Errorf("transport accepted write for a huge packet.") - } -} - -func TestTransportMaxPacketReader(t *testing.T) { - var header [5]byte - huge := make([]byte, maxPacket+128) - binary.BigEndian.PutUint32(header[0:], uint32(len(huge))) - // padding. - header[4] = 0 - - buf := &closerBuffer{} - buf.Write(header[:]) - buf.Write(huge) - - tr := newTransport(buf, rand.Reader, true) - _, err := tr.readPacket() - if err == nil { - t.Errorf("transport succeeded reading huge packet.") - } else if !strings.Contains(err.Error(), "large") { - t.Errorf("got %q, should mention %q", err.Error(), "large") - } -} diff --git a/vendor/golang.org/x/crypto/tea/cipher.go b/vendor/golang.org/x/crypto/tea/cipher.go deleted file mode 100644 index 9c13d12..0000000 --- a/vendor/golang.org/x/crypto/tea/cipher.go +++ /dev/null @@ -1,109 +0,0 @@ -// 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. - -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/tea/tea_test.go b/vendor/golang.org/x/crypto/tea/tea_test.go deleted file mode 100644 index eb98d1e..0000000 --- a/vendor/golang.org/x/crypto/tea/tea_test.go +++ /dev/null @@ -1,93 +0,0 @@ -// 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 - -import ( - "bytes" - "testing" -) - -// A sample test key for when we just want to initialize a cipher -var testKey = []byte{0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF} - -// Test that the block size for tea is correct -func TestBlocksize(t *testing.T) { - c, err := NewCipher(testKey) - if err != nil { - t.Fatalf("NewCipher returned error: %s", err) - } - - if result := c.BlockSize(); result != BlockSize { - t.Errorf("cipher.BlockSize returned %d, but expected %d", result, BlockSize) - } -} - -// Test that invalid key sizes return an error -func TestInvalidKeySize(t *testing.T) { - var key [KeySize + 1]byte - - if _, err := NewCipher(key[:]); err == nil { - t.Errorf("invalid key size %d didn't result in an error.", len(key)) - } - - if _, err := NewCipher(key[:KeySize-1]); err == nil { - t.Errorf("invalid key size %d didn't result in an error.", KeySize-1) - } -} - -// Test Vectors -type teaTest struct { - rounds int - key []byte - plaintext []byte - ciphertext []byte -} - -var teaTests = []teaTest{ - // These were sourced from https://github.com/froydnj/ironclad/blob/master/testing/test-vectors/tea.testvec - { - numRounds, - []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - []byte{0x41, 0xea, 0x3a, 0x0a, 0x94, 0xba, 0xa9, 0x40}, - }, - { - numRounds, - []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, - []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, - []byte{0x31, 0x9b, 0xbe, 0xfb, 0x01, 0x6a, 0xbd, 0xb2}, - }, - { - 16, - []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - []byte{0xed, 0x28, 0x5d, 0xa1, 0x45, 0x5b, 0x33, 0xc1}, - }, -} - -// Test encryption -func TestCipherEncrypt(t *testing.T) { - // Test encryption with standard 64 rounds - for i, test := range teaTests { - c, err := NewCipherWithRounds(test.key, test.rounds) - if err != nil { - t.Fatalf("#%d: NewCipher returned error: %s", i, err) - } - - var ciphertext [BlockSize]byte - c.Encrypt(ciphertext[:], test.plaintext) - - if !bytes.Equal(ciphertext[:], test.ciphertext) { - t.Errorf("#%d: incorrect ciphertext. Got %x, wanted %x", i, ciphertext, test.ciphertext) - } - - var plaintext2 [BlockSize]byte - c.Decrypt(plaintext2[:], ciphertext[:]) - - if !bytes.Equal(plaintext2[:], test.plaintext) { - t.Errorf("#%d: incorrect plaintext. Got %x, wanted %x", i, plaintext2, test.plaintext) - } - } -} diff --git a/vendor/golang.org/x/crypto/twofish/twofish.go b/vendor/golang.org/x/crypto/twofish/twofish.go deleted file mode 100644 index 376fa0e..0000000 --- a/vendor/golang.org/x/crypto/twofish/twofish.go +++ /dev/null @@ -1,342 +0,0 @@ -// 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. -package twofish // import "golang.org/x/crypto/twofish" - -// Twofish is defined in http://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/twofish/twofish_test.go b/vendor/golang.org/x/crypto/twofish/twofish_test.go deleted file mode 100644 index 303081f..0000000 --- a/vendor/golang.org/x/crypto/twofish/twofish_test.go +++ /dev/null @@ -1,129 +0,0 @@ -// 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 - -import ( - "bytes" - "testing" -) - -var qbox = [2][4][16]byte{ - { - {0x8, 0x1, 0x7, 0xD, 0x6, 0xF, 0x3, 0x2, 0x0, 0xB, 0x5, 0x9, 0xE, 0xC, 0xA, 0x4}, - {0xE, 0xC, 0xB, 0x8, 0x1, 0x2, 0x3, 0x5, 0xF, 0x4, 0xA, 0x6, 0x7, 0x0, 0x9, 0xD}, - {0xB, 0xA, 0x5, 0xE, 0x6, 0xD, 0x9, 0x0, 0xC, 0x8, 0xF, 0x3, 0x2, 0x4, 0x7, 0x1}, - {0xD, 0x7, 0xF, 0x4, 0x1, 0x2, 0x6, 0xE, 0x9, 0xB, 0x3, 0x0, 0x8, 0x5, 0xC, 0xA}, - }, - { - {0x2, 0x8, 0xB, 0xD, 0xF, 0x7, 0x6, 0xE, 0x3, 0x1, 0x9, 0x4, 0x0, 0xA, 0xC, 0x5}, - {0x1, 0xE, 0x2, 0xB, 0x4, 0xC, 0x3, 0x7, 0x6, 0xD, 0xA, 0x5, 0xF, 0x9, 0x0, 0x8}, - {0x4, 0xC, 0x7, 0x5, 0x1, 0x6, 0x9, 0xA, 0x0, 0xE, 0xD, 0x8, 0x2, 0xB, 0x3, 0xF}, - {0xB, 0x9, 0x5, 0x1, 0xC, 0x3, 0xD, 0xE, 0x6, 0x4, 0x7, 0xF, 0x2, 0x0, 0x8, 0xA}, - }, -} - -// genSbox generates the variable sbox -func genSbox(qi int, x byte) byte { - a0, b0 := x/16, x%16 - for i := 0; i < 2; i++ { - a1 := a0 ^ b0 - b1 := (a0 ^ ((b0 << 3) | (b0 >> 1)) ^ (a0 << 3)) & 15 - a0 = qbox[qi][2*i][a1] - b0 = qbox[qi][2*i+1][b1] - } - return (b0 << 4) + a0 -} - -func TestSbox(t *testing.T) { - for n := range sbox { - for m := range sbox[n] { - if genSbox(n, byte(m)) != sbox[n][m] { - t.Errorf("#%d|%d: sbox value = %d want %d", n, m, sbox[n][m], genSbox(n, byte(m))) - } - } - } -} - -var testVectors = []struct { - key []byte - dec []byte - enc []byte -}{ - // These tests are extracted from LibTom - { - []byte{0x9F, 0x58, 0x9F, 0x5C, 0xF6, 0x12, 0x2C, 0x32, 0xB6, 0xBF, 0xEC, 0x2F, 0x2A, 0xE8, 0xC3, 0x5A}, - []byte{0xD4, 0x91, 0xDB, 0x16, 0xE7, 0xB1, 0xC3, 0x9E, 0x86, 0xCB, 0x08, 0x6B, 0x78, 0x9F, 0x54, 0x19}, - []byte{0x01, 0x9F, 0x98, 0x09, 0xDE, 0x17, 0x11, 0x85, 0x8F, 0xAA, 0xC3, 0xA3, 0xBA, 0x20, 0xFB, 0xC3}, - }, - { - []byte{0x88, 0xB2, 0xB2, 0x70, 0x6B, 0x10, 0x5E, 0x36, 0xB4, 0x46, 0xBB, 0x6D, 0x73, 0x1A, 0x1E, 0x88, - 0xEF, 0xA7, 0x1F, 0x78, 0x89, 0x65, 0xBD, 0x44}, - []byte{0x39, 0xDA, 0x69, 0xD6, 0xBA, 0x49, 0x97, 0xD5, 0x85, 0xB6, 0xDC, 0x07, 0x3C, 0xA3, 0x41, 0xB2}, - []byte{0x18, 0x2B, 0x02, 0xD8, 0x14, 0x97, 0xEA, 0x45, 0xF9, 0xDA, 0xAC, 0xDC, 0x29, 0x19, 0x3A, 0x65}, - }, - { - []byte{0xD4, 0x3B, 0xB7, 0x55, 0x6E, 0xA3, 0x2E, 0x46, 0xF2, 0xA2, 0x82, 0xB7, 0xD4, 0x5B, 0x4E, 0x0D, - 0x57, 0xFF, 0x73, 0x9D, 0x4D, 0xC9, 0x2C, 0x1B, 0xD7, 0xFC, 0x01, 0x70, 0x0C, 0xC8, 0x21, 0x6F}, - []byte{0x90, 0xAF, 0xE9, 0x1B, 0xB2, 0x88, 0x54, 0x4F, 0x2C, 0x32, 0xDC, 0x23, 0x9B, 0x26, 0x35, 0xE6}, - []byte{0x6C, 0xB4, 0x56, 0x1C, 0x40, 0xBF, 0x0A, 0x97, 0x05, 0x93, 0x1C, 0xB6, 0xD4, 0x08, 0xE7, 0xFA}, - }, - // These test are derived from http://www.schneier.com/code/ecb_ival.txt - { - []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - []byte{0x9F, 0x58, 0x9F, 0x5C, 0xF6, 0x12, 0x2C, 0x32, 0xB6, 0xBF, 0xEC, 0x2F, 0x2A, 0xE8, 0xC3, 0x5A}, - }, - { - []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10, - 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, - }, - []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - []byte{0xCF, 0xD1, 0xD2, 0xE5, 0xA9, 0xBE, 0x9C, 0xDF, 0x50, 0x1F, 0x13, 0xB8, 0x92, 0xBD, 0x22, 0x48}, - }, - { - []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10, - 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, - }, - []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - []byte{0x37, 0x52, 0x7B, 0xE0, 0x05, 0x23, 0x34, 0xB8, 0x9F, 0x0C, 0xFC, 0xCA, 0xE8, 0x7C, 0xFA, 0x20}, - }, -} - -func TestCipher(t *testing.T) { - for n, tt := range testVectors { - // Test if the plaintext (dec) is encrypts to the given - // ciphertext (enc) using the given key. Test also if enc can - // be decrypted again into dec. - c, err := NewCipher(tt.key) - if err != nil { - t.Errorf("#%d: NewCipher: %v", n, err) - return - } - - buf := make([]byte, 16) - c.Encrypt(buf, tt.dec) - if !bytes.Equal(buf, tt.enc) { - t.Errorf("#%d: encrypt = %x want %x", n, buf, tt.enc) - } - c.Decrypt(buf, tt.enc) - if !bytes.Equal(buf, tt.dec) { - t.Errorf("#%d: decrypt = %x want %x", n, buf, tt.dec) - } - - // Test that 16 zero bytes, encrypted 1000 times then decrypted - // 1000 times results in zero bytes again. - zero := make([]byte, 16) - buf = make([]byte, 16) - for i := 0; i < 1000; i++ { - c.Encrypt(buf, buf) - } - for i := 0; i < 1000; i++ { - c.Decrypt(buf, buf) - } - if !bytes.Equal(buf, zero) { - t.Errorf("#%d: encrypt/decrypt 1000: have %x want %x", n, buf, zero) - } - } -} diff --git a/vendor/golang.org/x/crypto/xtea/block.go b/vendor/golang.org/x/crypto/xtea/block.go deleted file mode 100644 index bf5d245..0000000 --- a/vendor/golang.org/x/crypto/xtea/block.go +++ /dev/null @@ -1,66 +0,0 @@ -// 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 decrypt 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 deleted file mode 100644 index 108b426..0000000 --- a/vendor/golang.org/x/crypto/xtea/cipher.go +++ /dev/null @@ -1,82 +0,0 @@ -// 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." -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. -// table contains a series of precalculated values that are used each round. -type Cipher struct { - 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 k 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 = 0 - - // 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/xtea/xtea_test.go b/vendor/golang.org/x/crypto/xtea/xtea_test.go deleted file mode 100644 index be711bf..0000000 --- a/vendor/golang.org/x/crypto/xtea/xtea_test.go +++ /dev/null @@ -1,229 +0,0 @@ -// 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 - -import ( - "testing" -) - -// A sample test key for when we just want to initialize a cipher -var testKey = []byte{0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF} - -// Test that the block size for XTEA is correct -func TestBlocksize(t *testing.T) { - if BlockSize != 8 { - t.Errorf("BlockSize constant - expected 8, got %d", BlockSize) - return - } - - c, err := NewCipher(testKey) - if err != nil { - t.Errorf("NewCipher(%d bytes) = %s", len(testKey), err) - return - } - - result := c.BlockSize() - if result != 8 { - t.Errorf("BlockSize function - expected 8, got %d", result) - return - } -} - -// A series of test values to confirm that the Cipher.table array was initialized correctly -var testTable = []uint32{ - 0x00112233, 0x6B1568B8, 0xE28CE030, 0xC5089E2D, 0xC5089E2D, 0x1EFBD3A2, 0xA7845C2A, 0x78EF0917, - 0x78EF0917, 0x172682D0, 0x5B6AC714, 0x822AC955, 0x3DE68511, 0xDC1DFECA, 0x2062430E, 0x3611343F, - 0xF1CCEFFB, 0x900469B4, 0xD448ADF8, 0x2E3BE36D, 0xB6C46BF5, 0x994029F2, 0x994029F2, 0xF3335F67, - 0x6AAAD6DF, 0x4D2694DC, 0x4D2694DC, 0xEB5E0E95, 0x2FA252D9, 0x4551440A, 0x121E10D6, 0xB0558A8F, - 0xE388BDC3, 0x0A48C004, 0xC6047BC0, 0x643BF579, 0xA88039BD, 0x02736F32, 0x8AFBF7BA, 0x5C66A4A7, - 0x5C66A4A7, 0xC76AEB2C, 0x3EE262A4, 0x215E20A1, 0x215E20A1, 0x7B515616, 0x03D9DE9E, 0x1988CFCF, - 0xD5448B8B, 0x737C0544, 0xB7C04988, 0xDE804BC9, 0x9A3C0785, 0x3873813E, 0x7CB7C582, 0xD6AAFAF7, - 0x4E22726F, 0x309E306C, 0x309E306C, 0x8A9165E1, 0x1319EE69, 0xF595AC66, 0xF595AC66, 0x4F88E1DB, -} - -// Test that the cipher context is initialized correctly -func TestCipherInit(t *testing.T) { - c, err := NewCipher(testKey) - if err != nil { - t.Errorf("NewCipher(%d bytes) = %s", len(testKey), err) - return - } - - for i := 0; i < len(c.table); i++ { - if c.table[i] != testTable[i] { - t.Errorf("NewCipher() failed to initialize Cipher.table[%d] correctly. Expected %08X, got %08X", i, testTable[i], c.table[i]) - break - } - } -} - -// Test that invalid key sizes return an error -func TestInvalidKeySize(t *testing.T) { - // Test a long key - key := []byte{ - 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, - 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, - } - - _, err := NewCipher(key) - if err == nil { - t.Errorf("Invalid key size %d didn't result in an error.", len(key)) - } - - // Test a short key - key = []byte{0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77} - - _, err = NewCipher(key) - if err == nil { - t.Errorf("Invalid key size %d didn't result in an error.", len(key)) - } -} - -// Test that we can correctly decode some bytes we have encoded -func TestEncodeDecode(t *testing.T) { - original := []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF} - input := original - output := make([]byte, BlockSize) - - c, err := NewCipher(testKey) - if err != nil { - t.Errorf("NewCipher(%d bytes) = %s", len(testKey), err) - return - } - - // Encrypt the input block - c.Encrypt(output, input) - - // Check that the output does not match the input - differs := false - for i := 0; i < len(input); i++ { - if output[i] != input[i] { - differs = true - break - } - } - if differs == false { - t.Error("Cipher.Encrypt: Failed to encrypt the input block.") - return - } - - // Decrypt the block we just encrypted - input = output - output = make([]byte, BlockSize) - c.Decrypt(output, input) - - // Check that the output from decrypt matches our initial input - for i := 0; i < len(input); i++ { - if output[i] != original[i] { - t.Errorf("Decrypted byte %d differed. Expected %02X, got %02X\n", i, original[i], output[i]) - return - } - } -} - -// Test Vectors -type CryptTest struct { - key []byte - plainText []byte - cipherText []byte -} - -var CryptTests = []CryptTest{ - // These were sourced from http://www.freemedialibrary.com/index.php/XTEA_test_vectors - { - []byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}, - []byte{0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48}, - []byte{0x49, 0x7d, 0xf3, 0xd0, 0x72, 0x61, 0x2c, 0xb5}, - }, - { - []byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}, - []byte{0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41}, - []byte{0xe7, 0x8f, 0x2d, 0x13, 0x74, 0x43, 0x41, 0xd8}, - }, - { - []byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}, - []byte{0x5a, 0x5b, 0x6e, 0x27, 0x89, 0x48, 0xd7, 0x7f}, - []byte{0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41}, - }, - { - []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - []byte{0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48}, - []byte{0xa0, 0x39, 0x05, 0x89, 0xf8, 0xb8, 0xef, 0xa5}, - }, - { - []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - []byte{0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41}, - []byte{0xed, 0x23, 0x37, 0x5a, 0x82, 0x1a, 0x8c, 0x2d}, - }, - { - []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - []byte{0x70, 0xe1, 0x22, 0x5d, 0x6e, 0x4e, 0x76, 0x55}, - []byte{0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41}, - }, - - // These vectors are from http://wiki.secondlife.com/wiki/XTEA_Strong_Encryption_Implementation#Bouncy_Castle_C.23_API - { - []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - []byte{0xDE, 0xE9, 0xD4, 0xD8, 0xF7, 0x13, 0x1E, 0xD9}, - }, - { - []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - []byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}, - []byte{0x06, 0x5C, 0x1B, 0x89, 0x75, 0xC6, 0xA8, 0x16}, - }, - { - []byte{0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78, 0x23, 0x45, 0x67, 0x89, 0x34, 0x56, 0x78, 0x9A}, - []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - []byte{0x1F, 0xF9, 0xA0, 0x26, 0x1A, 0xC6, 0x42, 0x64}, - }, - { - []byte{0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78, 0x23, 0x45, 0x67, 0x89, 0x34, 0x56, 0x78, 0x9A}, - []byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}, - []byte{0x8C, 0x67, 0x15, 0x5B, 0x2E, 0xF9, 0x1E, 0xAD}, - }, -} - -// Test encryption -func TestCipherEncrypt(t *testing.T) { - for i, tt := range CryptTests { - c, err := NewCipher(tt.key) - if err != nil { - t.Errorf("NewCipher(%d bytes), vector %d = %s", len(tt.key), i, err) - continue - } - - out := make([]byte, len(tt.plainText)) - c.Encrypt(out, tt.plainText) - - for j := 0; j < len(out); j++ { - if out[j] != tt.cipherText[j] { - t.Errorf("Cipher.Encrypt %d: out[%d] = %02X, expected %02X", i, j, out[j], tt.cipherText[j]) - break - } - } - } -} - -// Test decryption -func TestCipherDecrypt(t *testing.T) { - for i, tt := range CryptTests { - c, err := NewCipher(tt.key) - if err != nil { - t.Errorf("NewCipher(%d bytes), vector %d = %s", len(tt.key), i, err) - continue - } - - out := make([]byte, len(tt.cipherText)) - c.Decrypt(out, tt.cipherText) - - for j := 0; j < len(out); j++ { - if out[j] != tt.plainText[j] { - t.Errorf("Cipher.Decrypt %d: out[%d] = %02X, expected %02X", i, j, out[j], tt.plainText[j]) - break - } - } - } -} diff --git a/vendor/golang.org/x/crypto/xts/xts.go b/vendor/golang.org/x/crypto/xts/xts.go deleted file mode 100644 index c9a283b..0000000 --- a/vendor/golang.org/x/crypto/xts/xts.go +++ /dev/null @@ -1,138 +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. - -// 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. -// -// (Note: this package does not implement ciphertext-stealing so sectors must -// be a multiple of 16 bytes.) -package xts // import "golang.org/x/crypto/xts" - -import ( - "crypto/cipher" - "errors" -) - -// Cipher contains an expanded key structure. It doesn't contain mutable state -// and therefore can be used concurrently. -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 - -// 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 may be the same slice but should not overlap. -// 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") - } - - var tweak [blockSize]byte - for i := 0; i < 8; i++ { - tweak[i] = byte(sectorNum) - sectorNum >>= 8 - } - - c.k2.Encrypt(tweak[:], tweak[:]) - - for i := 0; i < len(plaintext); i += blockSize { - for j := 0; j < blockSize; j++ { - ciphertext[i+j] = plaintext[i+j] ^ tweak[j] - } - c.k1.Encrypt(ciphertext[i:], ciphertext[i:]) - for j := 0; j < blockSize; j++ { - ciphertext[i+j] ^= tweak[j] - } - - mul2(&tweak) - } -} - -// Decrypt decrypts a sector of ciphertext and puts the result into plaintext. -// Plaintext and ciphertext may be the same slice but should not overlap. -// 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") - } - - var tweak [blockSize]byte - for i := 0; i < 8; i++ { - tweak[i] = byte(sectorNum) - sectorNum >>= 8 - } - - c.k2.Encrypt(tweak[:], tweak[:]) - - for i := 0; i < len(plaintext); i += blockSize { - for j := 0; j < blockSize; j++ { - plaintext[i+j] = ciphertext[i+j] ^ tweak[j] - } - c.k1.Decrypt(plaintext[i:], plaintext[i:]) - for j := 0; j < blockSize; j++ { - plaintext[i+j] ^= tweak[j] - } - - mul2(&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 - } -} diff --git a/vendor/golang.org/x/crypto/xts/xts_test.go b/vendor/golang.org/x/crypto/xts/xts_test.go deleted file mode 100644 index 7a5e9fa..0000000 --- a/vendor/golang.org/x/crypto/xts/xts_test.go +++ /dev/null @@ -1,85 +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. - -package xts - -import ( - "bytes" - "crypto/aes" - "encoding/hex" - "testing" -) - -// These test vectors have been taken from IEEE P1619/D16, Annex B. -var xtsTestVectors = []struct { - key string - sector uint64 - plaintext string - ciphertext string -}{ - { - "0000000000000000000000000000000000000000000000000000000000000000", - 0, - "0000000000000000000000000000000000000000000000000000000000000000", - "917cf69ebd68b2ec9b9fe9a3eadda692cd43d2f59598ed858c02c2652fbf922e", - }, { - "1111111111111111111111111111111122222222222222222222222222222222", - 0x3333333333, - "4444444444444444444444444444444444444444444444444444444444444444", - "c454185e6a16936e39334038acef838bfb186fff7480adc4289382ecd6d394f0", - }, { - "fffefdfcfbfaf9f8f7f6f5f4f3f2f1f022222222222222222222222222222222", - 0x3333333333, - "4444444444444444444444444444444444444444444444444444444444444444", - "af85336b597afc1a900b2eb21ec949d292df4c047e0b21532186a5971a227a89", - }, { - "2718281828459045235360287471352631415926535897932384626433832795", - 0, - "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", - "27a7479befa1d476489f308cd4cfa6e2a96e4bbe3208ff25287dd3819616e89cc78cf7f5e543445f8333d8fa7f56000005279fa5d8b5e4ad40e736ddb4d35412328063fd2aab53e5ea1e0a9f332500a5df9487d07a5c92cc512c8866c7e860ce93fdf166a24912b422976146ae20ce846bb7dc9ba94a767aaef20c0d61ad02655ea92dc4c4e41a8952c651d33174be51a10c421110e6d81588ede82103a252d8a750e8768defffed9122810aaeb99f9172af82b604dc4b8e51bcb08235a6f4341332e4ca60482a4ba1a03b3e65008fc5da76b70bf1690db4eae29c5f1badd03c5ccf2a55d705ddcd86d449511ceb7ec30bf12b1fa35b913f9f747a8afd1b130e94bff94effd01a91735ca1726acd0b197c4e5b03393697e126826fb6bbde8ecc1e08298516e2c9ed03ff3c1b7860f6de76d4cecd94c8119855ef5297ca67e9f3e7ff72b1e99785ca0a7e7720c5b36dc6d72cac9574c8cbbc2f801e23e56fd344b07f22154beba0f08ce8891e643ed995c94d9a69c9f1b5f499027a78572aeebd74d20cc39881c213ee770b1010e4bea718846977ae119f7a023ab58cca0ad752afe656bb3c17256a9f6e9bf19fdd5a38fc82bbe872c5539edb609ef4f79c203ebb140f2e583cb2ad15b4aa5b655016a8449277dbd477ef2c8d6c017db738b18deb4a427d1923ce3ff262735779a418f20a282df920147beabe421ee5319d0568", - }, { - "2718281828459045235360287471352631415926535897932384626433832795", - 1, - "27a7479befa1d476489f308cd4cfa6e2a96e4bbe3208ff25287dd3819616e89cc78cf7f5e543445f8333d8fa7f56000005279fa5d8b5e4ad40e736ddb4d35412328063fd2aab53e5ea1e0a9f332500a5df9487d07a5c92cc512c8866c7e860ce93fdf166a24912b422976146ae20ce846bb7dc9ba94a767aaef20c0d61ad02655ea92dc4c4e41a8952c651d33174be51a10c421110e6d81588ede82103a252d8a750e8768defffed9122810aaeb99f9172af82b604dc4b8e51bcb08235a6f4341332e4ca60482a4ba1a03b3e65008fc5da76b70bf1690db4eae29c5f1badd03c5ccf2a55d705ddcd86d449511ceb7ec30bf12b1fa35b913f9f747a8afd1b130e94bff94effd01a91735ca1726acd0b197c4e5b03393697e126826fb6bbde8ecc1e08298516e2c9ed03ff3c1b7860f6de76d4cecd94c8119855ef5297ca67e9f3e7ff72b1e99785ca0a7e7720c5b36dc6d72cac9574c8cbbc2f801e23e56fd344b07f22154beba0f08ce8891e643ed995c94d9a69c9f1b5f499027a78572aeebd74d20cc39881c213ee770b1010e4bea718846977ae119f7a023ab58cca0ad752afe656bb3c17256a9f6e9bf19fdd5a38fc82bbe872c5539edb609ef4f79c203ebb140f2e583cb2ad15b4aa5b655016a8449277dbd477ef2c8d6c017db738b18deb4a427d1923ce3ff262735779a418f20a282df920147beabe421ee5319d0568", - "264d3ca8512194fec312c8c9891f279fefdd608d0c027b60483a3fa811d65ee59d52d9e40ec5672d81532b38b6b089ce951f0f9c35590b8b978d175213f329bb1c2fd30f2f7f30492a61a532a79f51d36f5e31a7c9a12c286082ff7d2394d18f783e1a8e72c722caaaa52d8f065657d2631fd25bfd8e5baad6e527d763517501c68c5edc3cdd55435c532d7125c8614deed9adaa3acade5888b87bef641c4c994c8091b5bcd387f3963fb5bc37aa922fbfe3df4e5b915e6eb514717bdd2a74079a5073f5c4bfd46adf7d282e7a393a52579d11a028da4d9cd9c77124f9648ee383b1ac763930e7162a8d37f350b2f74b8472cf09902063c6b32e8c2d9290cefbd7346d1c779a0df50edcde4531da07b099c638e83a755944df2aef1aa31752fd323dcb710fb4bfbb9d22b925bc3577e1b8949e729a90bbafeacf7f7879e7b1147e28ba0bae940db795a61b15ecf4df8db07b824bb062802cc98a9545bb2aaeed77cb3fc6db15dcd7d80d7d5bc406c4970a3478ada8899b329198eb61c193fb6275aa8ca340344a75a862aebe92eee1ce032fd950b47d7704a3876923b4ad62844bf4a09c4dbe8b4397184b7471360c9564880aedddb9baa4af2e75394b08cd32ff479c57a07d3eab5d54de5f9738b8d27f27a9f0ab11799d7b7ffefb2704c95c6ad12c39f1e867a4b7b1d7818a4b753dfd2a89ccb45e001a03a867b187f225dd", - }, { - "27182818284590452353602874713526624977572470936999595749669676273141592653589793238462643383279502884197169399375105820974944592", - 0xff, - "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", - "1c3b3a102f770386e4836c99e370cf9bea00803f5e482357a4ae12d414a3e63b5d31e276f8fe4a8d66b317f9ac683f44680a86ac35adfc3345befecb4bb188fd5776926c49a3095eb108fd1098baec70aaa66999a72a82f27d848b21d4a741b0c5cd4d5fff9dac89aeba122961d03a757123e9870f8acf1000020887891429ca2a3e7a7d7df7b10355165c8b9a6d0a7de8b062c4500dc4cd120c0f7418dae3d0b5781c34803fa75421c790dfe1de1834f280d7667b327f6c8cd7557e12ac3a0f93ec05c52e0493ef31a12d3d9260f79a289d6a379bc70c50841473d1a8cc81ec583e9645e07b8d9670655ba5bbcfecc6dc3966380ad8fecb17b6ba02469a020a84e18e8f84252070c13e9f1f289be54fbc481457778f616015e1327a02b140f1505eb309326d68378f8374595c849d84f4c333ec4423885143cb47bd71c5edae9be69a2ffeceb1bec9de244fbe15992b11b77c040f12bd8f6a975a44a0f90c29a9abc3d4d893927284c58754cce294529f8614dcd2aba991925fedc4ae74ffac6e333b93eb4aff0479da9a410e4450e0dd7ae4c6e2910900575da401fc07059f645e8b7e9bfdef33943054ff84011493c27b3429eaedb4ed5376441a77ed43851ad77f16f541dfd269d50d6a5f14fb0aab1cbb4c1550be97f7ab4066193c4caa773dad38014bd2092fa755c824bb5e54c4f36ffda9fcea70b9c6e693e148c151", - }, -} - -func fromHex(s string) []byte { - ret, err := hex.DecodeString(s) - if err != nil { - panic("xts: invalid hex in test") - } - return ret -} - -func TestXTS(t *testing.T) { - for i, test := range xtsTestVectors { - c, err := NewCipher(aes.NewCipher, fromHex(test.key)) - if err != nil { - t.Errorf("#%d: failed to create cipher: %s", i, err) - continue - } - plaintext := fromHex(test.plaintext) - ciphertext := make([]byte, len(plaintext)) - c.Encrypt(ciphertext, plaintext, test.sector) - - expectedCiphertext := fromHex(test.ciphertext) - if !bytes.Equal(ciphertext, expectedCiphertext) { - t.Errorf("#%d: encrypted failed, got: %x, want: %x", i, ciphertext, expectedCiphertext) - continue - } - - decrypted := make([]byte, len(ciphertext)) - c.Decrypt(decrypted, ciphertext, test.sector) - if !bytes.Equal(decrypted, plaintext) { - t.Errorf("#%d: decryption failed, got: %x, want: %x", i, decrypted, plaintext) - } - } -}